(注意:本章沒有用到DLL,而是直接鉤住當(dāng)前程序!!)
首先列舉 一下WindowsHOOK基本的函數(shù)(主要關(guān)于鍵盤…):
HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWord dwThreadId
);
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK hhk,_In_ int nCode,_In_ WPARAM wParam,_In_ LPARAM lParam);BOOL WINAPI UnhookWindowsHookEx(
_In_ HHOOKhhk
);
LRESULT CALLBACK KeyboardProc(
_In_ int code,
_In_ WPARAMwParam,
_In_ LPARAMlParam
);
LRESULT CALLBACK LowLevelKeyboardProc(_In_ int nCode,_In_ WPARAM wParam,_In_ LPARAM lParam);注意 上面的 KeyboardProc 和 LowLevelKeyboardProc 函數(shù),前者是普通的鉤子函數(shù),而后者是一個(gè)低級(jí)的鉤子函數(shù),這兩個(gè)函數(shù)的參數(shù)不同,所以要獲取的值也不同!!摘自MSDN:KeyboardProc的函數(shù)參數(shù)(wparam和lparam)使用wParam [in]
Type: WPARAM
The virtual-key code of the key thatgenerated the keystroke message.
lParam [in]
Type: LPARAM
The repeat count, scan code, extended-key flag, contextcode, previous key-state flag, and transition-state flag. For more informationabout thelParam parameter, seeKeystroke Message Flags. The following table describes the bits of this value.
由此可看出 ,wparam主要是鍵盤的虛擬鍵代碼,lparam主要是:
The lParam parameter of a keystroke message containsadditional information about the keystroke that generated the message. Thisinformation includes therepeat count, the scan code, the extended-key flag, thecontext code, the previous key-state flag, and the transition-state flag.The following illustration shows the locations of these flags and values in thelParam parameter.
怎么說呢,這個(gè)參數(shù)其實(shí)主要看16-23位,剛好達(dá)到8位,也就是一個(gè)掃描碼!
那么像這樣的參數(shù)給我們有什么用啊?其實(shí)如果你 用過函數(shù) GetKeyNameText
就知道了,他的第一個(gè)參數(shù)就是lparam,也就是KeyboardProc 第三個(gè)參數(shù)!!是不是很巧?就是用他來獲取到按下的鍵盤名,所以這個(gè)函數(shù) 可以和KeyboardProc 一起使用!
下面就介紹 LowLevelboardProc 函數(shù),參數(shù)和KeyboardProc 一樣,但是參數(shù)所起的作用差距很大,可謂 失之毫厘,差之千里~~
當(dāng) SetWindowsHookEx() 參數(shù)idHOOK 為WH_KEYBORAD_LL時(shí),這個(gè)函數(shù)的參數(shù)中的wparam 為 鍵盤消息,如WM_KEYDOMN… 那么lparam 就是一個(gè) LPKBDLLHOOKSTRUCT結(jié)構(gòu)體了!看這個(gè)結(jié)構(gòu)體的名字就知道這是一個(gè)用于 低級(jí)鍵盤鉤子的,“LL”->”LowLevel“,呵呵~這個(gè)結(jié)構(gòu)體中 包括了 虛擬鍵代碼 和 掃描碼!
如上所述,我們大概就知道LowLevelboardProc 和 KeyboardProc的差別了,
但別忘了還有那個(gè) SetWindowsHookEx()函數(shù),現(xiàn)在在回憶一下那個(gè)函數(shù)原型:
HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWORD dwThreadId
);
當(dāng)IdHook為WH_KEYBOARD 時(shí),lpfn為KeyboardProc(名字自定義),hMod為當(dāng)前程序?qū)嵗浔琈FC 有多種方法獲取,如:AfxGetInstanceHandle()
最后一個(gè) dwThreadId為0!!至于為什么,我現(xiàn)在還不是很清楚,希望有大神解答…
所以,當(dāng)idHook為WH_KEYBOARD_LL時(shí),dwThreadid 必須為當(dāng)前模塊的線程ID!
看下圖來對(duì)比下:
據(jù)此,我把主要代碼給出來
HHOOK hHook2;
LRESULT CALLBACK KeyBoradProc(intcode,WPARAMwp,LPARAMlp)
{
if (code<0)
{
return CallNextHookEx(hHook2,code,wp,lp);
}
WCHAR szkeyValue[20]={ 0 };
//wsprintf(szkeyValue, L"%c", wp); //虛擬鍵代碼
//獲取按鍵的名稱
GetKeyNameText(lp,szkeyValue, 50);
AfxGetMainWnd()->SetDlgItemText(IDC_EDIT1,szkeyValue);
return CallNextHookEx(hHook2,code,wp,lp);
}
//安裝鍵盤鉤子
hHook2 = SetWindowsHookEx(WH_KEYBOARD,KeyBoradProc,AfxGetInstanceHandle(),GetCurrentThreadId()); //注意這里的線程ID為當(dāng)前程序的線程ID!
//卸載鉤子
UnhookWindowsHookEx(hHook2);
下面是關(guān)于低級(jí)鍵盤鉤子的代碼;
//低級(jí)的鍵盤鉤子
hHook= ::SetWindowsHookEx(WH_KEYBOARD_LL,myLowLevelKeyboardProc,AfxGetInstanceHandle(),0);//注意這里TID為 0
//卸載低級(jí)鉤子
UnhookWindowsHookEx(hHook)
//低級(jí)鉤子函數(shù)處理過程
LRESULT CALLBACK LowLevelKeyboardProc(_In_int code,_In_WPARAMwParam,_In_LPARAMlParam)
{
if (code < 0)
{
returnCallNextHookEx(hHook,code,wParam,lParam);
}
// 低級(jí)鍵盤鉤子時(shí),wparam參數(shù)為 WM鍵盤消息!!!
//按下的
if (code ==HC_ACTION&&wParam==WM_KEYDOWN)
{
LPKBDLLHOOKSTRUCTpKbs = (LPKBDLLHOOKSTRUCT)lParam;
WCHARszlMsg[100] = { 0 };
wsprintf(szMsg,L"vkCode:%c-scanCode:%02X",pKbs->vkCode,pKbs->scanCode);
//ESC鍵掃描碼
if (pKbs->scanCode==0x01)
{
returnTRUE;
}
}
return CallNextHookEx(hHook,code,wParam,lParam);
}
基本上注釋已經(jīng)說明了,那么本文也就到此結(jié)束了…
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注