首页 文章

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

提问于
浏览
0

我在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 回答

  • 1

    根据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 函数就像这样,它工作正常 .
    希望对你有帮助 ;)

相关问题