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