Download text file
#IF 0
    ----------------------------                      PowerBASIC v8.x
 ---|         DASoftVSS        |------------------------------------------
    ----------------------------         Code           DATE: 2004-11-04
    | FILE NAME  TransBMPs.bas |          by
    ----------------------------  Don Schullian, Jr.

              This code is released into the Public Domain
       ----------------------------------------------------------
        No guarantee as to the viability, accuracy, or safety of
         use of this code is implied, warranted, or guaranteed
       ----------------------------------------------------------
                         Use at your own risk!
       ----------------------------------------------------------
                  CONTACT AUTHOR AT basic@DASoftVSS.com
 -------------------------------------------------------------------------

  The following code doesn't work on NT 3.x, 4.x, or Win95

  This demo shows how to create your own cursor from a bitmap. For the sake
of space I've drawn a torus (doughnut) over a green background but any bitmap,
drawn or loaded from a file or resource, with a unique background color, will do.

  To do this you'll need a created bitmap to copy the screen, under where the
cursor will be placed, so you can replace the background when the cursor moves
and you'll have to get a copy of the screen to start the process. So the steps are

  Replace screen area to old cursor pos
  Get new cursor pos
  Copy background to bmp
  Use TransparentBlt to draw the cursor bmp to screen

Don't forget to destroy the 2 created bitmaps when the dialog closes.

PERSONAL NOTE:
  Many BASIC programmers shun GOTO. I believe it is just like any other
  tool and, when used properly, causes no ill effects to the legibility
  of the code. You'll note that in my code the 3 GOTOs jump down the code.
  This makes it easy to follow the flow as you don't have to be
  constantly running up and down to find the target label.

  GOTO is extreemly fast! No fussing around, no return pointer to set,
  etc. It's clean and efficient. In fact, in assembly, you can't very well
  program without the use of the jump commands and that is all GOTO is.

  So, the rule is: "Use it, don't abuse it."
#endif

#COMPILE EXE
#COMPILER PBWIN 8
#DIM ALL
#INCLUDE "win32api.inc"
'
'-------------------------------------------------------------------------
'
%DKBLUE = &h700000
%LTBLUE = &hFF5656
'
'-------------------------------------------------------------------------
'
CALLBACK FUNCTION Main_CB

  DIM hBMP    AS STATIC DWORD                                            ' Handle to the torus bitmap
  DIM hBmpDC  AS STATIC DWORD                                            ' DC for the torus
  DIM hBkGrnd AS STATIC DWORD                                            ' Handle for background bmp
  DIM tP      AS STATIC POINTL                                           ' Cursor position
  DIM hWnd    AS STATIC DWORD                                            ' Handle for graphic control
  DIM hWndDC  AS STATIC DWORD                                            ' DC for graphic control
                                                                         '
  SELECT CASE AS LONG CBMSG                                              ' process messages
    CASE %WM_SETCURSOR  : GOTO ShowTorus                                 ' mouse moved - update torus
    CASE %WM_INITDIALOG : GOTO CreateTorus                               ' 1st time here
    CASE %WM_COMMAND    : IF CBCTL = 2 THEN                              '  was pressed
                            DIALOG END CBHNDL, 0                         '   so we're gone!
                          END IF                                         '
    CASE %WM_DESTROY    : GRAPHIC ATTACH hBmp, 0                         ' select and delete
                          GRAPHIC BITMAP END                             '  the 2 created bitmaps
                          GRAPHIC ATTACH hBkGrnd, 0                      '
                          GRAPHIC BITMAP END                             '
  END SELECT                                                             '
                                                                         '
  EXIT FUNCTION                                                          '
  '                                                                      '
  '----------------------------------------------------------------------'
  '-- Local Routines ----------------------------------------------------'
  '----------------------------------------------------------------------'
  '                                                                      '
  CreateTorus:                                                           '
    GRAPHIC ATTACH CBHNDL, 1000, REDRAW                                  ' select main control
    GRAPHIC GET DC TO hWndDC                                             ' get the DC for the control
    CONTROL HANDLE CBHNDL, 1000 TO hWnd                                  ' get handle of control
    GRAPHIC COLOR %BLACK, %WHITE                                         ' set colors
    GRAPHIC PAINT (0,0), %BLACK, 0, 2                                    ' fill in a background
    '--------------------------------------------------------------------'
    GRAPHIC BITMAP NEW 49, 49 TO hBMP                                    ' create a new bitmap for the torus
    GRAPHIC ATTACH hBMP, 0                                               ' select it
    GRAPHIC PAINT (0,0), %GREEN                                          ' color the background
    GRAPHIC ELLIPSE ( 0, 0)-(48,48),%DKBLUE, %LTBLUE                     ' draw a circle
    GRAPHIC ELLIPSE (14,14)-(34,34),%DKBLUE, %GREEN                      ' draw an inner circle
    GRAPHIC GET DC TO hBmpDC                                             ' get the DC for the bitmap
    '--------------------------------------------------------------------'
    GRAPHIC BITMAP NEW 49, 49 TO hBkGrnd                                 ' create a new bitmap to save the area
    GRAPHIC ATTACH hBkGrnd, 0                                            ' under the torus when it's moved
    GRAPHIC COPY CBHNDL, 1000, (0,0)-(48,48) TO (0,0)                    ' copy bkgrnd
  GOTO StartHere                                                         ' jump down to capture/show
                                                                         '
  ShowTorus:                                                             '
    MOUSEPTR 0                                                           ' turn off the mouse pointer
    GRAPHIC COPY hBkGrnd, 0 TO (tP.X,tP.Y)                               ' replace bkgrnd under the torus
    GetCursorPos tP                                                      ' get new cursor position
  StartHere:                                                             ' capture bkbrnd to start the process
    ScreenToClient hWnd, tP                                              ' translate to local coords
    IF (tP.X < 0)     OR _                                               ' check if mouse has gone off the window
       (tP.Y < 0)     OR _                                               ' so the torus stays in sight
       (tP.X > 251)   OR _                                               '
       (tP.Y > 251) THEN                                                 '
        tP.X = MIN(MAX(0,tP.X),251)                                      '
        tP.Y = MIN(MAX(0,tP.Y),251)                                      '
        ClientToScreen CBHNDL, tP                                        ' if so, replace it back
        SetCursorPos tP.X, tP.Y                                          '
      ELSE                                                               '
        GRAPHIC ATTACH hBkGrnd, 0                                        ' select bkgrnd bitmap
        GRAPHIC COPY CBHNDL, 1000,(tP.X,tP.Y)-(tP.X+48,tP.Y+48) TO (0,0) ' copy window into it
        GRAPHIC ATTACH CBHNDL, 1000, REDRAW                              ' reselect window
        TransparentBlt hWndDC, tP.X,tP.Y,49,49,hBmpDC,0,0,49,49,%GREEN   ' copy BMP with transparent bkgrnd
        GRAPHIC REDRAW                                                   ' update the screen
    END IF                                                               '
  FUNCTION = 1                                                           ' we've processed the message

END FUNCTION
'
'-------------------------------------------------------------------------
'
FUNCTION PBMAIN () AS LONG                                               ' create the screen

  DIM hDlg AS LOCAL DWORD
  DIM  Txt AS LOCAL STRING

  Txt = "Press  to end."

  DIALOG NEW PIXELS, %HWND_DESKTOP, Txt, , , 300, 300, TO hDlg

  CONTROL ADD GRAPHIC, hDlg, 1000, "", 0, 0, 299, 299

  DIALOG SHOW MODAL hDlg , CALL Main_CB

END FUNCTION