Search code examples
c++winapiinputwindow

WM_INPUT is defective


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;
}

Solution

  • 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.