Hook(鉤子)是一種在消息到達目標窗口前進行截獲的技術。使用鉤子主要使用以下三個函數SetWindowsHookEx:創建鉤子
CallNextHookEx:將消息傳給鉤子鏈中的下一個鉤子
UnhookWindowsHookEx:釋放鉤子
對于創建鉤子的函數SetWindowsHookEx,MSDN給出其原形如下:
HHOOK SetWindowsHookEx(
int idHook, // type of hook to install
HOOKPROC lpfn, // address of hook procedure
HINSTANCE hMod, // handle to application instance
DWORD dwThreadId // identity of thread to install hook for
);
這些在windows上面使用沒有問題,但是在說明的最后,關于平臺限制的地方,可以清楚的看到以下文字:Windows CE: Unsupported.
也就是說,wince并不支持鉤子。
但是是不是不支持呢?只能說不直接支持鉤子,用別的方法也是可以使用鉤子函數的,那就是直接獲取鉤子函數地址,然后調用的方法。
g_hHookApiDLL = LoadLibrary(_T("coredll.dll"));
SetWindowsHookEx = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDLL, _T("SetWindowsHookExW"));
如法炮制,可以獲得其他兩個函數的地址,有了這三個函數的地址,就可以類似這樣使用了:
g_hInstalledLLKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardProc, hInstance, 0);
關于wince的鉤子,有以下總結,不盡不對之處,請給飛狐指正:
1 參看WinCE的winbase.h,wince下可以使用以下三種:
#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD_LL 20
其中最有用的就是鍵盤鉤子了。Wince里面定義其為20,而不是windows里面的14,因此調用時要注意。
2 關于鍵盤鉤子回調函數keyboardProc,它里面的幾個參數并不像MSDN里面提到的KeyboardProc那樣:
LRESULT CALLBACK KeyboardProc(
int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam // keystroke-message information
按照說明,wParam應該存的是虛擬鍵信息。然而事實上,這三個函數中,第二個是用來指示是鍵按下還是彈起,第三個參數lParam才是真正存儲的按鍵信息數據。它存儲的是一個KBDLLHOOKSTRUCT結構體指針。這個結構體定義如下:
typedef struct {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT;
結構體里面才是真正的按鍵信息。
3對于鍵盤鉤子,我只能使用一個,如果創建二個鉤子來檢測(不管是使用同一個dll,還是兩個不同的dll),則第一個可以正常工作,但是第二個會報錯,錯誤id是31 ERROR_GEN_FAILURE即
A device attached to the system is not functioning.
不知道哪位高手有解決方案?
4 鉤子有線程級和全局鉤子,但是我只試驗成功了全局鉤子,工作很好,但是線程級鉤子還沒有成功。
5 鉤子用途很多,我們就用它和驅動打交道,具體也不多說了。
鉤子函數源代碼在采用codeproject網站上面Prathamesh S Kulkarni的源代碼基礎上,增加了處理按鍵消息的部分,代碼比較長,就不貼了,有需要的可以交流,或者參看Prathamesh S Kulkarni的文章。