Contrary to superficial appearances, GetKeyState
and GetAsyncKeyState
actually have significantly different behavior, aside from skipping the input buffer queue.
GetKeyState
: docs
If the high-order bit is 1, the key is down; otherwise, it is up.
If the low-order bit is 1, the key is toggled.
- Allows detection of lock-key toggle state (e.g. "is CapsLock on?")
- Allows detection of currently-pressed state (e.g. "is CapsLock being pressed?")
GetAsyncKeyState
: docs
If the most significant bit is set, the key is down
If the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior
- Does not detect toggle state (try it! Note, this is different from the way Robot works on OSX)
- Allows detection of "recent" keypresses (almost useless since this can get reset by other processes, and is different from the way Robot works on OSX)
- Allows detection of currently-pressed state (e.g. "is CapsLock being pressed?")
I think Robot should probably be using GetKeyState
rather than GetAsyncKeyState
. The reasoning for using GetAsyncKeyState
is that it allows you to check the current realtime keyboard state regardless of queued input to your process, however it is your process so you could just as well drain your input before calling GetKeyState
to get the same result, with the added benefit that you can obtain lock-key toggle information, and can also obtain input-buffer key information if you want.
One still-missing feature would be the ability to distinguish between CapsLock-on-and-down, CapsLock-on-and-up, and CapsLock-off-and-down. Unfortunately, sorting this out would probably require a new method signature other than bool Keyboard::GetState (Key keycode)
, and it's fairly rare to need to know if CapsLock (or ScrollLock or NumLock) is actually being pressed at the moment.
Bug