#define WM_KEYDOWN 0x0100 #define WM_KEYUP 0x0101 #define WM_CHAR 0x0102 #define WM_SYSKEYDOWN 0x0104 #define WM_SYSKEYUP 0x0105 #define GWL_WNDPROC (-4) #define VK_SHIFT 0x10 #define VK_CONTROL 0x11 #define VK_MENU 0x12 Public goForm goForm = CreateObject("frmSample") goForm.Show() Define Class frmSample as Form Add OBJECT txtTest as Textbox nOldProc = 0 Procedure Init DECLARE integer GetWindowLong IN WIN32API ; integer hWnd, ; integer nIndex DECLARE integer CallWindowProc IN WIN32API ; integer lpPrevWndFunc, ; integer hWnd,integer Msg,; integer wParam,; integer lParam Declare Long GetKeyState in WIN32API LONG nVirtKey THIS.nOldProc=GetWindowLong(This.HWnd,GWL_WNDPROC) BindEvent(This.HWnd,WM_KEYDOWN,This,"WndProc") BindEvent(This.HWnd,WM_KEYUP,This,"WndProc") BindEvent(This.HWnd,WM_SYSKEYDOWN,This,"WndProc") BindEvent(This.HWnd,WM_KEYUP,This,"WndProc") BindEvent(This.HWnd,WM_CHAR,This,"WndProc") EndProc Procedure Unload UnBindEvents(This.HWnd,WM_KEYDOWN) EndProc Procedure WndProc(hWnd as Long,Msg as Long,wParam as Long,lParam as Long ) Local lnRetvalue, llDefault llDefault = .T. Do case Case m.Msg == WM_KEYDOWN * This.KeyMsg( "WM_KEYDOWN", m.wParam, m.lParam ) Case m.Msg == WM_KEYUP This.KeyMsg( "WM_KEYUP", m.wParam, m.lParam ) Case m.Msg == WM_SYSKEYDOWN * This.KeyMsg( "WM_SYSKEYDOWN", m.wParam, m.lParam ) Case m.Msg == WM_SYSKEYUP This.KeyMsg( "WM_SYSKEYUP", m.wParam, m.lParam ) Case m.Msg == WM_CHAR This.KeyMsg( "WM_CHAR", m.wParam, m.lParam ) EndCase If m.llDefault lnRetvalue = CallWindowProc(this.noldproc,hWnd,msg,wParam,lParam) EndIf Return m.lnRetvalue Procedure KeyMsg( tcMsg, wParam, lParam ) Activate Screen ? m.tcMsg, m.wParam, m.lParam ? " CTRL", Bittest(GetKeyState(VK_CONTROL),15) ? " SHIFT", Bittest(GetKeyState(VK_SHIFT),15) ? " ALT", Bittest(GetKeyState(VK_MENU),15) ? EndDefine