HOOK使用:全域性鍵盤鉤子
阿新 • • 發佈:2019-02-01
// CatchKey.cpp : Defines the entry point for the DLL application. // #define _WIN32_WINNT 0x0500 //設定系統版本,可以使用底層鍵盤鉤子 #define WM_MY_SHORTS (WM_USER + 105) #include "windows.h" //全域性變數 LPWORD g_lpdwVirtualKey = NULL; //Keycode 陣列的指標 int g_nLength = 0; //Keycode 陣列的大小 HINSTANCE g_hInstance = NULL; //模組例項控制代碼 HHOOK g_hHook = NULL; //鉤子控制代碼 HWND g_hWnd = NULL; BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call,LPVOID lpReserved) { //儲存模組例項控制代碼 g_hInstance = (HINSTANCE)hModule; //在程序結束或執行緒結束時解除安裝鉤子 switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: break; case DLL_THREAD_ATTACH: break; case DLL_PROCESS_DETACH: case DLL_THREAD_DETACH: delete g_lpdwVirtualKey; if (g_hHook != NULL) UnhookWindowsHookEx(g_hHook); break; } return TRUE; } LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam,LPARAM lParam) { //判斷是否是有效按鍵 if (nCode >= HC_ACTION && wParam==WM_KEYDOWN) { BOOL bctrl = GetAsyncKeyState(VK_CONTROL)>>((sizeof(SHORT) *8)-1); KBDLLHOOKSTRUCT* pStruct = (KBDLLHOOKSTRUCT*)lParam; LPWORD tmpVirtualKey = g_lpdwVirtualKey; if (pStruct->vkCode == 80 && bctrl) PostMessage(g_hWnd,WM_MY_SHORTS,0,1); return TRUE; } //傳給系統中的下一個鉤子 return CallNextHookEx(g_hHook, nCode, wParam, lParam); } _declspec(dllexport) BOOL WINAPI StartCatch(LPWORD lpdwVirtualKey, int nLength, HWND pWnd) { g_hWnd = pWnd; //如果已經安裝鍵盤鉤子則返回 FALSE if (g_hHook != NULL) return FALSE; //將使用者傳來的 keycode 陣列儲存在全域性變數中 g_lpdwVirtualKey = (LPWORD)malloc(sizeof(WORD) * nLength); LPWORD tmpVirtualKey = g_lpdwVirtualKey; for (int i = 0; i < nLength; i++) { *tmpVirtualKey++ = *lpdwVirtualKey++; } g_nLength = nLength; //安裝底層鍵盤鉤子 g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, g_hInstance, NULL); if (g_hHook == NULL) return FALSE; return TRUE; } _declspec(dllexport) BOOL WINAPI StopCatch() { //解除安裝鉤子 if (UnhookWindowsHookEx(g_hHook) == 0) return FALSE; g_hHook = NULL; return TRUE; }
利用底層的鍵盤鉤子
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam,LPARAM lParam)
來攔截 按鍵的時候
鍵盤的鍵按下和彈起時候會發生WM_KEYUP 和
WM_KEYDOWN兩個訊息,
這兩個訊息都會被hook,所以如此。
所以需要對 wParam 進行判斷 是 WM_KEYDOWN 還是 WM_KEYUP