In PBCC 4.03 and previous versions of PBCC 4, you could subclass the graphic window and capture these messages, there was a change in PBCC 4.04, where you must subclass the static control on the graphic window to capture these messages. A graphic window is a dialog box with one static control on it, the static control is what you actually do the drawing on. All you need to do is get the handle of this static control with hStatic = GetWindow(hGraphicWindow, %GW_CHILD) and subclass hStatic instead of hGraphicWindow. The following example illustrates this:
Code:
#COMPILE EXE #DIM ALL #INCLUDE "Win32Api.Inc" ' GLOBAL GraphicWindowChildOldProc AS LONG GLOBAL finished AS LONG GLOBAL hStatic AS LONG ' ' Timer callback routines, called every 200ms ' Just a little routine to display colored boxes on the graphic window SUB DisplayUpdate(BYVAL uID AS LONG, BYVAL uMsg AS LONG, _ BYVAL dwUser AS LONG, BYVAL dw1 AS LONG, BYVAL dw2 AS LONG) LOCAL r, g, b AS LONG LOCAL c AS LONG LOCAL x, y AS LONG LOCAL w, h AS LONG ' GRAPHIC ATTACH dwUser, 0&, REDRAW GRAPHIC GET CLIENT TO w, h ' r = RND(0, 255) g = RND(0, 255) b = RND(0, 255) ' x = RND(0, w-21) y = RND(30, h-21) ' c = RGB(r,g,b) ' GRAPHIC BOX (x,y) - (x+25,y+25), 20, c, c ' GRAPHIC REDRAW END SUB ' This is the function that is called whenever a Key or Mouse click is detected in the Graphics Window FUNCTION GraphicWindowChildNewProc(BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG LOCAL p AS POINTAPI SELECT CASE wMsg CASE %WM_NCHITTEST CASE %WM_MOUSEMOVE p.x = LO(WORD, lParam) ' Current Mouse X Position in the graphic window p.y = HI(WORD, lParam) ' Current Mouse Y Position in the graphic window ' Convert graphic window coordintates to screen (desktop) coordinates ClientToScreen(hWnd, p) ? "The mouse is at ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+") or screen ("+FORMAT$(p.x)+","+FORMAT$(p.y)+")" CASE %WM_LBUTTONDOWN ? "you clicked the left mouse button at ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")" CASE %WM_RBUTTONDOWN ? "you clicked the right mouse button at ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")" CASE %WM_KEYDOWN IF CHR$(WPARAM) = "X" THEN finished = 1 ELSE ? "you pressed the "+CHR$(wparam)+ " key" END IF END SELECT ' FUNCTION = CallWindowProc(GraphicWindowChildOldProc, hWnd, wMsg, wParam, lParam) END FUNCTION FUNCTION PBMAIN LOCAL w AS LONG LOCAL tid AS LONG LOCAL hGraphicWindow AS LONG ' RANDOMIZE ' finished = 0 ' GRAPHIC WINDOW "Graphic Window SubClass Example", 0, 0, 320, 240 TO hGraphicWindow ' ' Retreive the handle to the static control (the graphic) on the graphic window (dialog box) hStatic = GetWindow(hGraphicWindow, %GW_CHILD) ' ' This function subclasses the Graphic Window ' Which means that any key or mouse presses in the Window ' Will cause the GraphicWindowChildNewProc Callback function to be called GraphicWindowChildOldProc = SetWindowLong(hStatic, %GWL_WNDPROC, CODEPTR(GraphicWindowChildNewProc)) ' ' Create an timer that runs the routine DisplayUpdate every 200ms tid = TimeSetEvent(200, 10, CODEPTR(DisplayUpdate), BYVAL hGraphicWindow, %TIME_PERIODIC) ' GRAPHIC ATTACH hGraphicWindow, 0&, REDRAW GRAPHIC CLEAR %BLACK GRAPHIC COLOR %BLUE, %YELLOW GRAPHIC FONT "Times New Roman", 18, 1 GRAPHIC PRINT "press X to quit" GRAPHIC REDRAW GRAPHIC SET FOCUS ' w = 0 ' ' loop until an X is pressed on the graphic window WHILE finished = 0 INCR w ' Every third iteration of the loop give back ' one time slick to Windows too prevent 100% CPU utilization ' See the SLEEP statement in the Help file IF w MOD 3 = 0 THEN SLEEP 0 END IF WEND ' ' Stop the timer from running TimeKillEvent(tid) ' ' Set the graphics window to use the original Callback routine SetWindowLong(hStatic, %GWL_WNDPROC, GraphicWindowChildOldProc) ' GRAPHIC ATTACH hGraphicWindow, 0& GRAPHIC WINDOW END END FUNCTION