标题：虚拟键码
简介
虚拟指的是假定存在于思想中而不是现实世界中的一些事物，也只有熟练使用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 01 VK_LBUTTON 滑鼠左键 
2 02 VK_RBUTTON 滑鼠右键 
3 03 VK_CANCEL ˇ Ctrl-Break 
4 04 VK_MBUTTON 滑鼠中键 
您永远都不会从键盘讯息中获得这些滑鼠键代码。在下一章可以看到，我们能够从滑鼠讯息中获得它们。VK_CANCEL代码是一个虚拟键码，它包括同时按下两个键(Ctrl-Break)。Windows应用程式通常不使用此键。
表6-3中的键--Backspace、Tab、Enter、Escape和Spacebar－通常用於Windows程式。不过，Windows一般用字元讯息（而不是键盘讯息）来处理这些键。
表6-3 
十进位 十六进位 WINUSER.H识别字 必需？ IBM相容键盘 
8 08 VK_BACK ˇ Backspace 
9 09 VK_TAB ˇ Tab 
12 0C VK_CLEAR Num 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_PRIOR和VK_NEXT）都与键上的标志不同，而且也与卷动列中的识别字不统一。Print Screen键在平时都被Windows应用程式所忽略。Windows本身回应此键时会将视讯显示的点阵图影本存放到剪贴板中。假使有键盘提供了VK_SELECT、VK_PRINT、VK_EXECUTE和VK_HELP，大概也没几个人看过那样的键盘。
Windows也包括在主键盘上的字母和数位键的虚拟键码（数字键盘将单独处理）。
表6-5 
十进位 十六进位 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键 
93 5D VK_APPS Applications键 
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 数字键盘上的/ 
最後，虽然多数的键盘都有12个功能键，但Windows只需要10个，而位元旗标却有24个。另外，程式通常用功能键作为键盘加速键，这样，它们通常不处理表6-8所示的按键：
表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_LBUTTON1鼠标左键VK_RBUTTON2鼠标右键VK_CANCEL3CancelVK_MBUTTON4鼠标中键VK_XBUTTON15​VK_XBUTTON26​VK_BACK8BackspaceVK_TAB9TabVK_CLEAR12ClearVK_RETURN13EnterVK_SHIFT16ShiftVK_CONTROL17CtrlVK_MENU18AltVK_PAUSE19PauseVK_CAPITAL20Caps LockVK_KANA21​VK_HANGUL21​VK_JUNJA23​VK_FINAL24​VK_HANJA25​VK_KANJI25*​VK_ESCAPE27EscVK_CONVERT28​VK_NONCONVERT29​VK_ACCEPT30​VK_MODECHANGE31​VK_SPACE32SpaceVK_PRIOR33Page UpVK_NEXT34Page DownVK_END35EndVK_HOME36HomeVK_LEFT37Left ArrowVK_UP38Up ArrowVK_RIGHT39Right ArrowVK_DOWN40Down ArrowVK_SELECT41SelectVK_PRINT42PrintVK_EXECUTE43ExecuteVK_SNAPSHOT44SnapshotVK_INSERT45InsertVK_DELETE46DeleteVK_HELP47Help​480​491​502​513​524​535​546​557​568​579​65A​66B​67C​68D​69E​70F​71G​72H​73I​74J​75K​76L​77M​78N​79O​80P​81Q​82R​83S​84T​85U​86V​87W​88X​89Y​90ZVK_LWIN91​VK_RWIN92​VK_APPS93​VK_SLEEP95​VK_NUMPAD096小键盘 0VK_NUMPAD197小键盘 1VK_NUMPAD298小键盘 2VK_NUMPAD399小键盘 3VK_NUMPAD4100小键盘 4VK_NUMPAD5101小键盘 5VK_NUMPAD6102小键盘 6VK_NUMPAD7103小键盘 7VK_NUMPAD8104小键盘 8VK_NUMPAD9105小键盘 9VK_MULTIPLY106小键盘 *VK_ADD107小键盘 +VK_SEPARATOR108小键盘 EnterVK_SUBTRACT109小键盘 -VK_DECIMAL110小键盘 .VK_DIVIDE111小键盘 /VK_F1112F1VK_F2113F2VK_F3114F3VK_F4115F4VK_F5116F5VK_F6117F6VK_F7118F7VK_F8119F8VK_F9120F9VK_F10121F10VK_F11122F11VK_F12123F12VK_F13124​VK_F14125​VK_F15126​VK_F16127​VK_F17128​VK_F18129​VK_F19130​VK_F20131​VK_F21132​VK_F22133​VK_F23134​VK_F24135​VK_NUMLOCK144Num LockVK_SCROLL145ScrollVK_LSHIFT160​VK_RSHIFT161​VK_LCONTROL162​VK_RCONTROL163​VK_LMENU164​VK_RMENU165​VK_BROWSER_BACK166​VK_BROWSER_FORWARD167​VK_BROWSER_REFRESH168​VK_BROWSER_STOP169​VK_BROWSER_SEARCH170​VK_BROWSER_FAVORITES171​VK_BROWSER_HOME172​VK_VOLUME_MUTE173VolumeMuteVK_VOLUME_DOWN174VolumeDownVK_VOLUME_UP175VolumeUpVK_MEDIA_NEXT_TRACK176​VK_MEDIA_PREV_TRACK177​VK_MEDIA_STOP178​VK_MEDIA_PLAY_PAUSE179​VK_LAUNCH_MAIL180​VK_LAUNCH_MEDIA_SELECT181​VK_LAUNCH_APP1182​VK_LAUNCH_APP2183​VK_OEM_1186; :VK_OEM_PLUS187= +VK_OEM_COMMA188​VK_OEM_MINUS189- _VK_OEM_PERIOD190​VK_OEM_2191/ ?VK_OEM_3192` ~VK_OEM_4219[ {VK_OEM_5220\ |VK_OEM_6221] }VK_OEM_7222' "VK_OEM_8223​VK_OEM_102226​VK_PACKET231​VK_PROCESSKEY229​VK_ATTN246​VK_CRSEL247​VK_EXSEL248​VK_EREOF249​VK_PLAY250​VK_ZOOM251​VK_NONAME252​VK_PA1253​VK_OEM_CLEAR254
完整的虚拟键码表
VK_LBUTTON (01)
Left mouse button
VK_RBUTTON (02)
Right mouse button
VK_CANCEL (03)
Control-break processing
VK_MBUTTON (04)
Middle mouse button (three-button mouse)
VK_XBUTTON1 (05)
Windows 2000/XP: X1 mouse button
VK_XBUTTON2 (06)
Windows 2000/XP: X2 mouse button
- (07)
Undefined
VK_BACK (08)
BACKSPACE key
VK_TAB (09)
TAB key
- (0A-0B)
Reserved
VK_CLEAR (0C)
CLEAR key
VK_RETURN (0D)
ENTER key
- (0E-0F)
Undefined
VK_SHIFT (10)
SHIFT key
VK_CONTROL (11)
CTRL key
VK_MENU (12)
ALT key
VK_PAUSE (13)
PAUSE key
VK_CAPITAL (14)
CAPS LOCK key
VK_KANA (15)
Input Method Editor (IME) Kana mode
VK_HANGUEL (15)
IME Hanguel mode (maintained for compatibility; use VK_HANGUL)
VK_HANGUL (15)
IME Hangul mode
- (16)
Undefined
VK_JUNJA (17)
IME Junja mode
VK_FINAL (18)
IME final mode
VK_HANJA (19)
IME Hanja mode
VK_KANJI (19)
IME Kanji mode
- (1A)
Undefined
VK_ESCAPE (1B)
ESC key
VK_CONVERT (1C)
IME convert
VK_NONCONVERT (1D)
IME nonconvert
VK_ACCEPT (1E)
IME accept
VK_MODECHANGE (1F)
IME mode change request
VK_SPACE (20)
SPACEBAR
VK_PRIOR (21)
PAGE UP key
VK_NEXT (22)
PAGE DOWN key
VK_END (23)
END key
VK_HOME (24)
HOME key
VK_LEFT (25)
LEFT ARROW key
VK_UP (26)
UP ARROW key
VK_RIGHT (27)
RIGHT ARROW key
VK_DOWN (28)
DOWN ARROW key
VK_SELECT (29)
SELECT key
VK_PRINT (2A)
PRINT key
VK_EXECUTE (2B)
EXECUTE key
VK_SNAPSHOT (2C)
PRINT SCREEN key
VK_INSERT (2D)
INS key
VK_DELETE (2E)
DEL key
VK_HELP (2F)
HELP key
(30)
0 key
(31)
1 key
(32)
2 key
(33)
3 key
(34)
4 key
(35)
5 key
(36)
6 key
(37)
7 key
(38)
8 key
(39)
9 key
- (3A-40)
Undefined
(41)
A key
(42)
B key
(43)
C key
(44)
D key
(45)
E key
(46)
F key
(47)
G key
(48)
H key
(49)
I key
(4A)
J key
(4B)
K key
(4C)
L key
(4D)
M key
(4E)
N key
(4F)
O key
(50)
P key
(51)
Q key
(52)
R key
(53)
S key
(54)
T key
(55)
U key
(56)
V key
(57)
W key
(58)
X key
(59)
Y key
(5A)
Z key
VK_LWIN (5B)
Left Windows key (Microsoft Natural keyboard)
VK_RWIN (5C)
Right Windows key (Natural keyboard)
VK_APPS (5D)
Applications key (Natural keyboard)
- (5E)
Reserved
VK_SLEEP (5F)
Computer Sleep key
VK_NUMPAD0 (60)
Numeric keypad 0 key
VK_NUMPAD1 (61)
Numeric keypad 1 key
VK_NUMPAD2 (62)
Numeric keypad 2 key
VK_NUMPAD3 (63)
Numeric keypad 3 key
VK_NUMPAD4 (64)
Numeric keypad 4 key
VK_NUMPAD5 (65)
Numeric keypad 5 key
VK_NUMPAD6 (66)
Numeric keypad 6 key
VK_NUMPAD7 (67)
Numeric keypad 7 key
VK_NUMPAD8 (68)
Numeric keypad 8 key
VK_NUMPAD9 (69)
Numeric keypad 9 key
VK_MULTIPLY (6A)
Multiply key
VK_ADD (6B)
Add key
VK_SEPARATOR (6C)
Separator key
VK_SUBTRACT (6D)
Subtract key
VK_DECIMAL (6E)
Decimal key
VK_DIVIDE (6F)
Divide key
VK_F1 (70)
F1 key
VK_F2 (71)
F2 key
VK_F3 (72)
F3 key
VK_F4 (73)
F4 key
VK_F5 (74)
F5 key
VK_F6 (75)
F6 key
VK_F7 (76)
F7 key
VK_F8 (77)
F8 key
VK_F9 (78)
F9 key
VK_F10 (79)
F10 key
VK_F11 (7A)
F11 key
VK_F12 (7B)
F12 key
VK_F13 (7C)
F13 key
VK_F14 (7D)
F14 key
VK_F15 (7E)
F15 key
VK_F16 (7F)
F16 key
VK_F17 (80H)
F17 key
VK_F18 (81H)
F18 key
VK_F19 (82H)
F19 key
VK_F20 (83H)
F20 key
VK_F21 (84H)
F21 key
VK_F22 (85H)
F22 key
VK_F23 (86H)
F23 key
VK_F24 (87H)
F24 key
- (88-8F)
Unassigned
VK_NUMLOCK (90)
NUM LOCK key
VK_SCROLL (91)
SCROLL LOCK key
(92-96)
OEM specific
- (97-9F)
Unassigned
VK_LSHIFT (A0)
Left SHIFT key
VK_RSHIFT (A1)
Right SHIFT key
VK_LCONTROL (A2)
Left CONTROL key
VK_RCONTROL (A3)
Right CONTROL key
VK_LMENU (A4)
Left MENU key
VK_RMENU (A5)
Right MENU key
VK_BROWSER_BACK (A6)
Windows 2000/XP: Browser Back key
VK_BROWSER_FORWARD (A7)
Windows 2000/XP: Browser Forward key
VK_BROWSER_REFRESH (A8)
Windows 2000/XP: Browser Refresh key
VK_BROWSER_STOP (A9)
Windows 2000/XP: Browser Stop key
VK_BROWSER_SEARCH (AA)
Windows 2000/XP: Browser Search key
VK_BROWSER_FAVORITES (AB)
Windows 2000/XP: Browser Favorites key
VK_BROWSER_HOME (AC)
Windows 2000/XP: Browser Start and Home key
VK_VOLUME_MUTE (AD)
Windows 2000/XP: Volume Mute key
VK_VOLUME_DOWN (AE)
Windows 2000/XP: Volume Down key
VK_VOLUME_UP (AF)
Windows 2000/XP: Volume Up key
VK_MEDIA_NEXT_TRACK (B0)
Windows 2000/XP: Next Track key
VK_MEDIA_PREV_TRACK (B1)
Windows 2000/XP: Previous Track key
VK_MEDIA_STOP (B2)
Windows 2000/XP: Stop Media key
VK_MEDIA_PLAY_PAUSE (B3)
Windows 2000/XP: Play/Pause Media key
VK_LAUNCH_MAIL (B4)
Windows 2000/XP: Start Mail key
VK_LAUNCH_MEDIA_SELECT (B5)
Windows 2000/XP: Select Media key
VK_LAUNCH_APP1 (B6)
Windows 2000/XP: Start Application 1 key
VK_LAUNCH_APP2 (B7)
Windows 2000/XP: Start Application 2 key
- (B8-B9)
Reserved
VK_OEM_1 (BA)
Used for miscellaneous characters; it can vary by keyboard.
Windows 2000/XP: For the US standard keyboard, the ';:' key
VK_OEM_PLUS (BB)
Windows 2000/XP: For any country/region, the '+' key
VK_OEM_COMMA (BC)
Windows 2000/XP: For any country/region, the ',' key
VK_OEM_MINUS (BD)
Windows 2000/XP: For any country/region, the '-' key
VK_OEM_PERIOD (BE)
Windows 2000/XP: For any country/region, the '.' key
VK_OEM_2 (BF)
Used for miscellaneous characters; it can vary by keyboard.
Windows 2000/XP: For the US standard keyboard, the '/?' key
VK_OEM_3 (C0)
Used for miscellaneous characters; it can vary by keyboard.
Windows 2000/XP: For the US standard keyboard, the '`~' key
- (C1-D7)
Reserved
- (D8-DA)
Unassigned
VK_OEM_4 (DB)
Used for miscellaneous characters; it can vary by keyboard.
Windows 2000/XP: For the US standard keyboard, the '[{' key
VK_OEM_5 (DC)
Used for miscellaneous characters; it can vary by keyboard.
Windows 2000/XP: For the US standard keyboard, the '\|' key
VK_OEM_6 (DD)
Used for miscellaneous characters; it can vary by keyboard.
Windows 2000/XP: For the US standard keyboard, the ']}' key
VK_OEM_7 (DE)
Used for miscellaneous characters; it can vary by keyboard.
Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
VK_OEM_8 (DF)
Used for miscellaneous characters; it can vary by keyboard.
- (E0)
Reserved
(E1)
OEM specific
VK_OEM_102 (E2)
Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
(E3-E4)
OEM specific
VK_PROCESSKEY (E5)
Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key
(E6)
OEM specific
VK_PACKET (E7)
Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP
- (E8)
Unassigned
(E9-F5)
OEM specific
VK_ATTN (F6)
Attn key
VK_CRSEL (F7)
CrSel key
VK_EXSEL (F8)
ExSel key
VK_EREOF (F9)
Erase EOF key
VK_PLAY (FA)
Play key
VK_ZOOM (FB)
Zoom key
VK_NONAME (FC)
Reserved
VK_PA1 (FD)
PA1 key
VK_OEM_CLEAR (FE)
Clear key
键盘的扫描码、虚拟码
当用户按下某个键时，
' 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.