I am converting an application that currently uses DirectInput to use RawInput instead. (DirectInput is a largely deprecated API.)
Unfortunately, despite RawInput being the recommended successor to DirectInput, it doesn't appear to provide keyboard data in quite the same way as DirectInput.
DirectInput uses DIK_*
constants (such as DIK_A
, DIK_RETURN
, etc...) to define specific physical keys on the keyboard. These keys are consistent across keyboard hardware but do not change depending on keyboard layout. (For example, DIK_Q
refers to whatever key is in the physical location that the Q key is at on a standard US-English QWERTY keyboard.) In my case, this is the desired behavior.
RawInput's RAWKEYBOARD
structure provides both a MakeCode
and a VKey
. I can't use VKey
because that changes depending on keyboard layout.
But the MakeCode
doesn't correspond 1:1 with the DIK_*
constants. In particular, it doesn't differentiate between left and right ctrl and alt keys, or most of the number pad keys from their other keys.
So my question is: Is it possible to use the contents of a RAWKEYBOARD
structure to figure out the equivalent DIK_*
constant? And assuming that the MakeCode
is part of figuring that out, can I rely on MakeCode
being constant across keyboard hardware, in the same way that the DIK_*
constants are?
I'm not 100% sure this is reliable across all keyboard hardware, but it appears that I can use the MakeCode
and Flags
(specifically the RI_KEY_E0
and RI_KEY_E1
flags) fields of RAWKEYBOARD
to determine the actual physical key that was pressed or released, and map this to a DIK_
constant. I used this table to determine most of the make/scan codes for individual keys, and then experimentation to figure out the scan/make codes and flags for the remaining keys.
I have tested this on four different keyboards, and all produce identical make codes / flags: 2 USB keyboards, a PS/2 keyboard, and the built-in keyboard on a Macbook running bootcamp.
I'd love to have some documented confirmation that I can rely on the make code and flags to be consistent across all keyboards, but so far this seems to be working fine.
Update: It's now ~5 years later and my software has had tens of thousands of real-world users and I have not received a single report of incorrect key mapping. At this point I'm 99.999% confident this approach works consistently across all keyboards, with the caveat that I cannot be sure things won't change in the future.