C++ToUnicodeEx()无法识别移位键,除非我有一个messgaebox()

C++ ToUnicodeEx() not recognizing shift key unless i have a messgaebox()

本文关键字:非我 messgaebox 有一个 识别 C++ToUnicodeEx      更新时间:2023-10-16

im在用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时,我会弹出两个消息框,第一个是空的Shift键,第二个显示一个"@"字符。这是意料之中的事。

但是,如果我删除这个消息框,ToUnicodeEx()函数会转换击键,就好像没有使用shift键一样。我可以通过设置断点、使用命中计数器或将字符输出到程序窗口中的编辑框来实现这一点。

此外,当我包括MsgBox行并使用CapLock时,我的字母会相应地改变,但在我删除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]rn");
        }
        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函数的文档,您应该提供一个指向256字节数组的指针,该数组包含当前键盘状态(const BYTE *lpKeyState)。数组中的每个元素(字节)都包含一个键的状态。如果设置了字节的高阶位,则键处于关闭状态。

在调用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函数,它运行得很好
希望这对你有所帮助;)

相关文章: