2014-08-27 16 views
5

Używam niskiego poziomu haka klawiatury w systemie Windows. Działa jak czar, mimo że obecnie nie jestem w stanie stwierdzić, czy klawisz został pierwotnie wciśnięty, czy też został naciśnięty ponownie. documentation (+ here) mówi, że bit 7 przechowuje stan przejścia. Ale wydaje się, że tak jest tylko wtedy, gdy klucz zostanie wydany. Bit 7 niestety nie jest ustawiony, kiedy po raz pierwszy naciskam klawisz.Używanie KBDLLHOOKSTRUCT do określenia pierwszego naciśnięcia klawisza

Czy istnieje sposób sprawdzenia, czy klawisz jest naciśnięty na początku?

+0

Jednym z wielu problemów z hakami klawiatury, stanem klawiatury jest właściwość procesu. Więc to, co dostajesz w całości, zależy od tego, co się stanie z właścicielem okna na pierwszym planie i czy * it * zobaczył klucz wcześniej. –

+0

Wiem, ale nie obchodzi mnie w tym przypadku. Spodziewam się, że użytkownik skupi się tylko na moim procesie, ale jestem świadomy ryzyka, dzięki! –

+3

@Hans Stan klawiatury jest kontrolowany dla jednego wątku (lub grupy wątków, jeśli kilka wątków jest powiązanych w wyniku wywołania 'AttachThreadInput'). Zastąpienie wszystkich wystąpień * procesu * * wątkiem lub grupą wątków * naprawia twój komentarz. – IInspectable

Odpowiedz

1

Ostatnio napotkałem na ten problem. Nie mogę znaleźć żadnych dobrych rozwiązań, ale ostatecznie użyłem flagi i GetAsyncKeyState przed 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); 

Oczywiście ten kod wykonuje tylko jeden klucz. Możesz użyć tablicy flag, aby wykonać wiele kluczy. W zależności od aplikacji możesz także bezwarunkowo ustawić flagę na false, jeśli chcesz pierwsze naciśnięcie po ustawieniu haka.

+0

Dokładnie to robię obecnie, dopóki ktoś nie napisze lepszego rozwiązania. Dzięki! –