文章目录[隐藏]
虚拟键码
虚拟键码保存在WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP讯息的wParam参数中。此代码标识按下或释放的键。
简介
虚拟指的是假定存在于思想中而不是现实世界中的一些事物,也只有熟练使用DOS组合语言编写应用程式的程式写作者才有可能指出,为什么对Windows键盘处理如此基本的键码是虚拟的而不是真实的。
对於早期的程式写作者来说,真实的键码由实际键盘硬体产生。在Windows文件中将这些键码称为「扫描码(scan codes)」。在IBM相容机种上,扫描码16是Q键,17是W键,18是E、19是R,20是T,21是Y等等。这时您会发现,扫描码是依据键盘的实际布局的。Windows开发者认为这些代码过於与设备相关了,於是他们试图通过定义所谓的虚拟键码,以便经由与装置无关的方式处理键盘。其中一些虚拟键码不能在IBM相容机种上产生,但可能会在其他制造商生产的键盘中找到,或者在未来的键盘上找到。
您使用的大多数虚拟键码的名称在WINUSER.H表头档案中都定义为以VK_开头。表6-2列出了这些名称和数值(十进位和十六进位),以及与虚拟键相对应的IBM相容机种键盘上的键。下表也标出了Windows执行时是否需要这些键。下表还按数位顺序列出了虚拟键码。
前四个虚拟键码中有三个指的是滑鼠键:
表6-2
十进位 十六进位 WINUSER.H识别字 必需? IBM相容键盘
1
|
1
|
VK_LBUTTON
|
滑鼠左键
|
2
|
2
|
VK_RBUTTON
|
滑鼠右键
|
3
|
3
|
VK_CANCEL
|
Ctrl-Break
|
4
|
4
|
VK_MBUTTON
|
滑鼠中键
|
您永远都不会从键盘讯息中获得这些滑鼠键代码。在下一章可以看到,我们能够从滑鼠讯息中获得它们。VK_CANCEL代码是一个虚拟键码,它包括同时按下两个键(Ctrl-Break)。Windows应用程式通常不使用此键。
表6-3中的键--Backspace、Tab、Enter、Escape和Spacebar-通常用於Windows程式。不过,Windows一般用字元讯息(而不是键盘讯息)来处理这些键。
表6-3
十进位 十六进位 WINUSER.H识别字 必需? IBM相容键盘
十进制
|
十六进制
|
WINUSER.H识别字
|
IBM相容键盘
|
8
|
8
|
VK_BACK
|
Backspace
|
9
|
9
|
VK_TAB
|
Tab
|
12
|
0C
|
VK_CLEAR
|
Lock关闭时的数字键盘5
|
13
|
0D
|
VK_RETURN
|
Enter
|
16
|
10
|
VK_SHIFT
|
Shift
|
17
|
11
|
VK_CONTROL
|
Ctrl
|
18
|
12
|
VK_MENU
|
Alt
|
19
|
13
|
VK_PAUSE
|
Pause
|
20
|
14
|
VK_CAPITAL
|
Caps Lock
|
27
|
1B
|
VK_ESCAPE
|
Esc
|
32
|
20
|
VK_SPACE
|
Spacebar
|
另外,Windows程式通常不需要监视Shift、Ctrl或Alt键的状态。
表6-4列出的前八个码可能是与VK_INSERT和VK_DELETE一起最常用的虚拟键码:
表6-4
十进制
|
十六进制
|
WINUSER.H识别字
|
IBM相容键盘
|
33
|
21
|
VK_PRIOR
|
Page Up
|
34
|
22
|
VK_NEXT
|
Page Down
|
35
|
23
|
VK_END
|
End
|
36
|
24
|
VK_HOME
|
Home
|
37
|
25
|
VK_LEFT
|
左箭头
|
38
|
26
|
VK_UP
|
上箭头
|
39
|
27
|
VK_RIGHT
|
右箭头
|
40
|
28
|
VK_DOWN
|
下箭头
|
41
|
29
|
VK_SELECT
|
|
42
|
2A
|
VK_PRINT
|
|
43
|
2B
|
VK_EXECUTE
|
|
44
|
2C
|
VK_SNAPSHOT
|
Print Screen
|
45
|
2D
|
VK_INSERT
|
Insert
|
46
|
2E
|
VK_DELETE
|
Delete
|
47
|
2F
|
VK_HELP
|
注意,许多名称(例如VK_PRIORWindows也包括在主键盘上的字母和数位键的虚拟键码(数字键盘将单独处理)。
十进位 十六进位 WINUSER.H识别字 必需? IBM相容键盘
十进制
|
十六进制
|
WINUSER.H识别字
|
IBM相容键盘
|
48-57
|
30-39
|
无
|
主键盘上的0到9
|
65-90
|
41-5A
|
无
|
A到Z
|
注意,数字和字母的虚拟键码是ASCII码。Windows程式几乎从不使用这些虚拟键码;实际上,程式使用的是ASCII码字元的字元讯息。
表6-6所示的代码是由Microsoft Natural Keyboard及其相容键盘产生的:
表6-6
十进制
|
十六进制
|
WINUSER.H识别字
|
IBM相容键盘
|
91
|
5B
|
VK_LWIN
|
左Windows键
|
92
|
5C
|
VK_RWIN
|
右Windows键
|
Windows用VK_LWIN和VK_RWIN键打开「开始」功能表或者(在以前的版本中)启动「工作管理员程式」。这两个都可以用於登录或登出Windows(只在Microsoft Windows NT中有效),或者登录或登出网路(在Windows for Applications中)。应用程式能够通过显示辅助资讯或者当成捷径键看待来处理application键。
表6-7所示的代码用於数字键盘上的键(如果有的话):
表6-7
十进制
|
十六进制
|
WINUSER.H识别字
|
IBM相容键盘
|
96-105
|
60-69
|
VK_NUMPAD0到VK_
|
NUMPAD9 NumLock打开时数字键盘上的0到9
|
106
|
6A
|
VK_MULTIPLY
|
数字键盘上的*
|
107
|
6B
|
VK_ADD
|
数字键盘上的+
|
108
|
6C
|
VK_SEPARATOR
|
|
109
|
6D
|
VK_SUBTRACT
|
数字键盘上的-
|
110
|
6E
|
VK_DECIMAL
|
数字键盘上的.
|
111
|
6F
|
VK_DIVIDE
|
数字键盘上的/
|
表6-8
十进制
|
十六进制
|
WINUSER.H识别字
|
IBM相容键盘
|
112-121
|
70-79
|
VK_F1到VK_F10
|
功能键F1到F10
|
122-135
|
7A-87
|
VK_F11到VK_F24
|
功能键F11到F24
|
144
|
90
|
VK_NUMLOCK
|
Num Lock
|
145
|
91
|
VK_SCROLL
|
Scroll Lock
|
另外,还定义了一些其他虚拟键码,但它们只用於非标准键盘上的键,或者通常在大型主机终端机上使用的键。查看/ Platform SDK / User Interface Services / User Input / Virtual-Key Codes,可得到完整的列表。
虚拟键表
虚拟键码
|
对应值
|
对应键
|
VK_LBUTTON
|
1
|
鼠标左键
|
VK_RBUTTON
|
2
|
鼠标右键
|
VK_CANCEL
|
3
|
Cancel
|
VK_MBUTTON
|
4
|
鼠标中键
|
VK_XBUTTON1
|
5
|
|
VK_XBUTTON2
|
6
|
|
VK_BACK
|
8
|
Backspace
|
VK_TAB
|
9
|
Tab
|
VK_CLEAR
|
12
|
Clear
|
VK_RETURN
|
13
|
Enter
|
VK_SHIFT
|
16
|
Shift
|
VK_CONTROL
|
17
|
Ctrl
|
VK_MENU
|
18
|
Alt
|
VK_PAUSE
|
19
|
Pause
|
VK_CAPITAL
|
20
|
Caps Lock
|
VK_KANA
|
21
|
|
VK_HANGUL
|
21
|
|
VK_JUNJA
|
23
|
|
VK_FINAL
|
24
|
|
VK_HANJA
|
25
|
|
VK_KANJI
|
25*
|
|
VK_ESCAPE
|
27
|
Esc
|
VK_CONVERT
|
28
|
|
VK_NONCONVERT
|
29
|
|
VK_ACCEPT
|
30
|
|
VK_MODECHANGE
|
31
|
|
VK_SPACE
|
32
|
Space
|
VK_PRIOR
|
33
|
Page Up
|
VK_NEXT
|
34
|
Page Down
|
VK_END
|
35
|
End
|
VK_HOME
|
36
|
Home
|
VK_LEFT
|
37
|
Left Arrow
|
VK_UP
|
38
|
Up Arrow
|
VK_RIGHT
|
39
|
Right Arrow
|
VK_DOWN
|
40
|
Down Arrow
|
VK_SELECT
|
41
|
Select
|
VK_PRINT
|
42
|
Print
|
VK_EXECUTE
|
43
|
Execute
|
VK_SNAPSHOT
|
44
|
Snapshot
|
VK_INSERT
|
45
|
Insert
|
VK_DELETE
|
46
|
Delete
|
VK_HELP
|
47
|
Help
|
48
|
0
|
|
49
|
1
|
|
50
|
2
|
|
51
|
3
|
|
52
|
4
|
|
53
|
5
|
|
54
|
6
|
|
55
|
7
|
|
56
|
8
|
|
57
|
9
|
|
65
|
A
|
|
66
|
B
|
|
67
|
C
|
|
68
|
D
|
|
69
|
E
|
|
70
|
F
|
|
71
|
G
|
|
72
|
H
|
|
73
|
I
|
|
74
|
J
|
|
75
|
K
|
|
76
|
L
|
|
77
|
M
|
|
78
|
N
|
|
79
|
O
|
|
80
|
P
|
|
81
|
Q
|
|
82
|
R
|
|
83
|
S
|
|
84
|
T
|
|
85
|
U
|
|
86
|
V
|
|
87
|
W
|
|
88
|
X
|
|
89
|
Y
|
|
90
|
Z
|
|
VK_LWIN
|
91
|
左WIN键 |
VK_RWIN
|
92
|
右WIN键 |
VK_APPS
|
93
|
应用程序键 |
VK_SLEEP
|
95
|
睡眠键 |
VK_NUMPAD0
|
96
|
小键盘 0
|
VK_NUMPAD1
|
97
|
小键盘 1
|
VK_NUMPAD2
|
98
|
小键盘 2
|
VK_NUMPAD3
|
99
|
小键盘 3
|
VK_NUMPAD4
|
100
|
小键盘 4
|
VK_NUMPAD5
|
101
|
小键盘 5
|
VK_NUMPAD6
|
102
|
小键盘 6
|
VK_NUMPAD7
|
103
|
小键盘 7
|
VK_NUMPAD8
|
104
|
小键盘 8
|
VK_NUMPAD9
|
105
|
小键盘 9
|
VK_MULTIPLY
|
106
|
小键盘 *
|
VK_ADD
|
107
|
小键盘 +
|
VK_SEPARATOR
|
108
|
小键盘 Enter
|
VK_SUBTRACT
|
109
|
小键盘 -
|
VK_DECIMAL
|
110
|
小键盘 .
|
VK_DIVIDE
|
111
|
小键盘 /
|
VK_F1
|
112
|
F1
|
VK_F2
|
113
|
F2
|
VK_F3
|
114
|
F3
|
VK_F4
|
115
|
F4
|
VK_F5
|
116
|
F5
|
VK_F6
|
117
|
F6
|
VK_F7
|
118
|
F7
|
VK_F8
|
119
|
F8
|
VK_F9
|
120
|
F9
|
VK_F10
|
121
|
F10
|
VK_F11
|
122
|
F11
|
VK_F12
|
123
|
F12
|
VK_F13
|
124
|
|
VK_F14
|
125
|
|
VK_F15
|
126
|
|
VK_F16
|
127
|
|
VK_F17
|
128
|
|
VK_F18
|
129
|
|
VK_F19
|
130
|
|
VK_F20
|
131
|
|
VK_F21
|
132
|
|
VK_F22
|
133
|
|
VK_F23
|
134
|
|
VK_F24
|
135
|
|
VK_NUMLOCK
|
144
|
Num Lock
|
VK_SCROLL
|
145
|
Scroll
|
VK_LSHIFT
|
160
|
左shift |
VK_RSHIFT
|
161
|
右shift |
VK_LCONTROL
|
162
|
|
VK_RCONTROL
|
163
|
|
VK_LMENU
|
164
|
|
VK_RMENU
|
165
|
|
VK_BROWSER_BACK
|
166
|
|
VK_BROWSER_FORWARD
|
167
|
|
VK_BROWSER_REFRESH
|
168
|
|
VK_BROWSER_STOP
|
169
|
|
VK_BROWSER_SEARCH
|
170
|
|
VK_BROWSER_FAVORITES
|
171
|
|
VK_BROWSER_HOME
|
172
|
|
VK_VOLUME_MUTE
|
173
|
VolumeMute
|
VK_VOLUME_DOWN
|
174
|
VolumeDown
|
VK_VOLUME_UP
|
175
|
VolumeUp
|
VK_MEDIA_NEXT_TRACK
|
176
|
|
VK_MEDIA_PREV_TRACK
|
177
|
|
VK_MEDIA_STOP
|
178
|
|
VK_MEDIA_PLAY_PAUSE
|
179
|
|
VK_LAUNCH_MAIL
|
180
|
|
VK_LAUNCH_MEDIA_SELECT
|
181
|
|
VK_LAUNCH_APP1
|
182
|
|
VK_LAUNCH_APP2
|
183
|
|
VK_OEM_1
|
186
|
; :
|
VK_OEM_PLUS
|
187
|
= +
|
VK_OEM_COMMA
|
188
|
, |
VK_OEM_MINUS
|
189
|
- _
|
VK_OEM_PERIOD
|
190
|
. |
VK_OEM_2
|
191
|
/ ?
|
VK_OEM_3
|
192
|
` ~
|
VK_OEM_4
|
219
|
[ {
|
VK_OEM_5
|
220
|
\ |
|
VK_OEM_6
|
221
|
] }
|
VK_OEM_7
|
222
|
' "
|
VK_OEM_8
|
223
|
|
VK_OEM_102
|
226
|
|
VK_PACKET
|
231
|
|
VK_PROCESSKEY
|
229
|
|
VK_ATTN
|
246
|
|
VK_CRSEL
|
247
|
|
VK_EXSEL
|
248
|
|
VK_EREOF
|
249
|
|
VK_PLAY
|
250
|
|
VK_ZOOM
|
251
|
|
VK_NONAME
|
252
|
|
VK_PA1
|
253
|
|
VK_OEM_CLEAR
|
254
|
完整的虚拟键码
* *VirtualKeys,StandardSet */ #defineVK_LBUTTON0x01 #defineVK_RBUTTON0x02 #defineVK_CANCEL0x03 #defineVK_MBUTTON0x04/*NOTcontiguouswithL&RBUTTON*/ #if(_WIN32_WINNT>=0x0500) #defineVK_XBUTTON10x05/*NOTcontiguouswithL&RBUTTON*/ #defineVK_XBUTTON20x06/*NOTcontiguouswithL&RBUTTON*/ #endif/*_WIN32_WINNT>=0x0500*/ /* *0x07:unassigned */ #defineVK_BACK0x08 #defineVK_TAB0x09 /* *0x0A-0x0B:reserved */ #defineVK_CLEAR0x0C #defineVK_RETURN0x0D #defineVK_SHIFT0x10 #defineVK_CONTROL0x11 #defineVK_MENU0x12 #defineVK_PAUSE0x13 #defineVK_CAPITAL0x14 #defineVK_KANA0x15 #defineVK_HANGEUL0x15/*oldname-shouldbehereforcompatibility*/ #defineVK_HANGUL0x15 #defineVK_JUNJA0x17 #defineVK_FINAL0x18 #defineVK_HANJA0x19 #defineVK_KANJI0x19 #defineVK_ESCAPE0x1B #defineVK_CONVERT0x1C #defineVK_NONCONVERT0x1D #defineVK_ACCEPT0x1E #defineVK_MODECHANGE0x1F #defineVK_SPACE0x20 #defineVK_PRIOR0x21 #defineVK_NEXT0x22 #defineVK_END0x23 #defineVK_HOME0x24 #defineVK_LEFT0x25 #defineVK_UP0x26 #defineVK_RIGHT0x27 #defineVK_DOWN0x28 #defineVK_SELECT0x29 #defineVK_PRINT0x2A #defineVK_EXECUTE0x2B #defineVK_SNAPSHOT0x2C #defineVK_INSERT0x2D #defineVK_DELETE0x2E #defineVK_HELP0x2F /* *VK_0-VK_9arethesameasASCII'0'-'9'(0x30-0x39) *0x40:unassigned *VK_A-VK_ZarethesameasASCII'A'-'Z'(0x41-0x5A) */ #defineVK_LWIN0x5B #defineVK_RWIN0x5C #defineVK_APPS0x5D /* *0x5E:reserved */ #defineVK_SLEEP0x5F #defineVK_NUMPAD00x60 #defineVK_NUMPAD10x61 #defineVK_NUMPAD20x62 #defineVK_NUMPAD30x63 #defineVK_NUMPAD40x64 #defineVK_NUMPAD50x65 #defineVK_NUMPAD60x66 #defineVK_NUMPAD70x67 #defineVK_NUMPAD80x68 #defineVK_NUMPAD90x69 #defineVK_MULTIPLY0x6A #defineVK_ADD0x6B #defineVK_SEPARATOR0x6C #defineVK_SUBTRACT0x6D #defineVK_DECIMAL0x6E #defineVK_DIVIDE0x6F #defineVK_F10x70 #defineVK_F20x71 #defineVK_F30x72 #defineVK_F40x73 #defineVK_F50x74 #defineVK_F60x75 #defineVK_F70x76 #defineVK_F80x77 #defineVK_F90x78 #defineVK_F100x79 #defineVK_F110x7A #defineVK_F120x7B #defineVK_F130x7C #defineVK_F140x7D #defineVK_F150x7E #defineVK_F160x7F #defineVK_F170x80 #defineVK_F180x81 #defineVK_F190x82 #defineVK_F200x83 #defineVK_F210x84 #defineVK_F220x85 #defineVK_F230x86 #defineVK_F240x87 /* *0x88-0x8F:unassigned */ #defineVK_NUMLOCK0x90 #defineVK_SCROLL0x91 /* *NECPC-9800kbddefinitions */ #defineVK_OEM_NEC_EQUAL0x92//'='keyonnumpad /* *Fujitsu/OASYSkbddefinitions */ #defineVK_OEM_FJ_JISHO0x92//'Dictionary'key #defineVK_OEM_FJ_MASSHOU0x93//'Unregisterword'key #defineVK_OEM_FJ_TOUROKU0x94//'Registerword'key #defineVK_OEM_FJ_LOYA0x95//'LeftOYAYUBI'key #defineVK_OEM_FJ_ROYA0x96//'RightOYAYUBI'key /* *0x97-0x9F:unassigned */ /* *VK_L*&VK_R*-leftandrightAlt,CtrlandShiftvirtualkeys. *UsedonlyasparameterstoGetAsyncKeyState()andGetKeyState(). *NootherAPIormessagewilldistinguishleftandrightkeysinthisway. */ #defineVK_LSHIFT0xA0 #defineVK_RSHIFT0xA1 #defineVK_LCONTROL0xA2 #defineVK_RCONTROL0xA3 #defineVK_LMENU0xA4 #defineVK_RMENU0xA5 #if(_WIN32_WINNT>=0x0500) #defineVK_BROWSER_BACK0xA6 #defineVK_BROWSER_FORWARD0xA7 #defineVK_BROWSER_REFRESH0xA8 #defineVK_BROWSER_STOP0xA9 #defineVK_BROWSER_SEARCH0xAA #defineVK_BROWSER_FAVORITES0xAB #defineVK_BROWSER_HOME0xAC #defineVK_VOLUME_MUTE0xAD #defineVK_VOLUME_DOWN0xAE #defineVK_VOLUME_UP0xAF #defineVK_MEDIA_NEXT_TRACK0xB0 #defineVK_MEDIA_PREV_TRACK0xB1 #defineVK_MEDIA_STOP0xB2 #defineVK_MEDIA_PLAY_PAUSE0xB3 #defineVK_LAUNCH_MAIL0xB4 #defineVK_LAUNCH_MEDIA_SELECT0xB5 #defineVK_LAUNCH_APP10xB6 #defineVK_LAUNCH_APP20xB7 #endif/*_WIN32_WINNT>=0x0500*/ /* *0xB8-0xB9:reserved */ #defineVK_OEM_10xBA//';:'forUS #defineVK_OEM_PLUS0xBB//'+'anycountry #defineVK_OEM_COMMA0xBC//','anycountry #defineVK_OEM_MINUS0xBD//'-'anycountry #defineVK_OEM_PERIOD0xBE//'.'anycountry #defineVK_OEM_20xBF//'/?'forUS #defineVK_OEM_30xC0//'`~'forUS /* *0xC1-0xD7:reserved */ /* *0xD8-0xDA:unassigned */ #defineVK_OEM_40xDB//'[{'forUS #defineVK_OEM_50xDC//'\|'forUS #defineVK_OEM_60xDD//']}'forUS #defineVK_OEM_70xDE//''"'forUS #defineVK_OEM_80xDF /* *0xE0:reserved */ /* *Variousextendedorenhancedkeyboards */ #defineVK_OEM_AX0xE1//'AX'keyonJapaneseAXkbd #defineVK_OEM_1020xE2//"<>"or"\|"onRT102-keykbd. #defineVK_ICO_HELP0xE3//HelpkeyonICO #defineVK_ICO_000xE4//00keyonICO #if(WINVER>=0x0400) #defineVK_PROCESSKEY0xE5 #endif/*WINVER>=0x0400*/ #defineVK_ICO_CLEAR0xE6 #if(_WIN32_WINNT>=0x0500) #defineVK_PACKET0xE7 #endif/*_WIN32_WINNT>=0x0500*/ /* *0xE8:unassigned */ /* *Nokia/Ericssondefinitions */ #defineVK_OEM_RESET0xE9 #defineVK_OEM_JUMP0xEA #defineVK_OEM_PA10xEB #defineVK_OEM_PA20xEC #defineVK_OEM_PA30xED #defineVK_OEM_WSCTRL0xEE #defineVK_OEM_CUSEL0xEF #defineVK_OEM_ATTN0xF0 #defineVK_OEM_FINISH0xF1 #defineVK_OEM_COPY0xF2 #defineVK_OEM_AUTO0xF3 #defineVK_OEM_ENLW0xF4 #defineVK_OEM_BACKTAB0xF5 #defineVK_ATTN0xF6 #defineVK_CRSEL0xF7 #defineVK_EXSEL0xF8 #defineVK_EREOF0xF9 #defineVK_PLAY0xFA #defineVK_ZOOM0xFB #defineVK_NONAME0xFC #defineVK_PA10xFD #defineVK_OEM_CLEAR0xFE /* *0xFF:reserved */
键盘的扫描码、虚拟码:
当用户按下某个键时,
1.键盘会检测到这个动作,并通过键盘控制器把扫描码(scan code)传送到计算机;
键盘扫描码跟具体的硬件有关的,不同厂商对同一个键的扫描码有可能不同。
2.计算机接收到扫描码后,将其交给键盘驱动程序;
3.键盘驱动程序把这个扫描码转换为键盘虚拟码;
虚拟码与具体硬件无关,不同厂商的键盘,同一个键的虚拟码总是相同的。
3.然后,键盘驱动程序把该键盘操作的扫描码和虚拟码以及其它信息传递给操作系统;
4.操作系统将获得的信息封装在一个键盘消息中,并把该键盘消息插入到消息列队。
5.通过Windows的消息系统,该键盘消息被送到某个窗口中;
6.窗口所在的应用程序接收到消息后,可以了解到有关键盘操作的信息,然后决定作出一定的响应
键盘消息:WM_KEYDOWN
nVirtKey = (int) wParam; // 虚拟码
lKeyData = lParam; // 键盘操作的相关信息
键盘消息WM_KEYDOWN的第二个参数lParam比较复杂
其作用是指定重复次数、扫描码、扩展键标记、上下文环境码、前键状态标记、转换状态标记等
lParam: 总长4字节,32位
0–15位:用于指定当前消息的重复次数。当用户按下某个键持续一段时间的话,
该值是自动计数的按下某键的次数;若按键时间很长,则会发出多个消息,
且重复次数不会累计
16–23:指定扫描码
24:指定是否该键是一个扩展键(如alt、ctrl),若值为1表示是扩展键,否则其值为0
25–28:保留
29:指定上下文环境码。对于WM_KEYDOWN、WM_KEYUP消息,其值总为0,
对WM_CHAR消息,如果同时alt键被按下,则值为1,否则值为0.
30:指定前键状态。如果消息发送前该键是按下状态,其值为1,否则为0
31:指定转换状态,对于WM_KEYDOWN,其值总为0;
对于WM_CHAR,如果该键被释放,则其值为1,否则为0.