【IT168 技术文档】
#define WH_KEYBOARD_LL 20
#define HC_ACTION 0
typedef LRESULT (CALLBACK
* HOOKPROC)( int
code, WPARAM wParam, LPARAM lParam); typedef HHOOK (WINAPI * _SetWindowsHookExW)( int
, HOOKPROC, HINSTANCE, DWORD); typedef LRESULT (WINAPI * _CallNextHookEx)(HHOOK, int
, WPARAM, LPARAM); typedef LRESULT (WINAPI *
_UnhookWindowsHookEx)(HHOOK); typedef struct ...
{ DWORD vkCode; DWORD scanCode; DWORD flags; DWORD time; ULONG_PTR dwExtraInfo; } KBDLLHOOKSTRUCT, *
PKBDLLHOOKSTRUCT; static _SetWindowsHookExW SetWindowsHookEx; static _UnhookWindowsHookEx UnhookWindowsHookEx; static _CallNextHookEx CallNextHookEx;
然后是实现的代码,LLKeyboardHookCallbackFunction就是回调函数
BOOL ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction)
...
{ // we need to manually load these standard Win32 API calls // MSDN states that these aren't supported in WinCE SetWindowsHookEx = NULL; CallNextHookEx = NULL; UnhookWindowsHookEx = NULL; //从 coredll.dll 获取我们需要的函数 g_hHookApiDLL = LoadLibrary(_T( " coredll.dll " )); if (g_hHookApiDLL == NULL) ... { return FALSE ; } else ... { SetWindowsHookEx = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDLL, _T( " SetWindowsHookExW " )); if (SetWindowsHookEx == NULL) ... { return FALSE ; } else ... { g_hInstalledLLKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyboardHookCallbackFunction, hInstance, 0 ); if (g_hInstalledLLKBDhook == NULL) ... { return FALSE ; } } CallNextHookEx = (_CallNextHookEx)GetProcAddress(g_hHookApiDLL, _T( " CallNextHookEx " )); if (CallNextHookEx == NULL) ... { return FALSE ; } UnhookWindowsHookEx = (_UnhookWindowsHookEx)GetProcAddress(g_hHookApiDLL, _T( " UnhookWindowsHookEx " )); if (UnhookWindowsHookEx == NULL) ... { return FALSE ; } } return TRUE; } BOOL DeactivateKBHook()... { // unload the hook if (g_hInstalledLLKBDhook != NULL) ... { UnhookWindowsHookEx(g_hInstalledLLKBDhook); g_hInstalledLLKBDhook = NULL; } // unload the coredll.dll if (g_hHookApiDLL != NULL) ... { FreeLibrary(g_hHookApiDLL); g_hHookApiDLL = NULL; } // we have terminated gracefully return TRUE; }一般的回调函数是这么写的,BlockKeyList是需要屏蔽的按键列表
int CLoginDlg::BlockKeyList[] = {VK_TBACK,VK_TTALK,VK_TEND,VK_THOME};
LRESULT CALLBACK CLoginDlg::LLKeyboardHookCallbackFunction( int
nCode, WPARAM wParam, LPARAM lParam) ...
{ if (nCode >= HC_ACTION) ... { if (wParam == WM_KEYDOWN || wParam == WM_KEYUP || wParam == WM_LBUTTONDOWN) ... { int countKeyList = ARRAY_SIZEOF(BlockKeyList); for ( int i = 0 ;i < countKeyList;i ++ ) ... { if ((((KBDLLHOOKSTRUCT * )lParam) -> vkCode) == BlockKeyList[i]) ... { return TRUE; } } } } return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam); }
最后还有关键的一点,网上有人说 WH_KEYBOARD_LL不需要用DLL就能实现全局钩子,但是我发觉至少在windows mobile的机器上不行,还是要用DLL来实现键盘钩子。 以上的方法在windows mobile 5.0以及6.0上都可以正常使用,如果你只是要屏蔽所有按键的话可以简单的使用 EnableHardwareKeyboard函数来实现。