Windows processes keyboard input by sending messages to the application's window procedure. Keyboard input can be divided into keystroke messages and character messages. Keystroke messages represent the physical pressing and releasing of keys on the keyboard, whereas character messages represent the characters or symbols generated from those keystrokes. Not every keystroke produces a character. For example, keys such as Shift, Ctrl, Alt, and the function keys generate keystroke messages but do not normally produce character messages.
The keyboard hardware itself generates keystrokes (key press and key release events). Characters are generated later by Windows, after it interprets those keystrokes according to the current keyboard layout and modifier keys. Not every keystroke generates a character.
Each time a key is pressed, a message is sent to the window that currently has input focus. Input focus indicates the component of the graphical user interface that is selected to receive keyboard input. Since most applications contain more than one window, a particular window must have input focus in order to receive these messages.
The window that has input focus receives all keyboard messages until the focus changes to another window.
Keystroke Messages
When a key is pressed, Windows places either a WM_KEYDOWN or WM_SYSKEYDOWN message in the application's message queue. When the key is released, Windows places either a WM_KEYUP or WM_SYSKEYUP message in the queue.
These messages identify the key using a virtual-key code, which is stored in the wParam parameter. A virtual-key code is a device-independent integer value that identifies a particular key, regardless of the character it may produce.
The lParam parameter contains additional information about the keystroke, including the repeat count, scan code, extended-key flag, context code, previous key state, and transition state.
For a complete list of virtual-key codes and their symbolic constant names, see:
Microsoft Windows Virtual-Key Codes
The WM_SYSKEYDOWN and WM_SYSKEYUP messages are generated for system keystrokes, such as when the Alt key is pressed by itself, when another key is pressed while the Alt key is held down, or when the F10 key is pressed.
System keystroke messages are normally processed by Windows and by the application's default window procedure. Applications that need to respond to system keystrokes can process these messages explicitly, but care should be taken not to interfere with normal Windows keyboard processing.
Character Messages
Character messages are generated when Windows translates keystroke messages into character codes. The most commonly used character message is WM_CHAR. Unlike keystroke messages, which identify the key that was pressed, character messages identify the character produced by that key after Windows has taken into account the current keyboard layout and any modifier keys.
When a WM_CHAR message is received, the wParam parameter contains the character code, while the lParam parameter contains additional information such as the repeat count, scan code, extended-key flag, previous key state, and transition state.
To generate character messages, an application's message loop must call the TranslateMessage() function. This function examines keyboard messages, such as WM_KEYDOWN, and, where appropriate, posts the corresponding character messages, such as WM_CHAR, to the message queue.
Dead Keys
A dead key is a key that does not immediately produce a character. Instead, it modifies the character generated by the next key that is pressed. Dead keys are commonly used to produce accented characters, such as é, à, or ñ.
When a dead key is pressed, Windows generates a WM_DEADCHAR or WM_SYSDEADCHAR message. Applications that need to process dead-key input directly can handle these messages. However, most applications simply process the resulting WM_CHAR messages after Windows has translated the keyboard input.
Retrieving a Key State
The GetKeyState() API function retrieves the status of a specified virtual key. The returned status indicates whether the key is currently up or down and, for toggle keys, whether the key is toggled.
Information about the current state of modifier keys such as Shift and Ctrl is not always included directly in keyboard messages. The GetKeyState() function allows the developer to determine the state of a specified key before deciding on an appropriate course of action.
The syntax for this function is:
SHORT GetKeyState(int vKey);
vKey – Specifies one of the virtual-key codes.
If the function succeeds, the return value contains information about the current state of the specified key. The high-order bit is set if the key is currently down. For toggle keys, the low-order bit is set if the key is toggled.
Example
The following code segment demonstrates the WM_KEYDOWN and WM_CHAR messages by displaying the virtual-key code and the associated character on the screen. If no character is associated with the key, the second line is left blank.