Recently, I have encountered this problem. I cannot find any good solutions, but in the end I used the flag and GetAsyncKeyState before 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);
Of course, this code does this for only one key. You can use an array of flags to execute multiple keys. Depending on your application, you can also unconditionally set the flag false if you want the first click after your hook is set.
source share