2014-08-27 3 views
5

Я использую низкоуровневую клавиатуру на окнах. Он работает как charme, несмотря на то, что я в настоящее время не могу сказать, был ли ключ первоначально нажат или нажат снова. documentation (+ here) говорит, что бит 7 содержит состояние перехода. Но это кажется правдой только тогда, когда ключ освобождается. Бит 7, к сожалению, не установлен, когда я сначала нажимаю клавишу.Использование KBDLLHOOKSTRUCT для определения первого нажатия клавиши

Есть ли способ узнать, нажата ли клавиша изначально?

+0

Одна из многих проблем с клавиатурными крючками, состояние клавиатуры - свойство для каждого процесса. Итак, все, что вы получаете, полностью зависит от того, какой процесс имеет собственное окно переднего плана и есть ли он * раньше. –

+0

Я знаю, но в данном случае мне все равно. Я ожидаю, что пользователь сосредоточится только на моем процессе, но я знаю о риске, спасибо! –

+3

@Hans Состояние клавиатуры контролируется на поток (или группу потоков, если несколько потоков связаны друг с другом в результате вызова 'AttachThreadInput'). Замена всех вхождений * process * с помощью * потока или группы потоков * исправляет ваш комментарий. – IInspectable

ответ

1

В последнее время я столкнулся с этой проблемой. Я не могу найти никаких хороших решений, но в итоге я использовал флаг и GetAsyncKeyState до SetWindowHookEx.

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

Это именно то, что я делаю сейчас, пока кто-то не опубликует лучшее решение. Благодаря! –