複製鏈接
請複製以下鏈接發送給好友

虛擬鍵碼

鎖定
虛擬鍵碼保存在WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP訊息的wParam參數中。此代碼標識按下或釋放的鍵。
中文名
虛擬鍵碼
保存在
WM_KEYDOWN等
程    序
Windows程序
代碼標識
按下或釋放的鍵

虛擬鍵碼簡介

虛擬指的是假定存在於思想中而不是現實世界中的一些事物,也只有熟練使用DOS組合語言編寫應用程式的程式寫作者才有可能指出,為什麼對Windows鍵盤處理如此基本的鍵碼是虛擬的而不是真實的。
對於早期的程式寫作者來説,真實的鍵碼由實際鍵盤硬體產生。在Windows文件中將這些鍵碼稱為“掃描碼(scan codes)”。在IBM相容機種上,掃描碼16是Q鍵,17是W鍵,18是E、19是R,20是T,21是Y等等。這時您會發現,掃描碼是依據鍵盤的實際佈局的。Windows開發者認為這些代碼過於與設備相關了,於是他們試圖通過定義所謂的虛擬鍵碼,以便經由與裝置無關的方式處理鍵盤。其中一些虛擬鍵碼不能在IBM相容機種上產生,但可能會在其他製造商生產的鍵盤中找到,或者在未來的鍵盤上找到。
您使用的大多數虛擬鍵碼的名稱在WINUSER.H頭文件中都定義為以VK_開頭。表1列出了這些名稱和數值(十進位和十六進位),以及與虛擬鍵相對應的IBM相容機種鍵盤上的鍵。下表也標出了Windows執行時是否需要這些鍵。下表還按數位順序列出了虛擬鍵碼。
前四個虛擬鍵碼中有三個指的是鼠標鍵:
表1
十進制
十六進制
winuser.h識別字
IBM相容鍵盤對應鍵
1
0x01
VK_LBUTTON
鼠標左鍵
2
0x02
VK_RBUTTON
鼠標右鍵
3
0x03
VK_CANCEL
Ctrl-Break
4
0x04
VK_MBUTTON
鼠標中鍵
您永遠都不會從鍵盤訊息中獲得這些鼠標鍵代碼。VK_CANCEL代碼是一個虛擬鍵碼,它包括同時按下兩個鍵(Ctrl-Break)。Windows應用程序通常不使用此鍵。
表2中的鍵——Backspace、Tab、Enter、Esc和空格——通常用於Windows程序。不過,Windows一般用字元訊息(而不是鍵盤訊息)來處理這些鍵。
表2
十進制
十六進制
winuser.h識別字
IBM相容鍵盤對應鍵
8
0x08
VK_BACK
Backspace
9
0x09
VK_TAB
Tab
12
0x0C
VK_CLEAR
NumLock關閉時的數字鍵盤5
13
0x0D
VK_RETURN
Enter
16
0x10
VK_SHIFT
Shift
17
0x11
VK_CONTROL
Ctrl
18
0x12
VK_MENU
Alt
19
0x13
VK_PAUSE
Pause
20
0x14
VK_CAPITAL
Caps Lock
27
0x1B
VK_ESCAPE
Esc
32
0x20
VK_SPACE
空格
另外,Windows程序通常不需要監視Shift、Ctrl或Alt鍵的狀態。
表3列出的前八個碼可能是與VK_INSERT和VK_DELETE一起最常用的虛擬鍵碼:
表3
十進制
十六進制
winuser.h識別字
IBM相容鍵盤對應鍵
33
0x21
VK_PRIOR
Page Up
34
0x22
VK_NEXT
Page Down
35
0x23
VK_END
End
36
0x24
VK_HOME
Home
37
0x25
VK_LEFT
左箭頭
38
0x26
VK_UP
上箭頭
39
0x27
VK_RIGHT
右箭頭
40
0x28
VK_DOWN
下箭頭
41
0x29
VK_SELECT
-
42
0x2A
VK_PRINT
43
0x2B
VK_EXECUTE
44
0x2C
VK_SNAPSHOT
Print Screen
45
0x2D
VK_INSERT
Insert
46
0x2E
VK_DELETE
Delete
47
0x2F
VK_HELP
-
注意,許多名稱(例如VK_PRIOR)Windows也包括在主鍵盤上的字母和數位鍵的虛擬鍵碼(數字鍵盤將單獨處理)。
表4
十進制
十六進制
WINUSER.H識別字
IBM相容鍵盤
48-57
30-39
主鍵盤上的0到9
65-90
41-5A
A到Z
注意,數字和字母的虛擬鍵碼是ASCII碼。Windows程序幾乎從不使用這些虛擬鍵碼;實際上,程序使用的是ASCII碼字元的字元訊息
表5所示的代碼是由Microsoft Natural Keyboard及其相容鍵盤產生的:
表5
十進制
十六進制
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所示的代碼用於小鍵盤上的鍵(如果有的話):
表6
十進制
十六進制
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
數字鍵盤上的/
最後,雖然多數的鍵盤都有12個功能鍵,但Windows只需要10個,而位元旗標卻有24個。另外,程式通常用功能鍵作為鍵盤加速鍵,這樣,它們通常不處理表7所示的按鍵:
表7
十進制
十六進制
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.