The system sends keyboard input events as WM_CHAR messages to the message queue of the keyboard-focus window. If no window has the keyboard focus, the system posts WM_CHAR messages to the message queue of the active frame window. Following are two typical situations in which an application receives WM_CHAR messages:
An application has a client window or custom control window, either of which can have the keyboard focus. If the window procedure for the client or control window does not process WM_CHAR messages, it should pass them to WinDefWindowProc, which will pass them to the owner. Dialog control windows, in particular, should pass unprocessed WM_CHAR messages to the WinDefDlgProc function, because this is how the user interface implements control processing for the Tab and Arrow keys.
An application window owns a control window whose window procedure can handle some, but not all, WM_CHAR messages. This is common in dialog windows. If the window procedure of a control in a dialog window cannot process a WM_CHAR message, the procedure can pass the message to the WinDefDlgProc function. This function sends the message to the control window's owner, which usually is a dialog frame window. The application's dialog procedure then receives the WM_CHAR message. This also is the case when an application client window owns a control window.
A WM_CHAR message can represent a key-down or key-up transition. It might contain a character code, virtual-key code, or scan code. This message also contains information about the state of the Shift, Ctrl, and Alt keys.
Each time a user presses a key, at least two WM_CHAR messages are generated: one when the key is pressed, and one when the key is released. If the user holds down the key long enough to trigger the keyboard repeat, multiple WM_CHAR key-down messages are generated. If the keyboard repeats faster than the application can retrieve the input events from its message queue, the system combines repeating character events into one WM_CHAR message and increments a count byte that indicates the number of keystrokes represented by the message. Generally, this byte is set to 1, but an application should check each WM_CHAR message to avoid missing any keystrokes.
An application can ignore the repeat count. For example, an application might ignore the repeat count on Arrow keys to prevent the cursor from skipping characters when the system is slow.