我想编写一个简单的全局键盘钩子程序来重定向一些按键。例如,当程序被执行时,我在键盘上按下'a'键,程序可以禁用该按键并模拟'b'键的点击。我不需要图形用户界面,只需要控制台即可(保持运行)。
我的计划是使用全局钩子来捕获键盘输入,然后使用keybd_event来模拟键盘输入。但是我遇到了一些问题。
第一个问题是,程序可以正确地阻止'A'键,但如果我在键盘上敲击'A'键一次,回调函数中的printf会执行两次,以及keybd_event也会执行两次。因此,如果我打开一个文本文件,我按一次'A'键,就会有两个'B'键被输入。这是为什么?
第二个问题是,为什么使用WH_KEYBOARD_LL的钩子可以在没有dll的情况下在其他进程中工作?我以为我们必须使用dll来创建全局钩子,直到我写了这个例子...
#include "stdafx.h"
#include <Windows.h>
#define _WIN32_WINNT 0x050
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
BOOL fEatKeystroke = FALSE;
if (nCode == HC_ACTION)
{
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
if (fEatKeystroke = (p->vkCode == 0x41)) { //redirect a to b
printf("Hello a\n");
keybd_event('B', 0, 0, 0);
keybd_event('B', 0, KEYEVENTF_KEYUP, 0);
break;
}
break;
}
}
return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam));
}
int main()
{
// Install the low-level keyboard & mouse hooks
HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
// Keep this app running until we're told to stop
MSG msg;
while (!GetMessage(&msg, NULL, NULL, NULL)) { //this while loop keeps the hook
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(hhkLowLevelKybd);
return(0);
}
非常感谢!
hMod
,但在这种情况下,您可以使用任何合法值,因为对于低级别钩子不会注入任何DLL。例如,您可以使用GetModuleHandle("kernel32.dll")
。 - user