I want to catch the key presses send to my window in order to store each key's state, and distinguish between the left and right instances of the key, like WM_LCONTROL
and WM_RCONTROL
.
As WM_KEYUP/DOWN
doesn't offer this functionality so i moved to raw input and i need to process WM_INPUT
.
The problem is that the flags from the RAWKEYBOARD
structure, described here, don't work as they should.
When i press right control key, RI_KEY_E0
is set which is for the left version of the
key, and when i press left control, neither RI_KEY_E0
nor RI_KEY_E1
are set.
The alt key performs similarly, but i can workaround this problem, since left still provides different flags form the right key.
But for the left and right shift keys there aren't any flags set to distinguish the left version from the right version, so i can't do anything about them.
The virtual key code given when WM_INPUT
arrives doesn't distinguish between left and right keys, and using MapVirtualKey
on the scan code doesn't work either.
What's up with this unorthodox behavior of raw inputs?
Some code:
Registering:
RAWINPUTDEVICE rid;
rid.usUsagePage=0x01;
rid.usUsage=0x06;
rid.dwFlags=0; // I also tried RIDEV_APPKEYS,RIDEV_NOHOTKEYS,RIDEV_NOLEGACY, none fixed the problem
rid.hwndTarget=hwnd;
if(!RegisterRawInputDevices(&rid,1,sizeof(RAWINPUTDEVICE)))
ExitError("Failed to register raw input device",true); //displays error and exits
Processing WM_INPUT:
case WM_INPUT:
{
RAWINPUT rw;
UINT sz=sizeof(rw);
u_char vk; //used to make code shorter
USHORT flag; //used to make code shorter
if(!GetRawInputData((HRAWINPUT)lparam,RID_INPUT,&rw,&sz,sizeof(RAWINPUTHEADER)))
break;
vk=rw.data.keyboard.VKey;
flag=rw.data.keyboard.Flags;
...Process flags and save the actual key pressed in vk...
keys[vk]=!(flag&RI_KEY_BREAK); //save key's state
break;
}
WM_KEYDOWN/-UP
does deliver the info you want ,you just have to read the decription in MSDN.
check bit 24 of the lParam parameter.