(注意:本章沒有用到DLL,而是直接鉤住當前程序!!)
首先列舉 一下WindowsHOOK基本的函數(主要關于鍵盤…):
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 函數,前者是普通的鉤子函數,而后者是一個低級的鉤子函數,這兩個函數的參數不同,所以要獲取的值也不同!!摘自MSDN:KeyboardProc的函數參數(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.
怎么說呢,這個參數其實主要看16-23位,剛好達到8位,也就是一個掃描碼!
那么像這樣的參數給我們有什么用啊?其實如果你 用過函數 GetKeyNameText
就知道了,他的第一個參數就是lparam,也就是KeyboardProc 第三個參數!!是不是很巧?就是用他來獲取到按下的鍵盤名,所以這個函數 可以和KeyboardProc 一起使用!
下面就介紹 LowLevelboardProc 函數,參數和KeyboardProc 一樣,但是參數所起的作用差距很大,可謂 失之毫厘,差之千里~~
當 SetWindowsHookEx() 參數idHOOK 為WH_KEYBORAD_LL時,這個函數的參數中的wparam 為 鍵盤消息,如WM_KEYDOMN… 那么lparam 就是一個 LPKBDLLHOOKSTRUCT結構體了!看這個結構體的名字就知道這是一個用于 低級鍵盤鉤子的,“LL”->”LowLevel“,呵呵~這個結構體中 包括了 虛擬鍵代碼 和 掃描碼!
如上所述,我們大概就知道LowLevelboardProc 和 KeyboardProc的差別了,
但別忘了還有那個 SetWindowsHookEx()函數,現在在回憶一下那個函數原型:
HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWORD dwThreadId
);
當IdHook為WH_KEYBOARD 時,lpfn為KeyboardProc(名字自定義),hMod為當前程序實例句柄,MFC 有多種方法獲取,如:AfxGetInstanceHandle()
最后一個 dwThreadId為0!!至于為什么,我現在還不是很清楚,希望有大神解答…
所以,當idHook為WH_KEYBOARD_LL時,dwThreadid 必須為當前模塊的線程ID!
看下圖來對比下:
據此,我把主要代碼給出來
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為當前程序的線程ID!
//卸載鉤子
UnhookWindowsHookEx(hHook2);
下面是關于低級鍵盤鉤子的代碼;
//低級的鍵盤鉤子
hHook= ::SetWindowsHookEx(WH_KEYBOARD_LL,myLowLevelKeyboardProc,AfxGetInstanceHandle(),0);//注意這里TID為 0
//卸載低級鉤子
UnhookWindowsHookEx(hHook)
//低級鉤子函數處理過程
LRESULT CALLBACK LowLevelKeyboardProc(_In_int code,_In_WPARAMwParam,_In_LPARAMlParam)
{
if (code < 0)
{
returnCallNextHookEx(hHook,code,wParam,lParam);
}
// 低級鍵盤鉤子時,wparam參數為 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);
}
基本上注釋已經說明了,那么本文也就到此結束了…
新聞熱點
疑難解答