我在用C++编写键盘挂钩时遇到了一些麻烦。
我可以阅读击键,但是我想在按下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_ICONEXCLAMATION);
当我按Shift + 2时,在此“MessageBox”行中,我弹出两个消息框,第一个为Shift键为空白,第二个显示为“@”字符。这是预期的。
但是,如果我删除此消息框,则ToUnicodeEx()函数将转换击键,就好像未使用shift键一样。通过设置断点,命中计数器或将字符输出到程序窗口中的编辑框,我可以看到这一点。
另外,当我包括MsgBox行并使用CapLock时,我的字母也会相应更改,但是当我删除msgbox行之后,它仅在程序启动时使用大写锁定的状态(当programm启动时大写锁定处于打开状态,所有字母均为大写,反之亦然,即使我更改了大写锁定状态,在programm启动时,所有字母也都变小了
有人知道为什么我的钩子(Hook)只记得启动时的键盘状态,除非我包括msgbox?
我的钩子(Hook)设置为:
theHook = SetWindowsHookEx ( WH_KEYBOARD_LL, (HOOKPROC) KeyEvent, exe, 0);
我的钩子(Hook)回调函数是:
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);
}
最佳答案
根据ToUnicodeEx function的文档,您应该提供一个指向包含当前键盘状态(const BYTE *lpKeyState
)的256字节数组的指针。数组中的每个元素(字节)都包含一个键的状态。如果设置了字节的高位,则该键按下。
在调用ToUnicodeEx
之前,应像下面这样设置该数组(伪代码):
enum Keys
{
ShiftKey = 16, // shift
ControlKey = 17, // ctrl
Menu = 18, // alt
Capital = 20, // caps lock
};
BYTE keyState[256]= {0};
if (Control key down)
keyState[Keys::ControlKey] = 0x80;
if (Shift key down)
keyState[Keys::ShiftKey] = 0x80;
if (Alt key down)
keyState[Keys::Menu] = 0x80;
if (Caps lock ON)
keyState[Keys::Capital] = 0x01;
并设置了keyState数组后,您可以调用:
ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);
我一直在使用
ToUnicodeEx
函数,并且效果很好。希望这能够帮到你 ;)