Holy cow, I wrote a book!
I've seen some confusion over the difference between
the GetKeyState function
the GetAsyncKeyState function.
GetKeyState returns the virtual key state.
In other words,
GetKeyState reports the state of the keyboard
based on the messages you have retrieved from your input queue.
This is not the same as the physical keyboard state:
If the user has typed ahead,
GetKeyState doesn't report those changes
until you use
the PeekMessage function
the GetMessage function
to retrieve the message from your input queue.
If the user has switched to another program,
the GetKeyState function will not see the input
that the user typed into that other program, since that input
was not sent to your input queue.
When should you use GetKeyState and when should
you use GetAsyncKeyState?
For user interface work, you nearly always want
If you are responding to an input message and want to know what
keys were pressed at the time that input was generated, then
you want to use GetKeyState.
For example, if you want to distinguish a left-click of the mouse
from an Alt+LeftClick, you must use
GetKeyState to query the state of the Alt key
(known as VK_MENU for historical reasons).
That's because you want to know whether the Alt key was down
when the user clicked the mouse, not whether the key is
down this very instant.
Whether the user released the Alt key between the time
they clicked and the time you processed the message is
irrelevant. You care that the Alt key was down at the time
of the click.
Note that if you are implementing a context menu handler,
then you shouldn't be using either GetKeyState
because the context menu can be invoked programmatically
without any user action.
you should test for the CMF_EXTENDEDVERBS flag
to detect whether you should display extended commands
rather than querying the keyboard directly.
you should be testing the
if you want to alter your behavior based on the shift states.
Given this primer on the difference between
you can now
explain the behavior this user is seeing.
[Updated: 1 Dec 2004, minor typo.]