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 keypress and characters represent the display symbol or glyphs generated as a result of the keypress. Not every keystroke will generate a character.
Each time a key is pressed a message is sent to the window with input focus. Input focus indicates the component of the graphical user interface that is selected to receive input. Since most applications will have more than one window, a particular window must have input focus to receive these messages. The window that has the keyboard focus receives all keyboard messages until the focus changes to a different window.
Keystroke Messages
When a key is pressed, a WM_KEYDOWN or WM_SYSKEYDOWN message is placed in the message queue by Windows, and when that 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. The virtual key code is a device-independent integer code 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 other useful information about the keystroke including repeat count and key transition states i.e. if the key is being pressed or released. For a full list of virtual key codes keyboards and symbolic constant names https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
The WM_SYSKEYDOWN and WM_SYSKEYUP message is generated when the user presses the F10 key (menu bar) or holds down the ALT key and then presses another key. It also occurs when no window currently has the keyboard input focus with the message sent to the active window.
The WM_SYSKEYDOWN and WM_SYSKEYUP messages are usually processed by the Windows system and not by Windows applications. Since improperly handling system keystroke messages can result in unpredictable behaviour the WM_KEYDOWN and WM_KEYUP are the mouse messages of most interest to the developer.
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 status specifies whether the key is up, down, or toggled. Since information about the current states of keys such as Shift and Ctrl keys is not included in keyboard messages, the GetKeyState() API function allows the developer to determine these key states before deciding on a course of action. The syntax for this function is –
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.