Windows key repeat settings affecting Raw Input me

2019-08-13 13:18发布

问题:

It's supposed to be RAW input direct from the device, this is strange that it's affected by these settings:

It won't get a WM_INPUT message until after the delay. Also the repeat rate is affecting it. I've tried also registering the raw input device with NO_LEGACY flag, no difference. This is with a DirectX11 application I'm having this problem.

case WM_INPUT: {Input::handleInput(uMsg, wParam, lParam); break; }

回答1:

There is no way to get around it apparently, a gamedev tutorial explained that you just have to handle it in your code with your own convoluted workarounds. Raw Input my a$se Microsoft.

What happens is when you press and hold a key WM_INPUT will send one key down message, wait until the Windows "key repeat delay" has elapsed, and then continue sending key messages at the Windows "key repeat speed" setting.

I found that instead of using the Makecode or Vkey member, it's just easier to use the keyboard.flags member, because (for most keys) when a key is down this flag will be zero, and when it's up the flag will be set to 1, so you can just invert it by:

 switch (mpRawInput->data.keyboard.VKey)
        {
        case VK_W: Input::mIsKeyDown[VK_W] = !mpRawInput->data.keyboard.Flags;  break;
        case VK_A: Input::mIsKeyDown[VK_A] = !mpRawInput->data.keyboard.Flags; break;
        case VK_S: Input::mIsKeyDown[VK_S] = !mpRawInput->data.keyboard.Flags; break;
        case VK_D: Input::mIsKeyDown[VK_D] = !mpRawInput->data.keyboard.Flags; break;
        case VK_SPACE: Input::mIsKeyDown[VK_SPACE] = !mpRawInput->data.keyboard.Flags;
        }      

Using the keyboard.flag 0 or 1 value means when you press a key you get a flag message of 0, so you send the opposite of that to "isKeyDown" bool. When that key is lifted the flag will be set to 1.

For other keys keys you need workarounds, for example the arrow keys have a flag value of 3 when the num lock is on, and normal when it's off. Other keys behave entirely different like "Print Screen" and "Pause/Break". What a total mess.