簡介
虛擬指的是假定存在於思想中而不是現實世界中的一些事物,也只有熟練使用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 | 數字鍵盤上的/ |
最後,雖然多數的鍵盤都有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_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 | |
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 |
完整的虛擬鍵碼錶
鍵盤的掃描碼、虛擬碼:
當用戶按下某個鍵時,
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.