C++;ToUnicodeEx()无法识别shift键,除非我有一个messgaebox()文件 在C++中编写一个键盘钩子有点麻烦。
我可以读取击键,但我尝试在按下shift键时使用ToUnicodeEx()转换击键。 到目前为止,在我的代码中C++;ToUnicodeEx()无法识别shift键,除非我有一个messgaebox()文件 在C++中编写一个键盘钩子有点麻烦。,c++,visual-studio-2010,hook,C++,Visual Studio 2010,Hook,我可以读取击键,但我尝试在按下shift键时使用ToUnicodeEx()转换击键。 到目前为止,在我的代码中 i = ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout); MessageBox(MainnhWnd,keybuff, L"message", MB_OK | MB_ICON
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键时,会弹出两个消息框,第一个是空白的Shift键,第二个显示“@”字符。这是意料之中的
但是如果我删除这个messagebox,ToUnicodeEx()函数将转换击键,就像没有使用shift键一样。我可以通过设置断点、使用命中计数器或将字符输出到程序窗口中的编辑框来看到这一点
另外,当我包括MsgBox行并使用CapLock时,我的字母也会相应地改变,但在我删除MsgBox行后,它只使用程序启动时cap lock的状态(程序启动时,大写字母锁定处于打开状态,所有字母都是大写字母,反之,程序启动时,大写字母关闭所有字母都是小字母,即使我更改了大写字母锁定状态)
有人知道为什么我的钩子只记得开始时的键盘状态,除非我包含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);
}
根据的文档,您应该提供一个指向256字节数组的指针,该数组包含当前键盘状态(
const byte*lpKeyState
)。数组中的每个元素(字节)都包含一个键的状态。如果设置了字节的高位,则该键为向下键
在调用ToUnicodeEx
之前,应将此数组设置为如下(伪代码):
设置keyState数组后,可以调用:
ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);
我一直在使用像这样的ToUnicodeEx
函数,它工作得很好。希望这能帮助您;)GetKeyboardLayout和GetKeyState返回键盘布局和进程状态。不是那个会收到键盘信息的人。您不能可靠地使用ToUnicodeEx(),需要一个带有WH_键盘的全局钩子。@HansPassant我认为您可以。这是一个全局钩子,因此函数位于DLL中,并且该DLL被注入到原始进程中。所以这些函数应该按预期工作。@rodrigo-WH\u键盘\u LL不是全局钩子。没有注入DLL,Windows在您自己的进程中调用钩子回调,然后将消息添加到具有前景的窗口的消息队列中。OP发现MessageBox之所以有效,是因为它将焦点从窗口上移开了。@HansPassant-事实上,根据他的说法,WH_KEYBOARD_LL是一个全局唯一的钩子。可能低级钩子不同于其他全局钩子,并且不需要DLL(我没有测试它)。但我在文档中没有看到任何关于这方面的参考。谢谢,这很有效。我认为是与keyState变量有关,但我认为GetKeyboardState()更新了它。现在我只需要识别caps lock是否处于活动状态,但这不应该太难。
ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);