Original link: http://blog.sina.com.cn/s/blog_5f8817250100taab.html
Most of this article is from MSDN and netizens blog, I made some summary on the basis of practice.
1, Virtual key (vk_*)
Each key on the keyboard corresponds to a scan code, scan code is the OEM manufacturer, different manufacturers of the keyboard also a key scan code may appear inconsistent, in order to get rid of the system equipment inconsistencies in the situation, Through the keyboard driver to map the scan code to a unified virtual key code representation, so that all devices have a unified virtual key, such as the key to enter the virtual keys is Vk_return.
The virtual keys defined by Windows are defined in the WinUser.h header file and are prefixed with vk_ .
2. Activate / Deactivate window-to-keyboard messages
Activate / Deactivate message:wm_setfocus/wm_killfocus
Create cursor:createcaret (...)
Set cursor Position:setcaretpos (...)
Show cursor in window:showcaret (...)
Destroy cursor:destroycaret ()
3, keyboard message
1) character message
System character messages
Wm_syschar: System character
Wm_sysdeadchar: System dead character
Non-system Key message
WM_CHAR: Non-system characters
Wm_deadchar: Non-system dead characters
2) Key message
System Key message: key combination with ALT key (regardless of user handling no, requires last call to DefWindowProc (Hwnd,imessage,wparam,lparam))
Wm_syskeydown
Wm_syskeyup
Non-system Key message:
Wm_keydown
Wm_keyup
Attention:
A) There is a "press" message in addition to the print key.
b) There is a "bounce" message for all keys.
C) According to the MSDN instructions, only the following keys will produce a character message:
- Any character key
- Fallback key (BACKSPACE)
- Enter (carriage return)
- Esc
- Shift + ENTER (linefeed line wrap)
- TAB
How did we get the WM_CHAR? That's because we called the translatemessage on the message loop to translate the keyboard message,
If the message is Wm_keydown or WM_SYSKEYDOWN, and the key is combined with the displacement state to produce one character, TranslateMessage puts the character message into the message queue. This character message will be the next message after the key message getmessage from the message queue.
When we deal with this message, the corresponding WParam is not a virtual key, but the ANSI or Unicode character code, in general we can use : (TCHAR) WParam;
4, message order
Because the TranslateMessage function produces a character message from the Wm_keydown and Wm_syskeydown messages, the character message is sandwiched between the key messages passed to the window message handler. For example, if CAPS LOCK is not turned on and the consumer presses and releases the A key, the window message handler receives three messages as shown in table 6-10:
Table 6-10
News |
Key or code |
Wm_keydown |
Virtual key code for "a" (0x41) |
Wm_char |
"a" character code (0X61) |
Wm_keyup |
Virtual key code for "a" (0x41) |
If you press the SHIFT key, press the A key again, then release the A key, and then release the SHIFT key, you will enter an uppercase A, and the window message handler will receive five messages, as shown in table 6-11:
message |
|
wm_keydown |
virtual key Vk_shift (0x10) |
wm_keydown |
"a" virtual Key Code (0x41) |
wm_char |
" a"character code (0x41) |
wm_keyup |
Span style= "FONT-SIZE:12PX;" >"a" Virtual Key Code (0x41) |
wm_keyup |
virtual key Vk_shift (0x10) |
The SHIFT key itself does not produce a character message.
If the user holds down the a key so that a series of keystrokes are automatically repeated, a character message will be given to each WM_KEYDOWN message, as shown in table 6-12:
Table 6-12
News |
Key or code |
Wm_keydown |
Virtual key code for "a" (0x41) |
Wm_char |
"a" character code (0X61) |
Wm_keydown |
Virtual key code for "a" (0x41) |
Wm_char |
"a" character code (0X61) |
Wm_keydown |
Virtual key code for "a" (0x41) |
Wm_char |
"a" character code (0X61) |
Wm_keydown |
Virtual key code for "a" (0x41) |
Wm_char |
"a" character code (0X61) |
Wm_keyup |
Virtual key code for "a" (0x41) |
If some wm_keydown messages have a repeat count greater than 1, the corresponding WM_CHAR message will have the same repetition count.
Combining the CTRL key with the letter key produces an ASCII control code from 0X01 (ctrl-a) to 0x1a (ctrl-z), where some control codes can also be generated by the keys listed in table 6-13:
Table 6-13
Keys |
Character code |
Generation method |
ANSI C control characters |
Backspace |
0x08 |
Ctrl-h |
\b |
Tab |
0x09 |
Ctrl-i |
\ t |
Ctrl-enter |
0x0A |
Ctrl-j |
\ n |
Enter |
0x0D |
Ctrl-m |
\ r |
Esc |
0x1B |
ctrl-[ |
|
The right-most column gives the control characters defined in ANSI C, which are used to describe the character codes of these keys.
We can generally handle Wm_carh messages like this:
Case WM_CHAR:
{
Switch (WParam)
{
Case 0X08:
Process a backspace.
Break
Case 0x0A:
Process a linefeed.
Break
Case 0x1B:
Process an escape.
Break
Case 0X09:
Process a tab.
Break
Case 0x0D:
Process a carriage return.
Break
Default
Process displayable characters.
Break
}
}
We can judge in Wm_char whether there is currently a specified key being pressed:
BOOL Bisctrl = (:: Getasynckeystate (Vk_control) & 0x8000); (MFC source afxcolordialog.cpp 460 line)
Or
BOOL Bisctrl = (:: Getkeystate (Vk_control) & 0x8000);
Here I explain the lParam parameters of the keyboard message , this parameter can be found on MSDN, just in English, I do some simple explanation: (Take wm_keydown as an example)
WPARAM: Virtual key value,vt_* equivalent.
LPARAM: Different meanings can be divided into the following parts depending on their number of digits:
(1) Repeat Count Digit (0-15 bit): Represents the message key data. In general , 1, when the key has been pressed, the window process will receive a continuous w_keydown message, but it is possible that the window process is too late to process these key messages, then Windows will combine a few key messages into one, and increase the repetition count. For example, when you are dealing with wm_keydown, you can get a number that is greater than 1, which is usually thecount:
DWORD count = (((DWORD) lParam) & 0x0000ffff);
(2) OEM Scan code (16~23 bit): OEM Scan Code is the code value sent by the keyboard, because this field is device-dependent, and therefore this value is often ignored.
(3) Extension key flag (24-bit): The extension key flag is 1 when the ALT key (or CTRL key) is pressed, otherwise 0.
(4) Reserved bit (25~28 bit): Reserved bit is the system default reserved, generally do not use.
(5) Correlation code (29 bit): The correlation code is used to record a key and ALT key combination state, if you press ALT, when the WM_SYSKEYDOWN message is sent to an active window, its value is 1, otherwise 0.
(6) The previous state of the key (bit 30): The previous state of the key is used to record the state of a previous key, and for WM_SYSKEYUP messages, the value is always 1.
(7) Conversion State (31-bit): The message of the transition state is always the message generated by a key, and if a key is originally pressed, its previous state is 0. The conversion status indicates whether the key is pressed or released. When the key is pressed, corresponding to the WM_SYSKEYDOWN message, whose value is always 0, when the key is released, its conversion status is 1, corresponding to the WM_SYSKEYUP message, whose value is always 1.
5, dead character message
Windows programs often ignore Wm_deadchar and WM_SYSDEADCHAR messages, but you should know exactly what the dead characters are and how they work.
On some non-U.S. English keyboards, some keys are used to add tones to the letters. Because they do not produce characters themselves, they are called "dead Keys". For example, when using a German keyboard, the corresponding position of the German keyboard for the +/= key on the U.S. keyboard is a dead key, which is used to identify the sharp sound when the SHIFT key is not pressed, and is used to identify the suppressed sound when the SHIFT key is pressed.
When the user presses the dead key, the window message handler receives a WM_DEADCHAR message that wparam the ASCII or Unicode code that is equal to the tone itself. When a user presses a letter key that can carry this tone (for example, the A key), the window message handler receives the WM_CHAR message, where wparam equals the ANSI code "a" the letter with the tone.
Therefore, the consumer program does not need to process the WM_DEADCHAR message because the WM_CHAR message already contains all the information that the program needs. Windows's approach has even designed internal error handling. If a letter with this diacritic cannot be followed by a dead key (for example, "s"), the window message handler will receive two WM_CHAR messages on one line-the wparam of the previous message equals the ASCII code of the diacritic itself (and is passed to the WM_ The wparam value of the DEADCHAR message is the same), and the wparam of the second message equals the ASCII code of the letter S.
Of course, the best way to feel the way it works is to actually do it. You must load a foreign language keyboard that uses a dead key, such as a German keyboard that was previously spoken. You can set this up by selecting keyboard in the console, and then selecting the Language Family page label. Then you need an application that can display the details of every keyboard message it receives. The following KEYVIEW1 is such a program.
Windows keyboard Message Processing