- // 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