我在C中编写键盘钩子时遇到了一些麻烦 .
我可以读取击键但我试图使用ToUnicodeEx()来按下shift键时转换击键 . 在我迄今为止的代码中
i = ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);
MessageBox(MainnhWnd,keybuff, L"message", MB_OK | MB_ICONEXCLAMATION);
当我按下Shift 2时,按下这个'MessageBox'行我弹出两个消息框,第一个是Shift键空白,第二个是'@'字符 . 这是预料之中的 .
但是,如果我删除此消息框,ToUnicodeEx()函数将转换键击,就像没有使用shift键一样 . 我可以通过设置断点,使用点击计数器或将字符输出到程序窗口中的编辑框来查看 .
此外,当我包含MsgBox行并使用CapLock时,我的字母会相应更改,但在我删除msgbox行之后,它只会在我的程序启动时使用上限锁定的状态(当程序启动时,上限锁定,所有字母都是资本,反之,在程序启动时封顶所有字母都很小,即使我改变了上限锁定状态)
任何人都知道为什么我的钩子会在开始时记住键盘状态,除非我包含msgbox?
我的钩子设置如下:
theHook = SetWindowsHookEx ( WH_KEYBOARD_LL, (HOOKPROC) KeyEvent, exe, 0);
我的钩子回调函数是:
DLLEXPORT LRESULT CALLBACK KeyEvent(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode>=0) {
int i = 0;
KBDLLHOOKSTRUCT keyboard;
WCHAR keybuff[256]= {0};
if ((wParam == WM_KEYDOWN)|| (wParam == WM_SYSKEYDOWN)||(wParam == WM_SYSKEYUP)) {
keyboard = *((KBDLLHOOKSTRUCT*)lParam);
if (keyboard.vkCode == VK_RETURN) {
i += wsprintf (((LPWSTR)keybuff + i),L"[Return]\r\n");
}
else {
HKL keyboardlayout = GetKeyboardLayout(0);
GetKeyboardState((PBYTE)&keyState);
i = ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);
MessageBox(MainnhWnd,keybuff, L"message", MB_OK | MB_ICONEXCLAMATION);
}
if (keybuff>0) {
addToEditBox(keybuff);
}
}
}
return CallNextHookEx(theHook, nCode, wParam, lParam);
}
1 回答
根据ToUnicodeEx function的文档,您应该提供指向包含当前键盘状态(
const BYTE *lpKeyState
)的256字节数组的指针 . 数组中的每个元素(字节)都包含一个键的状态 . 如果设置了一个字节的高位,则键为关闭 .在调用
ToUnicodeEx
之前,你应该像这样设置这个数组(伪代码):当设置keyState数组时,您可以调用:
我一直在使用
ToUnicodeEx
函数就像这样,它工作正常 .希望对你有帮助 ;)