Skip to content

Improper GetAsyncKeyState usage #114

@p120ph37

Description

@p120ph37

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugAn error or incorrect implementation

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions