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 uniquely identifies a physical key on the keyboard, 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:
https://learn.microsoft.com/en-us/windows/win32/inputdev/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. If no window has the keyboard input focus, these messages are sent to the active window.
The WM_SYSKEYDOWN and WM_SYSKEYUP messages are usually processed by the Windows system rather than by application programs. Because improperly handling system keystroke messages can result in unpredictable behavior, the WM_KEYDOWN and WM_KEYUP messages are generally the keyboard messages of most interest to developers.
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 physical 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 (for example, 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 up, down, or toggled.
Information about the current state of modifier keys such as Shift and Ctrl is not always included in keyboard messages. The GetKeyState() function allows the developer to determine the state of these keys before deciding on an appropriate course of action.
The syntax for this function is as follows:
SHORT GetAsyncKeyState(int vKey);
vKey – Specifies one of 256 possible virtual-key codes.
If the function succeeds, the return value indicates whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down.
Example
The following code segment demonstrates the WM_KEYDOWN AND WM_CHAR message by printing the virtual key code and the associated character to the screen. If no character is associated with the keycode, the 2nd line is left blank.