Pressing a key results in a WM_KEYDOWN or WM_SYSKEYDOWN message being placed in the thread message queue associated with the window that has the keyboard focus. Releasing a key results in a WM_KEYUP or WM_SYSKEYUP message being placed in the queue. These messages correspond to the two scan codes assigned to each key.
Key up and key down messages typically occur in pairs, but if the user holds down a key long enough to invoke the keyboard's automatic repeat feature, the system generates a number of WM_KEYDOWN or WM_SYSKEYDOWN messages in a row, then a single WM_KEYUP or WM_SYSKEYUP message when the user releases the key.
Windows makes a distinction between system keystrokes and non-system keystrokes. System keystrokes produce system keystroke messages: WM_SYSKEYDOWN and WM_SYSKEYUP. Non-system keystrokes produce non-system keystroke messages: WM_KEYDOWN and WM_KEYUP.
System keystroke messages are intended primarily for use by Windows rather than by an application. Windows uses them to provide its built-in keyboard interface to menus and to allow the user to control which window is active. System keystroke messages are generated when the user types a key in combination with the ALT key, or when the user types and no window has the keyboard focus. In this case, the messages are posted to the message queue associated with the active window.
If your window procedure needs to process a system keystroke message for some reason, be sure it passes the message to the DefWindowProc function after processing the message. Otherwise, all system operations involving the ALT key will be disabled whenever the window has the keyboard focus. That is, the user won't be able to access the window's menus or system menu, or activate a different window by pressing ALT+ESC or ALT+TAB.
Non-system keystroke messages (WM_KEYDOWN and WM_KEYUP) are for use by application windows—the DefWindowProc function does nothing with them. A window procedure can discard any non-system keystroke messages that is doesn't need.
The wParam parameter of a keystroke message contains the virtual-key code of the key that was pressed or released. A window procedure processes or ignores a keystroke message depending on the value of the virtual-key code. For a list of virtual-key codes, see Appendix A, “Virtual-Key Codes.”
A typical window procedure processes only a small subset of the keystroke messages that it receives and ignores the rest. For example, a window procedure might process only WM_KEYDOWN keystroke messages, and only those that contain virtual-key codes for the cursor movement keys, shift keys, and function keys. A typical window procedure does not process keystroke messages from character keys. Instead, it uses the TranslateMessage function to convert the message into character messages. For more information on character messages, see Section 0.1.4, “Character Messages.”
The lParam parameter of a keystroke message contains additional information about the keystroke that generated the message. This information includes the repeat count, the scan code, the extended-key flag, the context code, the previous key-state flag, and the transition-state flag. The following illustration shows the locations of these flags and values in the lParam parameter:
You can check the repeat count to determine whether a keystroke message represents more than one keystroke. The system increments the count when the keyboard generates WM_KEYDOWN or WM_SYSKEYDOWN messages faster than your application can process them. This often occurs when the user holds down a key long enough to invoke the keyboard's automatic-repeat feature. Instead of filling the system message queue with the resulting key-down messages, the system combines the messages into a single keydown message and increments the repeat count. Releasing a key cannot invoke the automatic repeat feature, so the repeat count for WM_KEYUP and WM_SYSKEYUP messages is always set to one.
The scan code is the value that the keyboard hardware generates when the user presses a key. It is a device-dependent value that identifies the physical key pressed, as opposed to the character represented by the same key. An application typically ignores scan codes. Instead, it uses the device-independent virtual-key codes to interpret keystroke messages.
The extended key flag indicates whether the keystroke message originated from one of the additional keys on the IBM Enhanced Keyboard. The extended keys consist of the ALT and CONTROL keys on right-hand side of the keyboard; the INSERT, DELETE, HOME, END, PAGE UP, PAGE DOWN and DIRECTION keys in the clusters to the left of the numeric key pad; and the divide (/) and ENTER keys in the numeric key pad. The value of this flag is device-dependent, so applications typically ignore it.
The context code indicates whether the ALT key was down when the keystroke message was generated. It is one if the ALT key was down and zero if it was up.
The previous key-state flag indicates whether the key that generated the keystroke message was previously up or down. It is one if the key was previously down and zero if the key was previously up. You can use this flag to identify keystroke messages generated by the keyboard's automatic-repeat feature. This flag is set to one for WM_KEYDOWN and WM_SYSKEYDOWN keystroke messages generated by the automatic-repeat feature. It is always set to zero for WM_KEYUP and WM_SYSKEYUP messages.
The transition-state flag indicates whether pressing a key press or releasing a key generated the keystroke message. This flag is always set to zero for WM_KEYDOWN and WM_SYSKEYDOWN messages; it is always set to one for WM_KEYUP and WM_SYSKEYUP messages.