鍵盤輸入概觀
應用程式應該接受鍵盤和滑鼠的用戶輸入。 應用程式會以張貼至視窗的訊息形式接收鍵盤輸入。
鍵盤輸入模型
系統藉由安裝適用於目前鍵盤的鍵盤設備驅動器,為應用程式提供與裝置無關的鍵盤支援。 系統會使用使用者或應用程式目前選取的語言特定鍵盤配置,提供與語言無關的鍵盤支援。 鍵盤設備驅動器會從鍵盤接收掃描代碼,這些代碼會傳送至鍵盤配置,這些鍵盤配置會轉譯成訊息,並張貼到應用程式中的適當視窗。
指派給鍵盤上每個按鍵是稱為掃描碼的唯一值,這是鍵盤上按鍵的裝置相依標識符。 當使用者輸入按鍵時,鍵盤會產生兩個掃描碼,一個當使用者按下按鍵,另一個當使用者放開按鍵時。
鍵盤設備驅動器會解譯掃描代碼,並將它轉譯為 虛擬按鍵程式代碼,這是系統所定義的裝置獨立值,可識別按鍵的目的。 翻譯掃描程式代碼之後,鍵盤配置會建立包含掃描程式代碼、虛擬按鍵程式代碼,以及按鍵的其他資訊,然後將訊息放在系統消息佇列中。 系統會從系統消息佇列中移除訊息,並將它張貼至適當線程的訊息佇列。 最後,線程的訊息迴圈會移除訊息,並將它傳遞給適當的視窗程序進行處理。 下圖說明鍵盤輸入模型。
鍵盤焦點和啟用
系統會將鍵盤訊息張貼至前景線程的消息佇列,該線程會建立具有鍵盤焦點的視窗。 鍵盤焦點是視窗的暫存屬性。 系統會將鍵盤焦點從一個視窗移至另一個視窗,將鍵盤焦點從一個視窗移到另一個視窗,以在顯示器上共用鍵盤。 具有鍵盤焦點的視窗會接收所有鍵盤訊息,直到焦點變更為不同的窗口為止。
線程可以呼叫 GetFocus 函式來判斷其視窗(如果有的話)目前具有鍵盤焦點。 線程可以藉由呼叫 SetFocus 函式,將鍵盤焦點提供給其中一個視窗。 當鍵盤焦點從某個視窗變更為另一個視窗時,系統會將WM_KILLFOCUS訊息傳送至失去焦點的視窗,然後將WM_SETFOCUS訊息傳送至取得焦點的視窗。
鍵盤焦點的概念與活動視窗的概念有關。 使用中 視窗 是使用者目前正在使用的最上層視窗。 具有鍵盤焦點的視窗是活動視窗,或是活動視窗的子視窗。 為了協助用戶識別使用中的視窗,系統會將它放在 Z 順序的頂端,並醒目提示其標題列(如果有的話)和框線。
使用者可以按兩下最上層視窗、使用ALT+TAB或ALT+ESC鍵組合加以選取,或從 [工作清單] 中選取。 線程可以使用 SetActiveWindow 函式來啟動最上層視窗。 它可以使用 GetActiveWindow 函式來判斷所建立的最上層視窗是否為使用中狀態。
停用一個視窗並啟動另一個視窗時,系統會傳送 WM_ACTIVATE 訊息。 如果視窗已停用,則 wParam 參數的低序單字為零,如果視窗正在啟動則為非零。 當預設視窗程式收到 WM_ACTIVATE 訊息時,它會將鍵盤焦點設定為活動視窗。
若要封鎖鍵盤和滑鼠輸入事件無法連線到應用程式,請使用 BlockInput。 請注意, BlockInput 函式不會干擾異步鍵盤輸入狀態數據表。 這表示封鎖輸入時呼叫 SendInput 函式會變更異步鍵盤輸入狀態數據表。
擊鍵訊息
按下按鍵會導致WM_KEYDOWN或WM_SYSKEYDOWN訊息放在附加至鍵盤焦點視窗的線程消息佇列中。 釋放金鑰會導致將WM_KEYUP或WM_SYSKEYUP訊息放在佇列中。
按鍵和向下鍵訊息通常會成對發生,但是如果使用者按住的按鍵時間夠長,以啟動鍵盤的自動重複功能,系統就會產生一些WM_KEYDOWN或WM_SYSKEYDOWN訊息。 然後,當使用者放開密鑰時,它會產生單一WM_KEYUP或WM_SYSKEYUP訊息。
本章節涵蓋下列主題:
系統和非系統按鍵
系統區分系統擊鍵與非系統按鍵。 系統擊鍵會產生系統擊鍵訊息、WM_SYSKEYDOWN和WM_SYSKEYUP。 非系統按鍵會產生非系統按鍵訊息、WM_KEYDOWN和WM_KEYUP。
如果您的視窗程式必須處理系統按鍵訊息,請確定在處理訊息之後,程式會將它 傳遞給 DefWindowProc 函式。 否則,每當視窗具有鍵盤焦點時,就會停用涉及 ALT 鍵的所有系統作業。 也就是說,使用者將無法存取視窗的功能表或 [系統] 功能表,或使用ALT+ESC或ALT+TAB鍵組合來啟動不同的視窗。
系統按鍵訊息主要是供系統使用,而不是由應用程式使用。 系統會使用它們來提供其內建鍵盤介面給功能表,並允許使用者控制哪個視窗為使用中。 當使用者結合 ALT 鍵輸入按鍵時,或當使用者輸入且沒有視窗具有鍵盤焦點時,就會產生系統按鍵訊息(例如,當使用中應用程式最小化時)。 在此情況下,訊息會張貼至連結至使用中視窗的訊息佇列。
非系統按鍵訊息可供應用程式視窗使用; DefWindowProc 函式不會對它們執行任何動作。 視窗程式可以捨棄它不需要的任何非系統按鍵訊息。
說明的虛擬密鑰代碼
按鍵訊息的 wParam 參數包含按下或放開之按鍵的虛擬按鍵程序代碼。 視虛擬按鍵程式代碼的值而定,視窗程式會處理或忽略擊鍵訊息。
一般視窗程式只會處理它接收並忽略其餘部分的擊鍵訊息子集。 例如,視窗程式可能只會 處理WM_KEYDOWN 擊鍵訊息,而且只有包含游標移動鍵虛擬密鑰代碼、移動鍵(也稱為控制鍵)和函式按鍵的按鍵。 一般視窗程式不會處理字元鍵的擊鍵訊息。 相反地 ,它會使用 TranslateMessage 函式將訊息轉換成字元訊息。 如需 TranslateMessage 和字元訊息的詳細資訊,請參閱字元訊息。
擊鍵訊息旗標
擊鍵訊息的 lParam 參數包含產生訊息之擊鍵的其他資訊。 這項資訊包括重複計數、掃描程式代碼、擴充密鑰旗標、內容程式代碼、先前的索引鍵狀態旗標,以及轉換狀態旗標。 下圖顯示 lParam 參數中這些旗標和值的位置。
應用程式可以使用下列值,從 lParam 的高序字組取得擊鍵旗標。
值 | Description |
---|---|
KF_EXTENDED 0x0100 |
操作擴充索引鍵旗標。 |
KF_DLGMODE 0x0800 |
操作對話框模式旗標,指出對話框是否為使用中。 |
KF_MENUMODE 0x1000 |
操作功能表模式旗標,指出功能表是否為使用中。 |
KF_ALTDOWN 0x2000 |
操作內容程式 代碼旗標。 |
KF_REPEAT 0x4000 |
操作先前的 索引鍵狀態旗標。 |
KF_UP 0x8000 |
操作轉換狀態旗標。 |
範例程式碼:
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
{
WORD vkCode = LOWORD(wParam); // virtual-key code
WORD keyFlags = HIWORD(lParam);
WORD scanCode = LOBYTE(keyFlags); // scan code
BOOL isExtendedKey = (keyFlags & KF_EXTENDED) == KF_EXTENDED; // extended-key flag, 1 if scancode has 0xE0 prefix
if (isExtendedKey)
scanCode = MAKEWORD(scanCode, 0xE0);
BOOL wasKeyDown = (keyFlags & KF_REPEAT) == KF_REPEAT; // previous key-state flag, 1 on autorepeat
WORD repeatCount = LOWORD(lParam); // repeat count, > 0 if several keydown messages was combined into one message
BOOL isKeyReleased = (keyFlags & KF_UP) == KF_UP; // transition-state flag, 1 on keyup
// if we want to distinguish these keys:
switch (vkCode)
{
case VK_SHIFT: // converts to VK_LSHIFT or VK_RSHIFT
case VK_CONTROL: // converts to VK_LCONTROL or VK_RCONTROL
case VK_MENU: // converts to VK_LMENU or VK_RMENU
vkCode = LOWORD(MapVirtualKeyW(scanCode, MAPVK_VSC_TO_VK_EX));
break;
}
// ...
}
break;
重複計數
您可以檢查重複計數,以判斷擊鍵訊息是否代表一個以上的擊鍵。 當鍵盤產生WM_KEYDOWN或WM_SYSKEYDOWN訊息時,系統就會遞增計數,速度比應用程式可以處理這些訊息更快。 當使用者按住足夠長且足以啟動鍵盤的自動重複功能時,通常會發生這種情況。 系統不必將產生的按鍵關閉訊息填入系統消息佇列,而是將訊息合併成單一按鍵關閉訊息,並遞增重複計數。 釋出金鑰無法啟動自動重複功能,因此WM_KEYUP和WM_SYSKEYUP訊息的重複計數一律設定為 1。
掃描代碼
掃描碼是當使用者按下按鍵時,系統所產生的值。 這是一個值,可識別按下的按鍵,不論使用 中的鍵盤配置為何,而不是按鍵所代表的字元。 應用程式通常會忽略掃描代碼。 相反地,它會使用虛擬按鍵程式代碼來解譯擊鍵訊息。
新式鍵盤使用 Human Interface Devices (HID) 規格與電腦通訊。 鍵盤驅動程式 會將從鍵盤傳送的 HID 使用量值轉換為掃描代碼,並將其傳遞至應用程式。
注意
雖然虛擬按鍵碼通常對傳統型應用程式更有用,但當您需要知道按下哪一個按鍵時,您可能需要掃描代碼,而不論目前的 鍵盤配置為何。 例如,WASD (W 為向上、A 為左、S 為向下,而 D 為右)遊戲按鍵系結,可確保美國 QWERTY 或法文 AZERTY 鍵盤版面配置有一致的按鍵形成。
下表列出 Windows 目前可辨識的掃描代碼集。 HID 使用量頁面/HID使用量標識碼/HID使用量名稱值會參考 HID 使用量數據表檔。 索引 鍵位置 值會參考上述鍵盤影像。
Scan 1 Make 程式代碼會在WM_KEYDOWN/WM_KEYUP WM_SYSKEYDOWN//WM_SYSKEYUP和WM_INPUT訊息中傳遞。
HID 使用量頁面名稱 | HID 使用方式名稱 | HID 使用方式頁面 | HID 使用量標識碼 | 掃描 1 製作 | 索引鍵位置 |
---|---|---|---|---|---|
一般桌面 | 系統關閉電源 | 0x0001 | 0x0081 | 0xE05E | |
一般桌面 | 系統睡眠 | 0x0001 | 0x0082 | 0xE05F | |
一般桌面 | 系統喚醒 | 0x0001 | 0x0083 | 0xE063 | |
鍵盤/鍵盤 | ErrorRollOver | 0x0007 | 0x0001 | 0x00FF | |
鍵盤/鍵盤 | 鍵盤 A | 0x0007 | 0x0004 | 0x001E | 31 |
鍵盤/鍵盤 | 鍵盤 B | 0x0007 | 0x0005 | 0x0030 | 50 |
鍵盤/鍵盤 | 鍵盤 C | 0x0007 | 0x0006 | 0x002E | 48 |
鍵盤/鍵盤 | 鍵盤 D | 0x0007 | 0x0007 | 0x0020 | 33 |
鍵盤/鍵盤 | 鍵盤 E | 0x0007 | 0x0008 | 0x0012 | 19 |
鍵盤/鍵盤 | 鍵盤 F | 0x0007 | 0x0009 | 0x0021 | 34 |
鍵盤/鍵盤 | 鍵盤 G | 0x0007 | 0x000A | 0x0022 | 35 |
鍵盤/鍵盤 | 鍵盤 H | 0x0007 | 0x000B | 0x0023 | 36 |
鍵盤/鍵盤 | 鍵盤 I | 0x0007 | 0x000C | 0x0017 | 24 |
鍵盤/鍵盤 | 鍵盤 J | 0x0007 | 0x000D | 0x0024 | 37 |
鍵盤/鍵盤 | 鍵盤 K | 0x0007 | 0x000E | 0x0025 | 38 |
鍵盤/鍵盤 | 鍵盤 L | 0x0007 | 0x000F | 0x0026 | 39 |
鍵盤/鍵盤 | 鍵盤 M | 0x0007 | 0x0010 | 0x0032 | 52 |
鍵盤/鍵盤 | 鍵盤 N | 0x0007 | 0x0011 | 0x0031 | 51 |
鍵盤/鍵盤 | 鍵盤 O | 0x0007 | 0x0012 | 0x0018 | 25 |
鍵盤/鍵盤 | 鍵盤 P | 0x0007 | 0x0013 | 0x0019 | 26 |
鍵盤/鍵盤 | 鍵盤 Q | 0x0007 | 0x0014 | 0x0010 | 17 |
鍵盤/鍵盤 | 鍵盤 R | 0x0007 | 0x0015 | 0x0013 | 20 |
鍵盤/鍵盤 | 鍵盤 S | 0x0007 | 0x0016 | 0x001F | 32 |
鍵盤/鍵盤 | 鍵盤 T | 0x0007 | 0x0017 | 0x0014 | 21 |
鍵盤/鍵盤 | 鍵盤U | 0x0007 | 0x0018 | 0x0016 | 23 |
鍵盤/鍵盤 | 鍵盤 V | 0x0007 | 0x0019 | 0x002F | 49 |
鍵盤/鍵盤 | 鍵盤 W | 0x0007 | 0x001A | 0x0011 | 18 |
鍵盤/鍵盤 | 鍵盤 X | 0x0007 | 0x001B | 0x002D | 47 |
鍵盤/鍵盤 | 鍵盤 Y | 0x0007 | 0x001C | 0x0015 | 22 |
鍵盤/鍵盤 | 鍵盤 Z | 0x0007 | 0x001D | 0x002C | 46 |
鍵盤/鍵盤 | 鍵盤 1 和砰 | 0x0007 | 0x001E | 0x0002 | 2 |
鍵盤/鍵盤 | 鍵盤 2 和 At | 0x0007 | 0x001F | 0x0003 | 3 |
鍵盤/鍵盤 | 鍵盤 3 和哈希 | 0x0007 | 0x0020 | 0x0004 | 4 |
鍵盤/鍵盤 | 鍵盤 4 和美元 | 0x0007 | 0x0021 | 0x0005 | 5 |
鍵盤/鍵盤 | 鍵盤5和百分比 | 0x0007 | 0x0022 | 0x0006 | 6 |
鍵盤/鍵盤 | 鍵盤 6 和插入號 | 0x0007 | 0x0023 | 0x0007 | 7 |
鍵盤/鍵盤 | 鍵盤 7 和 Ampersand | 0x0007 | 0x0024 | 0x0008 | 8 |
鍵盤/鍵盤 | 鍵盤8和星形 | 0x0007 | 0x0025 | 0x0009 | 9 |
鍵盤/鍵盤 | 鍵盤 9 和左括弧 | 0x0007 | 0x0026 | 0x000A | 10 |
鍵盤/鍵盤 | 鍵盤 0 和右括弧 | 0x0007 | 0x0027 | 0x000B | 11 |
鍵盤/鍵盤 | 鍵盤傳回 Enter | 0x0007 | 0x0028 | 0x001C | 43 |
鍵盤/鍵盤 | 鍵盤逸出 | 0x0007 | 0x0029 | 0x0001 | 110 |
鍵盤/鍵盤 | 鍵盤刪除 | 0x0007 | 0x002A | 0x000E | 15 |
鍵盤/鍵盤 | 鍵盤索引標籤 | 0x0007 | 0x002B | 0x000F | 16 |
鍵盤/鍵盤 | 鍵盤空格鍵 | 0x0007 | 0x002C | 0x0039 | 61 |
鍵盤/鍵盤 | 鍵盤虛線和底線 | 0x0007 | 0x002D | 0x000C | 12 |
鍵盤/鍵盤 | 鍵盤等於和加號 | 0x0007 | 0x002E | 0x000D | 13 |
鍵盤/鍵盤 | 鍵盤左大括弧 | 0x0007 | 0x002F | 0x001A | 27 |
鍵盤/鍵盤 | 鍵盤右大括弧 | 0x0007 | 0x0030 | 0x001B | 28 |
鍵盤/鍵盤 | 鍵盤管道和斜線 | 0x0007 | 0x0031 | 0x002B | 29 |
鍵盤/鍵盤 | 非美國鍵盤 | 0x0007 | 0x0032 | 0x002B | 42 |
鍵盤/鍵盤 | 鍵盤分號和冒號 | 0x0007 | 0x0033 | 0x0027 | 40 |
鍵盤/鍵盤 | 鍵盤引號和雙引號 | 0x0007 | 0x0034 | 0x0028 | 41 |
鍵盤/鍵盤 | 鍵盤嚴重輔色和Tilde | 0x0007 | 0x0035 | 0x0029 | 1 |
鍵盤/鍵盤 | 鍵盤逗號 | 0x0007 | 0x0036 | 0x0033 | 53 |
鍵盤/鍵盤 | 鍵盤期間 | 0x0007 | 0x0037 | 0x0034 | 54 |
鍵盤/鍵盤 | 鍵盤問題標記 | 0x0007 | 0x0038 | 0x0035 | 55 |
鍵盤/鍵盤 | 鍵盤上限鎖定 | 0x0007 | 0x0039 | 0x003A | 30 |
鍵盤/鍵盤 | 鍵盤 F1 | 0x0007 | 0x003A | 0x003B | 112 |
鍵盤/鍵盤 | 鍵盤 F2 | 0x0007 | 0x003B | 0x003C | 113 |
鍵盤/鍵盤 | 鍵盤 F3 | 0x0007 | 0x003C | 0x003D | 114 |
鍵盤/鍵盤 | 鍵盤 F4 | 0x0007 | 0x003D | 0x003E | 115 |
鍵盤/鍵盤 | 鍵盤 F5 | 0x0007 | 0x003E | 0x003F | 116 |
鍵盤/鍵盤 | 鍵盤 F6 | 0x0007 | 0x003F | 0x0040 | 117 |
鍵盤/鍵盤 | 鍵盤 F7 | 0x0007 | 0x0040 | 0x0041 | 118 |
鍵盤/鍵盤 | 鍵盤 F8 | 0x0007 | 0x0041 | 0x0042 | 119 |
鍵盤/鍵盤 | 鍵盤 F9 | 0x0007 | 0x0042 | 0x0043 | 120 |
鍵盤/鍵盤 | 鍵盤 F10 | 0x0007 | 0x0043 | 0x0044 | 121 |
鍵盤/鍵盤 | 鍵盤 F11 | 0x0007 | 0x0044 | 0x0057 | 122 |
鍵盤/鍵盤 | 鍵盤 F12 | 0x0007 | 0x0045 | 0x0058 | 123 |
鍵盤/鍵盤 | 鍵盤 PrintScreen | 0x0007 | 0x0046 | 0xE037 0x0054 *附注 1 |
124 |
鍵盤/鍵盤 | 鍵盤捲動鎖定 | 0x0007 | 0x0047 | 0x0046 | 125 |
鍵盤/鍵盤 | 鍵盤暫停 | 0x0007 | 0x0048 | 0xE11D45 0xE046 *附注 2 0x0045 *附注 3 |
126 |
鍵盤/鍵盤 | 鍵盤插入 | 0x0007 | 0x0049 | 0xE052 | 75 |
鍵盤/鍵盤 | 鍵盤首頁 | 0x0007 | 0x004A | 0xE047 | 80 |
鍵盤/鍵盤 | 鍵盤 PageUp | 0x0007 | 0x004B | 0xE049 | 85 |
鍵盤/鍵盤 | 鍵盤向前刪除 | 0x0007 | 0x004C | 0xE053 | 76 |
鍵盤/鍵盤 | 鍵盤結束 | 0x0007 | 0x004D | 0xE04F | 81 |
鍵盤/鍵盤 | 鍵盤 PageDown | 0x0007 | 0x004E | 0xE051 | 86 |
鍵盤/鍵盤 | 鍵盤 RightArrow | 0x0007 | 0x004F | 0xE04D | 89 |
鍵盤/鍵盤 | 鍵盤 LeftArrow | 0x0007 | 0x0050 | 0xE04B | 79 |
鍵盤/鍵盤 | 鍵盤向下箭號 | 0x0007 | 0x0051 | 0xE050 | 84 |
鍵盤/鍵盤 | 鍵盤 UpArrow | 0x0007 | 0x0052 | 0xE048 | 83 |
鍵盤/鍵盤 | Keypad Num Lock and Clear | 0x0007 | 0x0053 | 0x0045 0xE045 *附注 3 |
90 |
鍵盤/鍵盤 | 鍵盤正斜線 | 0x0007 | 0x0054 | 0xE035 | 95 |
鍵盤/鍵盤 | 鍵盤星形 | 0x0007 | 0x0055 | 0x0037 | 100 |
鍵盤/鍵盤 | 鍵盤虛線 | 0x0007 | 0x0056 | 0x004A | 105 |
鍵盤/鍵盤 | 鍵盤加號 | 0x0007 | 0x0057 | 0x004E | 106 |
鍵盤/鍵盤 | 鍵盤 ENTER | 0x0007 | 0x0058 | 0xE01C | 108 |
鍵盤/鍵盤 | 鍵盤 1 和結束 | 0x0007 | 0x0059 | 0x004F | 93 |
鍵盤/鍵盤 | 鍵盤 2 和向下箭號 | 0x0007 | 0x005A | 0x0050 | 98 |
鍵盤/鍵盤 | 鍵盤 3 和 PageDn | 0x0007 | 0x005B | 0x0051 | 103 |
鍵盤/鍵盤 | 鍵盤 4 和向左鍵 | 0x0007 | 0x005C | 0x004B | 92 |
鍵盤/鍵盤 | 鍵盤 5 | 0x0007 | 0x005D | 0x004C | 97 |
鍵盤/鍵盤 | 鍵盤 6 和向右鍵 | 0x0007 | 0x005E | 0x004D | 102 |
鍵盤/鍵盤 | 鍵盤 7 和首頁 | 0x0007 | 0x005F | 0x0047 | 91 |
鍵盤/鍵盤 | 鍵盤8和向上鍵 | 0x0007 | 0x0060 | 0x0048 | 96 |
鍵盤/鍵盤 | 鍵盤 9 和 PageUp | 0x0007 | 0x0061 | 0x0049 | 101 |
鍵盤/鍵盤 | 鍵盤 0 和插入 | 0x0007 | 0x0062 | 0x0052 | 99 |
鍵盤/鍵盤 | 鍵盤期間 | 0x0007 | 0x0063 | 0x0053 | 104 |
鍵盤/鍵盤 | 鍵盤非美國斜線 | 0x0007 | 0x0064 | 0x0056 | 45 |
鍵盤/鍵盤 | 鍵盤應用程式 | 0x0007 | 0x0065 | 0xE05D | 129 |
鍵盤/鍵盤 | 鍵盤電源 | 0x0007 | 0x0066 | 0xE05E | |
鍵盤/鍵盤 | 鍵盤等於 | 0x0007 | 0x0067 | 0x0059 | |
鍵盤/鍵盤 | 鍵盤 F13 | 0x0007 | 0x0068 | 0x0064 | |
鍵盤/鍵盤 | 鍵盤 F14 | 0x0007 | 0x0069 | 0x0065 | |
鍵盤/鍵盤 | 鍵盤 F15 | 0x0007 | 0x006A | 0x0066 | |
鍵盤/鍵盤 | 鍵盤 F16 | 0x0007 | 0x006B | 0x0067 | |
鍵盤/鍵盤 | 鍵盤 F17 | 0x0007 | 0x006C | 0x0068 | |
鍵盤/鍵盤 | 鍵盤 F18 | 0x0007 | 0x006D | 0x0069 | |
鍵盤/鍵盤 | 鍵盤 F19 | 0x0007 | 0x006E | 0x006A | |
鍵盤/鍵盤 | 鍵盤 F20 | 0x0007 | 0x006F | 0x006B | |
鍵盤/鍵盤 | 鍵盤 F21 | 0x0007 | 0x0070 | 0x006C | |
鍵盤/鍵盤 | 鍵盤 F22 | 0x0007 | 0x0071 | 0x006D | |
鍵盤/鍵盤 | 鍵盤 F23 | 0x0007 | 0x0072 | 0x006E | |
鍵盤/鍵盤 | 鍵盤 F24 | 0x0007 | 0x0073 | 0x0076 | |
鍵盤/鍵盤 | 鍵盤逗號 | 0x0007 | 0x0085 | 0x007E | 107 *附注 4 |
鍵盤/鍵盤 | 鍵盤國際1 | 0x0007 | 0x0087 | 0x0073 | 56 *附注 4,5 |
鍵盤/鍵盤 | 鍵盤國際2 | 0x0007 | 0x0088 | 0x0070 | 133 *附注 5 |
鍵盤/鍵盤 | 鍵盤國際3 | 0x0007 | 0x0089 | 0x007D | 14 *附注 5 |
鍵盤/鍵盤 | 鍵盤國際4 | 0x0007 | 0x008A | 0x0079 | 132 *附注 5 |
鍵盤/鍵盤 | 鍵盤國際5 | 0x0007 | 0x008B | 0x007B | 131 *附注 5 |
鍵盤/鍵盤 | 鍵盤國際6 | 0x0007 | 0x008C | 0x005C | |
鍵盤/鍵盤 | 鍵盤 LANG1 | 0x0007 | 0x0090 | 0x0072 *附注 6 0x00F2 *附注 3、6 |
|
鍵盤/鍵盤 | 鍵盤 LANG2 | 0x0007 | 0x0091 | 0x0071 *附注 6 0x00F1 *附注 3、6 |
|
鍵盤/鍵盤 | 鍵盤 LANG3 | 0x0007 | 0x0092 | 0x0078 | |
鍵盤/鍵盤 | 鍵盤 LANG4 | 0x0007 | 0x0093 | 0x0077 | |
鍵盤/鍵盤 | 鍵盤 LANG5 | 0x0007 | 0x0094 | 0x0076 | |
鍵盤/鍵盤 | 鍵盤 LeftControl | 0x0007 | 0x00E0 | 0x001D | 58 |
鍵盤/鍵盤 | 鍵盤 LeftShift | 0x0007 | 0x00E1 | 0x002A | 44 |
鍵盤/鍵盤 | 鍵盤 LeftAlt | 0x0007 | 0x00E2 | 0x0038 | 60 |
鍵盤/鍵盤 | 鍵盤左 GUI | 0x0007 | 0x00E3 | 0xE05B | 127 |
鍵盤/鍵盤 | 鍵盤 RightControl | 0x0007 | 0x00E4 | 0xE01D | 64 |
鍵盤/鍵盤 | 鍵盤 RightShift | 0x0007 | 0x00E5 | 0x0036 | 57 |
鍵盤/鍵盤 | 鍵盤 RightAlt | 0x0007 | 0x00E6 | 0xE038 | 62 |
鍵盤/鍵盤 | 鍵盤右鍵 GUI | 0x0007 | 0x00E7 | 0xE05C | 128 |
消費者 | 掃描下一個追蹤 | 0x000C | 0x00B5 | 0xE019 | |
消費者 | 掃描上一個追蹤 | 0x000C | 0x00B6 | 0xE010 | |
消費者 | 停止 | 0x000C | 0x00B7 | 0xE024 | |
消費者 | 執行/暫停 | 0x000C | 0x00CD | 0xE022 | |
消費者 | 靜音 | 0x000C | 0x00E2 | 0xE020 | |
消費者 | 磁碟區遞增 | 0x000C | 0x00E9 | 0xE030 | |
消費者 | 磁碟區遞減 | 0x000C | 0x00EA | 0xE02E | |
消費者 | AL 取用者控制項設定 | 0x000C | 0x0183 | 0xE06D | |
消費者 | AL 電子郵件閱讀程式 | 0x000C | 0x018A | 0xE06C | |
消費者 | AL 計算機 | 0x000C | 0x0192 | 0xE021 | |
消費者 | AL 本機電腦瀏覽器 | 0x000C | 0x0194 | 0xE06B | |
消費者 | AC 搜尋 | 0x000C | 0x0221 | 0xE065 | |
消費者 | AC Home | 0x000C | 0x0223 | 0xE032 | |
消費者 | AC Back | 0x000C | 0x0224 | 0xE06A | |
消費者 | AC 轉寄 | 0x000C | 0x0225 | 0xE069 | |
消費者 | AC Stop | 0x000C | 0x0226 | 0xE068 | |
消費者 | AC 重新整理 | 0x000C | 0x0227 | 0xE067 | |
消費者 | AC 書籤 | 0x000C | 0x022A | 0xE066 |
注意:
- SysRq 鍵掃描代碼會在 Alt+Print 畫面按鍵上發出
- 中斷按鍵掃描程序代碼會在 Control+Pause 按鍵上發出
- 如舊版鍵盤訊息所示
- 鍵盤上有按鍵
- 按鍵存在於日文鍵盤上
- 掃描碼只會在金鑰發行事件中發出
擴充索引鍵旗標
擴充鍵旗標指出按鍵訊息是否源自增強式 101/102 鍵鍵盤上的其中一個額外按鍵。 延伸鍵是由鍵盤右側的 ALT 鍵和 CTRL 鍵所組成:數值鍵盤左側叢集中的 INS、DEL、HOME、END、PAGE UP、PAGE DOWN 和箭頭鍵;NUM LOCK 鍵;BREAK (CTRL+PAUSE) 鍵;PRINT SCRN 鍵;和數位鍵盤中的除號 (/) 和 ENTER 鍵。 右側 SHIFT 鍵不會被視為擴充密鑰,而是具有個別的掃描碼。
如果指定,掃描程式代碼是由兩個字節的序列所組成,其中第一個字節的值為 0xE0。
內容程序代碼
內容程式代碼指出當產生按鍵訊息時,ALT 鍵是否已關閉。 如果 ALT 鍵已關閉,則程式代碼為 1,如果它已啟動,則為 0。
上一個索引鍵狀態旗標
先前的索引鍵狀態旗標會指出產生按鍵訊息的按鍵先前是向上或向下。 如果索引鍵先前已關閉,則為 1;如果金鑰先前已啟動,則為 0。 您可以使用此旗標來識別鍵盤自動重複功能所產生的擊鍵訊息。 針對自動重複功能所產生的WM_KEYDOWN和WM_SYSKEYDOWN擊鍵訊息,此旗標會設定為 1。 一律會針對WM_KEYUP和WM_SYSKEYUP訊息設定為 1。
轉換狀態旗標
轉換狀態旗標會指出按下按鍵或釋放按鍵是否產生擊鍵訊息。 對於WM_KEYDOWN和WM_SYSKEYDOWN訊息,此旗標一律設定為0;WM_KEYUP和WM_SYSKEYUP訊息一律設定為1。
字元訊息
擊鍵訊息提供許多按鍵相關信息,但不會提供字元擊鍵的字元碼。 若要擷取字元碼,應用程式必須在其線程訊息迴圈中包含 TranslateMessage 函式。 TranslateMessage 會將WM_KEYDOWN或WM_SYSKEYDOWN訊息傳遞至鍵盤配置。 配置會檢查訊息的虛擬密鑰程式代碼,如果它對應至字元密鑰,則會提供對等字元碼(考慮到 SHIFT 和 CAPS LOCK 鍵的狀態)。 然後,它會產生字元訊息,其中包含字元碼,並將訊息放在消息佇列頂端。 訊息迴圈的下一個反覆專案會從佇列中移除字元訊息,並將訊息分派至適當的窗口程式。
本章節涵蓋下列主題:
非系統字元訊息
視窗程式可以接收下列字元訊息:WM_CHAR、WM_DEADCHAR、WM_SYSCHAR、WM_SYSDEADCHAR和WM_UNICHAR。 TranslateMessage 函式會在處理WM_KEYDOWN訊息時產生WM_CHAR或WM_DEADCHAR訊息。 同樣地,它會在處理WM_SYSKEYDOWN訊息時產生WM_SYSCHAR或WM_SYSDEADCHAR訊息。
處理鍵盤輸入的應用程式通常會忽略除了WM_CHAR和WM_UNICHAR訊息以外的所有訊息,將任何其他訊息傳遞至 DefWindowProc 函式。 請注意, WM_CHAR 使用 UTF-16(16 位 Unicode 轉換格式)或 ANSI 字元集,而 WM_UNICHAR 一律使用 UTF-32(32 位 Unicode 轉換格式)。 系統會使用WM_SYSCHAR和WM_SYSDEADCHAR訊息來實作功能表助記鍵。
所有字元訊息的 wParam 參數包含已按下之字元鍵的字元碼。 字元碼的值取決於接收訊息之視窗的窗口類別。 如果使用 RegisterClass 函式的 Unicode 版本來註冊視窗類別,系統就會將 Unicode 字元提供給該類別的所有視窗。 否則,系統會提供 ANSI 字元碼。 如需詳細資訊,請參閱在 Windows 應用程式中註冊視窗類別和使用 UTF-8 代碼頁。
字元訊息之 lParam 參數的內容與已轉譯成產生字元訊息的 lParam 參數內容相同。 如需詳細資訊,請參閱 擊鍵訊息旗標。
無效字元訊息
某些非英文鍵盤包含字元鍵,這些按鍵不會自行產生字元。 相反地,它們用來將變音符號新增至後續擊鍵所產生的字元。 這些金鑰稱為 死鍵。 德文鍵盤上的圓環反射鍵是死鍵的範例。 若要輸入由 「o」 組成的字元與周光反射,德文用戶會輸入周光反射鍵,後面接著 「o」 鍵。 具有鍵盤焦點的視窗會收到下列訊息序列:
TranslateMessage 會在處理死鍵WM_KEYDOWN訊息時產生WM_DEADCHAR訊息。 雖然WM_DEADCHAR訊息的 wParam 參數包含死鍵的變音符號字元碼,但應用程式通常會忽略訊息。 相反地,它會處理 後續擊鍵所產生的WM_CHAR 訊息。 WM_CHAR訊息的 wParam 參數包含具有變音符號之字母的字元碼。 如果後續的擊鍵產生無法與讀音符號結合的字元,系統會產生兩 個WM_CHAR 訊息。 第一個的 wParam 參數包含變音符號的字元碼;第二個的 wParam 參數包含後續字元索引鍵的字元碼。
TranslateMessage 函式會在處理來自系統死鍵的WM_SYSKEYDOWN訊息時產生WM_SYSDEADCHAR訊息(結合 ALT 鍵按下的死鍵)。 應用程式通常會忽略 WM_SYSDEADCHAR 訊息。
索引鍵狀態
處理鍵盤訊息時,應用程式可能需要判斷產生目前訊息之按鍵以外的另一個按鍵狀態。 例如,可讓使用者按下 SHIFT+END 選取文字處理應用程式,必須在收到 END 鍵的擊鍵訊息時檢查 SHIFT 鍵的狀態。 應用程式可以使用 GetKeyState 函式來判斷產生目前訊息時虛擬密鑰的狀態;它可以使用 GetAsyncKeyState 函式來擷取虛擬密鑰的目前狀態。
鍵盤配置會維護名稱清單。 產生單一字元的索引鍵名稱與索引鍵所產生的字元相同。 TAB 和 ENTER 等非字元索引鍵的名稱會儲存為字元字串。 應用程式可以藉由呼叫 GetKeyNameText 函式,從設備驅動器擷取任何密鑰的名稱。
擊鍵和字元翻譯
系統包含數個特殊用途函式,可轉譯各種擊鍵訊息所提供的掃描碼、字元碼和虛擬按鍵碼。 這些函式包括 MapVirtualKey、ToAscii、ToUnicode 和 VkKeyScan。
此外,Microsoft Rich Edit 3.0 支援 HexToUnicode IME,這可讓使用者使用快速鍵在十六進位和 Unicode 字元之間轉換。 這表示當 Microsoft Rich Edit 3.0 併入應用程式時,應用程式會繼承 HexToUnicode IME 的功能。
熱鍵支援
作用 中索引鍵 是產生 WM_HOTKEY 訊息的按鍵組合,系統會將訊息放在線程消息佇列頂端,略過佇列中的任何現有訊息。 應用程式會使用熱鍵從使用者取得高優先順序鍵盤輸入。 例如,藉由定義由 CTRL+C 按鍵組合組成的熱鍵,應用程式可以讓使用者取消冗長的作業。
若要定義熱鍵,應用程式會呼叫 RegisterHotKey 函式,並指定產生WM_HOTKEY訊息的索引鍵組合、接收訊息的視窗句柄,以及作用中索引鍵的標識碼。 當使用者按下熱鍵時, 會將WM_HOTKEY 訊息放在建立視窗之線程的訊息佇列中。 訊息的 wParam 參數包含作用中索引鍵的標識碼。 應用程式可以定義線程的多個熱鍵,但線程中的每個熱鍵都必須有唯一標識符。 在應用程式終止之前,它應該使用 UnregisterHotKey 函式來終結熱鍵。
應用程式可以使用熱鍵控制件,讓使用者輕鬆選擇熱鍵。 經常性鍵控制項通常用於定義啟動視窗的熱鍵;它們不會使用 RegisterHotKey 和 UnregisterHotKey 函式。 相反地,使用作用中鍵控件的應用程式通常會傳送 WM_SETHOTKEY 訊息來設定作用中索引鍵。 每當使用者按下快捷鍵時,系統就會傳送指定 SC_HOTKEY的WM_SYSCOMMAND 訊息。 如需熱鍵控件的詳細資訊,請參閱熱鍵控件中的 <使用熱鍵控件>。
流覽和其他函式的鍵盤按鍵
Windows 針對瀏覽器功能、媒體功能、應用程式啟動和電源管理提供特殊按鍵的鍵盤支援。 WM_APPCOMMAND支持額外的鍵盤按鍵。 此外, ShellProc 函式會修改為支持額外的鍵盤按鍵。
元件應用程式中的子視窗不太可能直接實作這些額外鍵盤按鍵的命令。 因此,按下其中一個按鍵時,DefWindowProc 會將WM_APPCOMMAND訊息傳送至視窗。 DefWindowProc 也會將WM_APPCOMMAND訊息反升至其父視窗。 這類似於使用滑鼠右鍵叫用操作功能表的方式,也就是 DefWindowProc 會在滑鼠右鍵上傳送 WM_CONTEXTMENU 訊息,並將它反升至其父系。 此外,如果 DefWindowProc 收到 最上層視窗的WM_APPCOMMAND 訊息,則會使用程式代碼 HSHELL_APPCOMMAND呼叫殼層攔截。
Windows 也支援 Microsoft IntelliMouse Explorer,這是具有五個按鈕的滑鼠。 這兩個額外按鈕支援向前和向後瀏覽器流覽。 如需詳細資訊,請參閱 XBUTTON。
模擬輸入
若要模擬不中斷的一系列使用者輸入事件,請使用 SendInput 函式。 函式接受三個參數。 第一個參數 cInputs 表示將仿真的輸入事件數目。 第二個參數 rgInputs 是 INPUT 結構的數位,每個參數都會描述一種輸入事件,以及該事件的其他資訊。 最後一個參數 cbSize 會接受 INPUT 結構的大小,以位元組為單位。
SendInput 函式的運作方式是將一系列的模擬輸入事件插入裝置的輸入數據流。 效果類似於重複呼叫keybd_event或mouse_event函式,不同之處在於系統可確保沒有任何其他輸入事件與模擬事件交織在一起。 呼叫完成時,傳回值會指出已成功播放的輸入事件數目。 如果此值為零,則會封鎖輸入。
SendInput 函式不會重設鍵盤的目前狀態。 因此,如果使用者在呼叫此函式時按下任何按鍵,他們可能會干擾此函式所產生的事件。 如果您擔心可能的干擾,請使用 GetAsyncKeyState 函式檢查鍵盤的狀態,並視需要更正。
語言、地區設定和鍵盤配置
語言是自然語言,例如英文、法文和日文。 子語言是一種自然語言的變體,該語言在特定地理區域中口語,例如英國和 美國 中說的英文子語言。 應用程式會使用稱為 語言標識碼的值來唯一識別語言和子語言。
應用程式通常會使用 地區設定 來設定用來處理輸入和輸出的語言。 例如,設定鍵盤的地區設定會影響鍵盤所產生的字元值。 設定顯示器或印表機的地區設定會影響顯示或列印的字元。 應用程式會載入並使用鍵盤配置來設定鍵盤的地區設定。 他們會選取支援指定地區設定的字型,以設定顯示或印表機的地區設定。
鍵盤配置不僅會指定鍵盤上按鍵的實體位置,也會決定按下這些按鍵所產生的字元值。 每個配置都會識別目前的輸入語言,並決定由哪些索引鍵和按鍵組合產生哪些字元值。
每個鍵盤配置都有對應的句柄,可識別版面配置和語言。 句柄的低字是語言標識碼。 高字是裝置句柄、指定實體版面配置或零,表示預設實體配置。 用戶可以將任何輸入語言與實體版面配置產生關聯。 例如,偶爾在法文中工作的英文使用者可以將鍵盤的輸入語言設定為法文,而不需要變更鍵盤的實體版面配置。 這表示使用者可以使用熟悉的英文版面配置,以法文輸入文字。
應用程式通常不會直接操作輸入語言。 相反地,用戶會設定語言和版面配置組合,然後在其中切換。 當使用者按下以不同語言標示的文字時,應用程式會呼叫 ActivateKeyboardLayout 函式,以啟用該語言的用戶預設版面配置。 如果使用者以不在使用中列表的語言編輯文字,應用程式可以使用語言呼叫 LoadKeyboardLayout 函式,以根據該語言取得版面配置。
ActivateKeyboardLayout 函式會設定目前工作的輸入語言。 hkl 參數可以是鍵盤配置或零擴充語言標識碼的句柄。 鍵盤配置控點可以從 LoadKeyboardLayout 或 GetKeyboardLayoutList 函式取得。 HKL_NEXT和HKL_PREV值也可以用來選取下一個或上一個鍵盤。
GetKeyboardLayoutName 函式會擷取呼叫線程的作用中鍵盤配置名稱。 如果應用程式使用 LoadKeyboardLayout 函式建立使用中版面配置,GetKeyboardLayoutName 會擷取用來建立版面配置的相同字串。 否則,字串是對應至使用中版面配置地區設定的主要語言標識碼。 這表示函式不一定會區分具有相同主要語言的不同版面配置,因此無法傳回輸入語言的特定資訊。 不過,GetKeyboardLayout 函式可用來判斷輸入語言。
LoadKeyboardLayout 函式會載入鍵盤配置,並讓使用者可以使用配置。 應用程式可以使用 KLF_ACTIVATE 值,立即啟用目前線程的配置。 應用程式可以使用 KLF_REORDER 值來重新排序版面配置,而不需同時指定 KLF_ACTIVATE 值。 載入鍵盤配置時,應用程式應該一律使用 KLF_SUBSTITUTE_OK 值,以確保已選取使用者的喜好設定。
針對多語系支援, LoadKeyboardLayout 函式會提供 KLF_REPLACELANG 和 KLF_NOTELLSHELL 旗標。 KLF_REPLACELANG旗標會指示函式取代現有的鍵盤配置,而不需要變更語言。 嘗試使用相同語言識別碼取代現有的配置,但未指定 KLF_REPLACELANG 是錯誤。 KLF_NOTELLSHELL旗標可防止函式在新增或取代鍵盤配置時通知殼層。 這對於在連續一系列呼叫中新增多個版面配置的應用程式很有用。 這個旗標應該用於最後一次呼叫的所有專案。
UnloadKeyboardLayout 函式會受到限制,因為它無法卸除系統默認輸入語言。 這可確保使用者一律有一個配置可供輸入文字使用殼層和文件系統所使用的相同字元集。