Keystroke messages provide a lot of information about keystrokes, but they don't provide character codes for character keystrokes. To obtain character codes, you must include the TranslateMessage function in the thread message loop. TranslateMessage passes a WM_KEYDOWN or WM_SYSKEYDOWN message to the keyboard device driver. The driver examines the message's virtual-key code and, if it corresponds to a character key, provides the character code equivalent (taking into account the state of the SHIFT and CAPS LOCK keys). It then generates a character message that includes the character code and places the message at the top of the message queue. The next iteration of the message loop removes the character message from the queue and dispatches the message to the appropriate window procedure.
A window procedure can receive four different character messages, including WM_CHAR, WM_DEADCHAR , WM_SYSCHAR, and WM_SYSDEADCHAR. The TranslateMessage function generates a WM_CHAR or WM_DEADCHAR message when it processes a WM_KEYDOWN message. It generates a WM_SYSCHAR or WM_SYSDEADCHAR message when it processes a WM_SYSKEYDOWN message.
An application that processes keyboard input typically ignores all but the WM_CHAR message, passing the others to the DefWindowProc function. Windows uses the WM_SYSCHAR and WM_SYSDEADCHAR messages to implement menu mnemonics.
The wParam parameter of all character messages contain the character code of the character key that was pressed. The value of the character code depends on window class of the window receiving the message. If the UNICODE switch is defined when the application registers the window class, the system provides Unicode characters to all windows belonging to the class. Otherwise,the system provides ASCII character codes from the Windows ANSI character set. For more information about Unicode, see Chapter 93, “Unicode.”
The contents of the lParam parameter of a character message are identical to the contents of the lParam parameter of the key-down message that was translated to produce the character message. For information on the contents of the lParam parameter, see Section 0.1.3.3, “Keystroke Message Flags.”
Some non-English keyboards contain character keys that are not expected to produce characters by themselves. Instead, they are used to add a diacritic to the character produced by the subsequent keystroke. These keys are called dead keys. The umlaut key on a German keyboard is an example of a dead key. To enter the character consisting of an o with an umlaut, a German user would type the umlaut key followed by the o key. The window with the keyboard focus would receive the following sequence of messages:
WM_KEYDOWN
WM_DEADCHAR
WM_KEYUP
WM_KEYDOWN
WM_CHAR
WM_KEYUP
The TranslateMessage function generates the WM_DEADCHAR message when it processes the WM_KEYDOWN message from a dead key. Although the wParam parameter of the WM_DEADCHAR message contains the character code of the diacritic for the dead key, an application typically ignores the message. Instead, it processes the WM_CHAR message generated by the subsequent keystroke. The wParam parameter of the WM_CHAR message contains the character code of the letter with the diacritic. If the subsequent keystroke generates a character that cannot be combined with a diacritic, Windows generates two WM_CHAR messages. The wParam parameter of the first contains the character code of the diacritic; the wParam parameter of the second contains the character code of the subsequent character key.
The TranslateMessage function generates the WM_SYSDEADCHAR message when it processes the WM_SYSKEYDOWN message from a system dead key (a dead key that is pressed while holding down the ALT key. An application typically ignores the WM_SYSDEADCHAR message.