Shift States

The wParam and lParam parameters that accompany WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, and WM_SYSKEYUP messages do not tell your program about the state of the shift keys. You can obtain the current state of any virtual key using the GetKeyState function. This function generally is used to obtain the state of shift keys (Shift, Ctrl, and Alt) and toggle keys (Caps Lock and Num Lock). For instance:

GetKeyState (VK_SHIFT) ;

returns a negative value (that is, the high bit is set) if the Shift key is down. The value returned from:

GetKeyState (VK_CAPITAL) ;

has the low bit set if the Caps Lock key is toggled on. You can also obtain the state of the mouse buttons using the virtual key codes VK_LBUTTON, VK_RBUTTON, and VK_MBUTTON. However, most Windows programs that need to monitor a combination of mouse buttons and keystrokes usually do it the other way around—by checking keystrokes when they receive a mouse message. In fact, shift-state information is included in the mouse messages (as you'll see in the next chapter).

Be careful with GetKeyState. It is not a real-time keyboard status check. Rather, it is a check of the keyboard status up to and including the current message being processed. GetKeyState does not let you retrieve keyboard information independent of normal keyboard messages. For instance, you may want to hold up processing in your window procedure until the user presses the F1 function key:

while (GetKeyState (VK_F1) >= 0) ; // WRONG !!!

This statement will execute for a very long time—until you reset your machine with Ctrl-Alt-Delete. Your program must retrieve the keyboard message from the queue before GetKeyState can retrieve the state of the key. This synchronization actually works to your advantage, because if you need to know the shift state for a particular keystroke message, GetKeyState is guaranteed to be accurate, even if you are processing the message after the shift key has been released. If you really need the current state of the key, you can use GetAsyncKeyState.