For a usb keyboard configuration tool I need to intercept all keyboard input and detect which modifier keys and normal keys are pressed simultaneously. Therefore I use a windows low level hook (WH_KEYBOARD_LL) which works fine except that I´m not able to determine if WIN-Key (VK_LWIN / VK_RWIN) is pressed (control / shift and alt is working).
I made a little commandline tool to show the problem:
#include <Windows.h>
#include <iostream>
using namespace std;
HHOOK hKeyboardHook;
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
{
if (nCode < 0 || nCode != HC_ACTION )
return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam);
KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
if(wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
{
// working
if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
cout << "CONTROL" << endl;
if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
cout << "SHIFT" << endl;
if(GetAsyncKeyState(VK_MENU) & 0x8000) // ALT
cout << "ALT" << endl;
// VK_xWIN not working at all
if((GetAsyncKeyState(VK_LWIN) & 0x8000) || (GetAsyncKeyState(VK_RWIN) & 0x8000))
cout << "WIN" << endl;
// working for ALTGR/right-handed ALT
if((GetAsyncKeyState(VK_LCONTROL) & 0x8000) || (GetAsyncKeyState(VK_RCONTROL) & 0x8000))
cout << "LRCONTROL" << endl;
// not working at all
if((GetAsyncKeyState(VK_LSHIFT) & 0x8000) || (GetAsyncKeyState(VK_RSHIFT) & 0x8000))
cout << "LRSHIFT" << endl;
if((GetAsyncKeyState(VK_LMENU) & 0x8000) || (GetAsyncKeyState(VK_RMENU) & 0x8000))
cout << "LRMENU" << endl;
}
//return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam);
return 1;
}
int main(int argc, char* argv[])
{
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 );
MSG message;
while (GetMessage(&message,NULL,0,0)) {
TranslateMessage( &message );
DispatchMessage( &message );
}
UnhookWindowsHookEx(hKeyboardHook);
return 0;
}
If I return "1" from LowLevelKeyboardProc every key press is "swallowed" (except for CTRL+ALT+DEL and WIN+L). If I call the next hook at the end of the callback function the behaviour changes (and the keys obviously aren´t swallowed any more). Then if WIN key is pressed together with another key I get the information that WIN key is pressed.
What do I have to do to intercept all keyboard input and detect a WIN-key press (using GetAsyncKeyState)? Or is there another way to get all (inkl. WIN) pressed modifier keys?
Best Answer
The documentation for
LowLevelKeyboardProc
says the following about the return value:So,
return 1
says "I've processes the information, and there is nothing else that should be done with these keys".I'm not certain how you fix the problem with detection of WIN key on it's own - I suspect the system just simply doesn't forward that has a keyboard event until the second key is pressed.