In PBWin 8.03 and previous versions of PBWin 8, you could subclass the graphic window and capture these messages, there was a change in PBWin 8.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 how to capture mouse and keyboard messages from both a graphic control and a graphic window in PBWin 8.04:
Code:
#COMPILE EXE #DIM ALL #INCLUDE "WIN32API.INC" %IDC_LISTBOX1 = 1001 %IDC_GRAPHIC1 = 1002 GLOBAL GraphicWindowOldProc AS LONG GLOBAL GraphicControlOldProc AS LONG GLOBAL hDlg AS LONG ' Add a string to the list box and ensure that the last added string is visible MACRO AddListBoxString(s) CONTROL SEND hDlg, %IDC_LISTBOX1, %LB_ADDSTRING, 0, VARPTR(s) TO i CONTROL SEND hDlg, %IDC_LISTBOX1, %LB_SETTOPINDEX, i, 0 END MACRO ' Callback routine to capture messages sent to the graphic window FUNCTION GraphicWindowNewProc(BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG LOCAL i AS LONG LOCAL s AS ASCIIZ * 256 SELECT CASE wMsg CASE %WM_MOUSEMOVE s = "GRAPHIC WINDOW: %WM_MOUSEMOUSE ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")" CASE %WM_LBUTTONDOWN s = "GRAPHIC WINDOW: %WM_LBUTTONDOWN ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")" CASE %WM_RBUTTONDOWN s = "GRAPHIC WINDOW: %WM_RBUTTONDOWN ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")" CASE %WM_KEYDOWN s = "GRAPHIC WINDOW: %WM_KEYDOWN key = "+CHR$(wParam) END SELECT IF LEN(s) THEN AddListBoxString(s) END IF ' Call the default callback routine to process any message we did not FUNCTION = CallWindowProc(GraphicWindowOldProc, hWnd, wMsg, wParam, lParam) END FUNCTION ' Callback routine to capture messages sent to the graphic control FUNCTION GraphicControlNewProc(BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG LOCAL i AS LONG LOCAL s AS ASCIIZ * 256 SELECT CASE wMsg CASE %WM_MOUSEMOVE s = "GRAPHIC CONTROL: %WM_MOUSEMOUSE ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")" CASE %WM_LBUTTONDOWN s = "GRAPHIC CONTROL: %WM_LBUTTONDOWN ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")" CASE %WM_RBUTTONDOWN s = "GRAPHIC CONTROL: %WM_RBUTTONDOWN ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")" CASE %WM_KEYDOWN s = "GRAPHIC CONTROL: %WM_KEYDOWN key = "+CHR$(wParam) END SELECT IF LEN(s) THEN AddListBoxString(s) END IF ' Call the default callback routine to process any message we did not FUNCTION = CallWindowProc(GraphicControlOldProc, hWnd, wMsg, wParam, lParam) END FUNCTION ' Callback routine to process messages sent to the dialog box CALLBACK FUNCTION DlgProc STATIC hGrWin AS LONG SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG ' Setup the graphic window GRAPHIC WINDOW "Graphic Window SubClass Example", 0, 0, 320, 240 TO hGrWin GRAPHIC ATTACH hGrWin, 0, REDRAW GRAPHIC CLEAR %BLACK GRAPHIC COLOR %YELLOW, %BLACK GRAPHIC PRINT "Move the mouse over the graphic window" GRAPHIC PRINT "or click the mouse on the graphic window" GRAPHIC PRINT "or press a key, the window must have focus" GRAPHIC PRINT "before a keypress can be captured." GRAPHIC REDRAW ' Setup the graphic control GRAPHIC ATTACH CBHNDL, %IDC_GRAPHIC1 GRAPHIC CLEAR %BLACK GRAPHIC COLOR %YELLOW, %BLACK GRAPHIC PRINT "Move the mouse over the graphic window" GRAPHIC PRINT "or click the mouse on the graphic window" GRAPHIC PRINT "or press a key, the window must have focus" GRAPHIC PRINT "before a keypress can be captured." GRAPHIC REDRAW ' Get the handle of the static control on the graphic window hGrWin = GetWindow(hGrWin, %GW_CHILD) ' Subclass the static control on the graphic window GraphicWindowOldProc = SetWindowLong(hGrWin, %GWL_WNDPROC, CODEPTR(GraphicWindowNewProc)) ' Subclass the graphic control GraphicControlOldProc = SetWindowLong(GetDlgItem(CBHNDL, %IDC_GRAPHIC1), %GWL_WNDPROC, CODEPTR(GraphicControlNewProc)) CASE %WM_DESTROY ' Set the graphic window to use it's original callback routine SetWindowLong(GetDlgItem(CBHNDL, %IDC_GRAPHIC1), %GWL_WNDPROC, GraphicControlOldProc) ' Set the graphic control to use it's original callback routine SetWindowLong(hGrWin, %GWL_WNDPROC, GraphicWindowOldProc) END SELECT END FUNCTION FUNCTION PBMAIN () AS LONG DIALOG NEW 0, "Graphic Subclass Example", 100, 170, 451, 205, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR _ %WS_SYSMENU OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD LISTBOX, hDlg, %IDC_LISTBOX1, , 5, 5, 280, 195, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL _ OR %LBS_NOSEL OR %LBS_NOINTEGRALHEIGHT, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _ %WS_EX_RIGHTSCROLLBAR CONTROL ADD GRAPHIC, hDlg, %IDC_GRAPHIC1, "", 290, 5, 155, 195, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR _ %SS_NOTIFY, %WS_EX_CLIENTEDGE DIALOG SHOW MODAL hDlg, CALL DlgProc END FUNCTION