2014-08-27 46 views
5

我在窗口上使用低级别键盘挂钩。它的作用就像一个魅力,尽管我目前无法分辨出钥匙是最初被按下还是再次按下。 documentation(+ here)说,位7保持过渡状态。但是,当钥匙被释放时,这似乎只是真的。当我第一次按下键时,位7很遗憾地没有设置。使用KBDLLHOOKSTRUCT确定第一次按键

有什么办法可以判断最初是否按下了按键?

+0

键盘钩子的许多问题之一是键盘状态是每个进程的属性。所以你完全取决于拥有前景窗口的过程以及它*之前是否已经看到了密钥。 – 2014-08-27 11:52:35

+0

我知道,但我不在乎这种情况。我希望用户只关注我的流程,但我意识到风险,谢谢! – 2014-08-27 12:31:45

+3

@Hans键盘状态由每个线程(或线程组,如果多个线程由于调用'AttachThreadInput'而连接在一起)控制。用*线程或线程组*替换* process *的所有匹配项*修复您的评论。 – IInspectable 2014-08-27 14:30:54

回答

1

我碰巧遇到这个问题最近。我找不到任何好的解决方案,但我最终在SetWindowHookEx之前使用了一个标志和一个GetAsyncKeyState

BOOL wasDown; 

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { 
    if (nCode == HC_ACTION) { 
     LPKBDLLHOOKSTRUCT key = (LPKBDLLHOOKSTRUCT) lParam; 
     if (key->vkCode == VK_SOMETHING) { 
      switch (wParam) { 
       case WM_KEYDOWN: 
       case WM_SYSKEYDOWN: 
        if (!wasDown) { 
         // Processing on first key down 
         wasDown = true; 
        } 
        break; 
       case WM_KEYUP: 
       case WM_SYSKEYUP: 
        // Processing on key up 
        wasDown = FALSE; 
        break; 
      } 
    } 
    return CallNextHookEx(NULL, nCode, wParam, lParam); 
} 

wasDown = GetAsyncKeyState(VK_SOMETHING) < 0; 
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0); 

当然,这段代码只能用于一个键。您可以使用一组标志来执行多个键。根据您的应用程序,如果您希望在设置钩子后进行第一次按下,则可以无条件地将标志设置为false

+0

这正是我目前所做的,直到有人发布更好的解决方案。谢谢! – 2014-08-28 19:17:54