該例的鈎子都是寫在一個DLL中的,和應用程序獨立開來的全局鈎子。
一般情況下,如果要截獲鼠標和普通按鍵,剛可以用下邊的方法
鼠標:
LRESULT CALLBACK MouseProc( int nCode, // hook code WPARAM wParam, // message identifier LPARAM lParam // mouse coordinates ) { return TRUE; }
鍵盤:
LRESULT CALLBACK KeyboardProc( int code, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information ) { return TRUE; }
上邊這個鍵盤鈎子只能截獲普通鍵,像WIN鍵、CTRL+ESC什么的是截獲不了的,如果要截獲這些比較牛的功能鍵及組合鍵,那就要用低級鍵盤鈎子了
低級鍵盤鈎子:
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam ) { if(nCode==HC_ACTION) { KBDLLHOOKSTRUCT *kblp=(KBDLLHOOKSTRUCT*)lParam; BOOL bCtrlKeyDown = GetAsyncKeyState(VK_CONTROL)>>((sizeof(SHORT) * 8) - 1); if ((kblp->vkCode==VK_ESCAPE && bCtrlKeyDown) || // Ctrl+Esc // Alt+TAB (kblp->vkCode==VK_TAB && kblp->flags & LLKHF_ALTDOWN) || // Alt+Esc (kblp->vkCode==VK_ESCAPE && kblp->flags & LLKHF_ALTDOWN)|| (kblp->vkCode==VK_LWIN || kblp->vkCode==VK_RWIN)) { return TRUE; // 不再往CallNextHookEx傳遞,直接返回 } } return CallNextHookEx(g_KeyBoardHook, nCode, wParam, lParam); }
然后通過下邊的方法安裝和卸載鈎子:
VOID __stdcall InstallHookEv() { //g_KeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, theApp.m_hInstance, 0); g_LowKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)LowLevelKeyboardProc, theApp.m_hInstance, 0); g_MouseHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseProc, theApp.m_hInstance, 0); } VOID __stdcall UninstallHookEv() { //UnhookWindowsHookEx(g_KeyBoardHook); UnhookWindowsHookEx(g_LowKeyBoardHook); UnhookWindowsHookEx(g_MouseHook); }
這些方法中帶"g_"的變量都是定義在DLL中這些方法所在的.cpp文件最上邊的
HHOOK g_KeyBoardHook = NULL; HHOOK g_LowKeyBoardHook = NULL; HHOOK g_MouseHook = NULL;
要包含頭文件
#include <Windows.h>
這些方法我自己在多台機子上測試時有時候會出些問題,我這個DEMO運行后是托盤圖標形式的,鈎子是可以按情況安裝和卸載的,在有的機子上安裝卸載一次后,托盤圖標右鍵菜單點擊沒反應,其他一切正常;在另一台機子上安裝鈎子后好像無法卸載鈎子。這些問題的出現我想可能和這些機子上的安全軟件有關。