PUBLIC oform1 oform1=NEWOBJECT("form1") ACTIVATE WINDOW "Debug Output" oform1.Show RETURN DEFINE CLASS form1 AS form Autocenter = .t. showwindow = 2 Caption = "IMPLEMENT KeyUp and KeyDown events" Name = "form1" keypreview = .T. ADD OBJECT text1 AS textbox WITH ; Height = 23, ; Left = 92, ; Top = 80, ; Width = 100, ; Name = "Text1" PROCEDURE keypress LPARAMETERS nKeyCode, nShiftAltCtrl DEBUGOUT "Form", nKeyCode, nShiftAltCtrl PROCEDURE keyup LPARAMETERS nVirtualKeyCode; , nScanCode ; , lExtendKey DEBUGOUT "Up ",nVirtualKeyCode; , nScanCode ; , lExtendKey ENDPROC PROCEDURE keydown LPARAMETERS nVirtualKeyCode; , nScanCode ; , lExtendKey ; , lStillDown ; , nRepeatCount DEBUGOUT "Down",nVirtualKeyCode; , nScanCode ; , lExtendKey ; , lStillDown ; , nRepeatCount ENDPROC PROCEDURE winproc LPARAMETERS hWnd,msg,wParam,lParam #DEFINE WM_KEYDOWN 0x0100 #DEFINE WM_KEYUP 0x0101 DO CASE CASE m.msg = WM_KEYDOWN this.KeyDown(m.wParam, BITAND(BITRSHIFT(m.lParam,16),0xFF); , BITTEST(m.lParam,24) ; , BITTEST(m.lParam,30) ; , BITAND(m.lParam,0xFFFF)) CASE m.msg = WM_KEYUP this.KeyUp(m.wParam, BITAND(BITRSHIFT(m.lParam,16),0xFF); , BITTEST(m.lParam,24)) ENDCASE RETURN CallWindowProc(m.this.WndProc,m.hWnd,m.msg,m.wParam,m.lParam) ENDPROC PROCEDURE Init #DEFINE WM_KEYDOWN 0x0100 #DEFINE WM_KEYUP 0x0101 #DEFINE GWL_WNDPROC -4 DECLARE LONG GetWindowLong IN user32.dll LONG ,INTEGER nIndex DECLARE integer CallWindowProc IN user32.dll ; integer lpPrevWndFunc,LONG , integer Msg ,integer wParam ,integer lParam ADDPROPERTY(M.THIS,'WndProc',GetWindowLong(m.this.hWnd,GWL_WNDPROC)) CLEAR DLLS "GetWindowLong" =BINDEVENT(m.this.hWnd,WM_KEYDOWN,m.this,'WinProc'); ,BINDEVENT(m.this.hWnd,WM_KEYUP,m.this,'WinProc') ENDPROC PROCEDURE Destroy CLEAR DLLS "CallWindowProc" ENDDEFINEFor the ALT, and others system/hot keys, WM_SYSKEYDOWN,WM_SYSKEYUP ...