鍵盤輸入概觀

應用程式應該接受鍵盤和滑鼠的用戶輸入。 應用程式會以張貼至視窗的訊息形式接收鍵盤輸入。

鍵盤輸入模型

系統藉由安裝適用於目前鍵盤的鍵盤設備驅動器,為應用程式提供與裝置無關的鍵盤支援。 系統會使用使用者或應用程式目前選取的語言特定鍵盤配置,提供與語言無關的鍵盤支援。 鍵盤設備驅動器會從鍵盤接收掃描代碼,這些代碼會傳送至鍵盤配置,這些鍵盤配置會轉譯成訊息,並張貼到應用程式中的適當視窗。

指派給鍵盤上每個按鍵是稱為掃描碼的唯一值,這是鍵盤上按鍵的裝置相依標識符。 當使用者輸入按鍵時,鍵盤會產生兩個掃描碼,一個當使用者按下按鍵,另一個當使用者放開按鍵時。

鍵盤設備驅動器會解譯掃描代碼,並將它轉譯為 虛擬按鍵程式代碼,這是系統所定義的裝置獨立值,可識別按鍵的目的。 翻譯掃描程式代碼之後,鍵盤配置會建立包含掃描程式代碼、虛擬按鍵程式代碼,以及按鍵的其他資訊,然後將訊息放在系統消息佇列中。 系統會從系統消息佇列中移除訊息,並將它張貼至適當線程的訊息佇列。 最後,線程的訊息迴圈會移除訊息,並將它傳遞給適當的視窗程序進行處理。 下圖說明鍵盤輸入模型。

keyboard input processing model

鍵盤焦點和啟用

系統會將鍵盤訊息張貼至前景線程的消息佇列,該線程會建立具有鍵盤焦點的視窗。 鍵盤焦點是視窗的暫存屬性。 系統會將鍵盤焦點從一個視窗移至另一個視窗,將鍵盤焦點從一個視窗移到另一個視窗,以在顯示器上共用鍵盤。 具有鍵盤焦點的視窗會接收所有鍵盤訊息,直到焦點變更為不同的窗口為止。

線程可以呼叫 GetFocus 函式來判斷其視窗(如果有的話)目前具有鍵盤焦點。 線程可以藉由呼叫 SetFocus 函式,將鍵盤焦點提供給其中一個視窗。 當鍵盤焦點從某個視窗變更為另一個視窗時,系統會將WM_KILLFOCUS訊息傳送至失去焦點的視窗,然後將WM_SETFOCUS訊息傳送至取得焦點的視窗。

鍵盤焦點的概念與活動視窗的概念有關。 使用中 視窗 是使用者目前正在使用的最上層視窗。 具有鍵盤焦點的視窗是活動視窗,或是活動視窗的子視窗。 為了協助用戶識別使用中的視窗,系統會將它放在 Z 順序的頂端,並醒目提示其標題列(如果有的話)和框線。

使用者可以按兩下最上層視窗、使用ALT+TAB或ALT+ESC鍵組合加以選取,或從 [工作清單] 中選取。 線程可以使用 SetActiveWindow 函式來啟動最上層視窗 它可以使用 GetActiveWindow 函式來判斷所建立的最上層視窗是否為使用中狀態。

停用一個視窗並啟動另一個視窗時,系統會傳送 WM_ACTIVATE 訊息。 如果視窗已停用,則 wParam 參數的低序單字為零,如果視窗正在啟動則為非零。 當預設視窗程式收到 WM_ACTIVATE 訊息時,它會將鍵盤焦點設定為活動視窗。

若要封鎖鍵盤和滑鼠輸入事件無法連線到應用程式,請使用 BlockInput 請注意, BlockInput 函式不會干擾異步鍵盤輸入狀態數據表。 這表示封鎖輸入時呼叫 SendInput 函式會變更異步鍵盤輸入狀態數據表。

擊鍵訊息

按下按鍵會導致WM_KEYDOWNWM_SYSKEYDOWN訊息放在附加至鍵盤焦點視窗的線程消息佇列中。 釋放金鑰會導致將WM_KEYUPWM_SYSKEYUP訊息放在佇列中。

按鍵和向下鍵訊息通常會成對發生,但是如果使用者按住的按鍵時間夠長,以啟動鍵盤的自動重複功能,系統就會產生一些WM_KEYDOWNWM_SYSKEYDOWN訊息。 然後,當使用者放開密鑰時,它會產生單一WM_KEYUPWM_SYSKEYUP訊息。

本章節涵蓋下列主題:

系統和非系統按鍵

系統區分系統擊鍵與非系統按鍵。 系統擊鍵會產生系統擊鍵訊息、WM_SYSKEYDOWNWM_SYSKEYUP。 非系統按鍵會產生非系統按鍵訊息、WM_KEYDOWNWM_KEYUP。

如果您的視窗程式必須處理系統按鍵訊息,請確定在處理訊息之後,程式會將它 傳遞給 DefWindowProc 函式。 否則,每當視窗具有鍵盤焦點時,就會停用涉及 ALT 鍵的所有系統作業。 也就是說,使用者將無法存取視窗的功能表或 [系統] 功能表,或使用ALT+ESC或ALT+TAB鍵組合來啟動不同的視窗。

系統按鍵訊息主要是供系統使用,而不是由應用程式使用。 系統會使用它們來提供其內建鍵盤介面給功能表,並允許使用者控制哪個視窗為使用中。 當使用者結合 ALT 鍵輸入按鍵時,或當使用者輸入且沒有視窗具有鍵盤焦點時,就會產生系統按鍵訊息(例如,當使用中應用程式最小化時)。 在此情況下,訊息會張貼至連結至使用中視窗的訊息佇列。

非系統按鍵訊息可供應用程式視窗使用; DefWindowProc 函式不會對它們執行任何動作。 視窗程式可以捨棄它不需要的任何非系統按鍵訊息。

說明的虛擬密鑰代碼

按鍵訊息的 wParam 參數包含按下或放開之按鍵的虛擬按鍵程序代碼。 視虛擬按鍵程式代碼的值而定,視窗程式會處理或忽略擊鍵訊息。

一般視窗程式只會處理它接收並忽略其餘部分的擊鍵訊息子集。 例如,視窗程式可能只會 處理WM_KEYDOWN 擊鍵訊息,而且只有包含游標移動鍵虛擬密鑰代碼、移動鍵(也稱為控制鍵)和函式按鍵的按鍵。 一般視窗程式不會處理字元鍵的擊鍵訊息。 相反地 ,它會使用 TranslateMessage 函式將訊息轉換成字元訊息。 如需 TranslateMessage 和字元訊息的詳細資訊,請參閱字元訊息

擊鍵訊息旗標

擊鍵訊息的 lParam 參數包含產生訊息之擊鍵的其他資訊。 這項資訊包括重複計數掃描程式代碼、擴充密鑰旗標內容程式代碼先前的索引鍵狀態旗標,以及轉換狀態旗標。 下圖顯示 lParam 參數中這些旗標和值的位置。

the locations of the flags and values in the lparam parameter of a keystroke message

應用程式可以使用下列值,從 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_KEYDOWNWM_SYSKEYDOWN訊息時,系統就會遞增計數,速度比應用程式可以處理這些訊息更快。 當使用者按住足夠長且足以啟動鍵盤的自動重複功能時,通常會發生這種情況。 系統不必將產生的按鍵關閉訊息填入系統消息佇列,而是將訊息合併成單一按鍵關閉訊息,並遞增重複計數。 釋出金鑰無法啟動自動重複功能,因此WM_KEYUPWM_SYSKEYUP訊息的重複計數一律設定為 1。

掃描代碼

Diagram of a Type 4 keyboard with the key locations for each key.

掃描碼是當使用者按下按鍵時,系統所產生的值。 這是一個值,可識別按下的按鍵,不論使用 中的鍵盤配置為何,而不是按鍵所代表的字元。 應用程式通常會忽略掃描代碼。 相反地,它會使用虛擬按鍵程式代碼來解譯擊鍵訊息。

新式鍵盤使用 Human Interface Devices (HID) 規格與電腦通訊。 鍵盤驅動程式 會將從鍵盤傳送的 HID 使用量值轉換為掃描 сode,並將其傳遞至應用程式。

注意

雖然虛擬按鍵碼通常對傳統型應用程式更有用,但當您需要知道按下哪一個按鍵時,您可能需要掃描代碼,而不論目前的 鍵盤配置為何。 例如,WASD (W 為向上、A 為左、S 為向下,而 D 為右)遊戲按鍵系結,可確保美國 QWERTY 或法文 AZERTY 鍵盤版面配置有一致的按鍵形成。

下表列出 Windows 目前可辨識的掃描代碼集。 HID 使用量頁面/HID使用量標識碼/HID使用量名稱值會參考 HID 使用量數據表檔。 索引 鍵位置 值會參考上述鍵盤影像。

Scan 1 Make 程式代碼會在WM_KEYDOWN/WM_KEYUP WM_SYSKEYDOWN//WM_SYSKEYUPWM_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

注意:

  1. Alt+Print 畫面 按鍵擊鍵時會省略 SysRq 鍵掃描代碼
  2. 中斷 按鍵掃描程式碼會在 Control+Pause 按鍵上 省略
  3. 如舊版鍵盤訊息所示
  4. 鍵盤上有按鍵
  5. 按鍵存在於日文鍵盤上
  6. 掃描碼只會在金鑰發行事件中省略

擴充索引鍵旗標

擴充鍵旗標指出按鍵訊息是否源自增強式 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_KEYDOWNWM_SYSKEYDOWN擊鍵訊息,此旗標會設定為 1。 一律會針對WM_KEYUPWM_SYSKEYUP訊息設定為 1。

轉換狀態旗標

轉換狀態旗標會指出按下按鍵或釋放按鍵是否產生擊鍵訊息。 對於WM_KEYDOWNWM_SYSKEYDOWN訊息,此旗標一律設定為0;WM_KEYUP和WM_SYSKEYUP訊息一律設定為1。

字元訊息

擊鍵訊息提供許多按鍵相關信息,但不會提供字元擊鍵的字元碼。 若要擷取字元碼,應用程式必須在其線程訊息迴圈中包含 TranslateMessage 函式。 TranslateMessage 會將WM_KEYDOWNWM_SYSKEYDOWN訊息傳遞至鍵盤配置。 配置會檢查訊息的虛擬密鑰程式代碼,如果它對應至字元密鑰,則會提供對等字元碼(考慮到 SHIFT 和 CAPS LOCK 鍵的狀態)。 然後,它會產生字元訊息,其中包含字元碼,並將訊息放在消息佇列頂端。 訊息迴圈的下一個反覆專案會從佇列中移除字元訊息,並將訊息分派至適當的窗口程式。

本章節涵蓋下列主題:

非系統字元訊息

視窗程式可以接收下列字元訊息:WM_CHARWM_DEADCHAR、WM_SYSCHAR、WM_SYSDEADCHARWM_UNICHAR。 TranslateMessage 函式會在處理WM_KEYDOWN訊息時產生WM_CHARWM_DEADCHAR訊息。 同樣地,它會在處理WM_SYSKEYDOWN訊息時產生WM_SYSCHARWM_SYSDEADCHAR訊息。

處理鍵盤輸入的應用程式通常會忽略除了WM_CHARWM_UNICHAR訊息以外的所有訊息,將任何其他訊息傳遞至 DefWindowProc 函式。 請注意, WM_CHAR 使用 UTF-16(16 位 Unicode 轉換格式)或 ANSI 字元集,而 WM_UNICHAR 一律使用 UTF-32(32 位 Unicode 轉換格式)。 系統會使用WM_SYSCHARWM_SYSDEADCHAR訊息來實作功能表助記鍵。

所有字元訊息的 wParam 參數包含已按下之字元鍵的字元碼。 字元碼的值取決於接收訊息之視窗的窗口類別。 如果使用 RegisterClass 函式的 Unicode 版本來註冊視窗類別,系統就會將 Unicode 字元提供給該類別的所有視窗。 否則,系統會提供 ANSI 字元碼。 如需詳細資訊,請參閱在 Windows 應用程式中註冊視窗類別和使用 UTF-8 代碼頁。

字元訊息之 lParam 參數的內容與已轉譯成產生字元訊息的 lParam 參數內容相同。 如需詳細資訊,請參閱 擊鍵訊息旗標

無效字元訊息

某些非英文鍵盤包含字元鍵,這些按鍵不會自行產生字元。 相反地,它們用來將變音符號新增至後續擊鍵所產生的字元。 這些金鑰稱為 死鍵。 德文鍵盤上的圓環反射鍵是死鍵的範例。 若要輸入由 「o」 組成的字元與周光反射,德文用戶會輸入周光反射鍵,後面接著 「o」 鍵。 具有鍵盤焦點的視窗會收到下列訊息序列:

  1. WM_KEYDOWN
  2. WM_DEADCHAR
  3. WM_KEYUP
  4. WM_KEYDOWN
  5. WM_CHAR
  6. WM_KEYUP

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 函式,從設備驅動器擷取任何密鑰的名稱。

擊鍵和字元翻譯

系統包含數個特殊用途函式,可轉譯各種擊鍵訊息所提供的掃描碼、字元碼和虛擬按鍵碼。 這些函式包括 MapVirtualKeyToAsciiToUnicode 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_ACTI加值稅E 值,立即啟用目前線程的配置 。 應用程式可以使用 KLF_REORDER 值來重新排序版面配置,而不需同時指定 KLF_ACTI加值稅E 值。 載入鍵盤配置時,應用程式應該一律使用 KLF_SUBSTITUTE_OK 值,以確保已選取使用者的喜好設定。

針對多語系支援, LoadKeyboardLayout 函式會提供 KLF_REPLACELANG KLF_NOTELLSHELL 旗標。 KLF_REPLACELANG 旗標會指示函式取代現有的鍵盤配置,而不需要變更語言。 嘗試使用相同語言識別項取代現有的配置,但未指定 KLF_REPLACELANG 是錯誤。 KLF_NOTELLSHELL 旗標可防止函式在新增或取代鍵盤配置時通知殼層。 這對於在連續一系列呼叫中新增多個版面配置的應用程式很有用。 這個旗標應該用於最後一次呼叫的所有專案。

UnloadKeyboardLayout 函式會受到限制,因為它無法卸載系統預設輸入語言。 這可確保使用者一律有一個配置可供輸入文字使用殼層和檔案系統所使用的相同字元集。