Windows receives keyboard input in the form of messages. A physical key press can generate both a keystroke message and a character. Keystrokes represent the physical key press, while characters represent the display symbols or glyphs generated as a result of that key press. 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, a WM_KEYDOWN or WM_SYSKEYDOWN message is placed in the message queue by Windows. When the key is released, Windows places either a WM_KEYUP or WM_SYSKEYUP message in the message queue.
These keystroke messages indicate the pressed key using a virtual-key code. A virtual-key code is a device-independent integer value that uniquely identifies a key on the keyboard. This virtual-key code is stored in the wParam parameter of the message.
The lParam parameter contains additional information about the keystroke, including the repeat count and key transition state (for example, whether the key is being pressed or released).
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 when the user presses the F10 key (which activates the menu bar) or holds down the ALT key while pressing another key. These messages can also occur when no window currently has keyboard input focus, in which case the message is 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 the result of translating keystroke messages into character codes. The most commonly used character message is WM_CHAR. When the WM_CHAR message is sent, the wparam parameter contains the character code of the key pressed and the lparam parameter contains other information such as the repeat count, extended key flag, and transition state. An application must include the TranslateMessage function in its message loop to retrieve character codes.
Dead Keys
A dead key is a modifier key that does not generate a character but modifies the character generated by the key pressed immediately after it. Dead keys are typically used to attach a specific diacritic to a base letter.
An application will need a WM_DEADCHAR or WM_SYSDEADCHAR message map handler to process dead-key messages.
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.