キーボード入力の概要

アプリケーションでは、キーボードとマウスからのユーザー入力を受け入れる必要があります。 アプリケーションは、ウィンドウに投稿されたメッセージの形式でキーボード入力を受け取ります。

キーボード入力モデル

システムは、現在のキーボードに適したキーボード デバイス ドライバーをインストールすることで、アプリケーションに対してデバイスに依存しないキーボード サポートを提供します。 システムは、ユーザーまたはアプリケーションによって現在選択されている言語固有のキーボード レイアウトを使用して、言語に依存しないキーボード サポートを提供します。 キーボード デバイス ドライバーは、キーボードからスキャン コードを受け取ります。このコードはキーボード レイアウトに送信され、そこでメッセージに変換され、アプリケーション内の適切なウィンドウに投稿されます。

キーボードの各キーに割り当てられるのは、"スキャン コード" と呼ばれる一意の値です。これは、キーボード上のキーのデバイス依存識別子です。 キーボードは、ユーザーがキーを入力すると 2 つのスキャン コードを生成します。1 つはユーザーがキーを押したときに、もう 1 つはユーザーがキーを解放したときに生成します。

キーボード デバイス ドライバーはスキャン コードを解釈し、それを "仮想キー コード" (キーの目的を識別する、システムによって定義されたデバイスに依存しない値) に変換 (マップ) します。 スキャン コードを変換すると、キーボード レイアウトによって、スキャン コード、仮想キー コード、キーストロークに関するその他の情報を含むメッセージが作成され、メッセージがシステム メッセージ キューに配置されます。 システムは、システム メッセージ待ち行列からメッセージを削除し、それを適切なスレッドのメッセージ待ち行列に投稿します。 最終的に、スレッドのメッセージ ループはメッセージを削除し、処理のために適切なウィンドウ プロシージャに渡します。 次の図は、キーボード入力モデルを示しています。

keyboard input processing model

キーボード フォーカスとアクティブ化

システムは、キーボード フォーカスを持つウィンドウを作成したフォアグラウンド スレッドのメッセージ キューにキーボード メッセージを投稿します。 "キーボード フォーカス" は、ウィンドウの一時的なプロパティです。 システムは、ユーザーの指示に従ってキーボード フォーカスをあるウィンドウから別のウィンドウにシフトすることで、ディスプレイ上のすべてのウィンドウ間でキーボードを共有します。 キーボード フォーカスを持つウィンドウは、フォーカスが別のウィンドウに変わるまで、すべてのキーボード メッセージを (ウィンドウを作成したスレッドのメッセージ キューから) 受け取ります。

スレッドは GetFocus 関数を呼び出して、現在キーボード フォーカスを持っているウィンドウ (存在する場合) を判別できます。 スレッドは SetFocus 関数を呼び出すことによって、いずれかのウィンドウにキーボード フォーカスを与えることができます。 キーボードフォーカスがあるウィンドウから別のウィンドウに変更されると、フォーカスを失ったウィンドウに WM_KILLFOCUS メッセージが送信され、フォーカスを取得したウィンドウに WM_SETFOCUS メッセージが送信されます。

キーボード フォーカスの概念は、アクティブ ウィンドウの概念に関連しています。 "アクティブ ウィンドウ" は、ユーザーが現在操作している最上位のウィンドウです。 キーボード フォーカスのあるウィンドウは、アクティブ ウィンドウまたはアクティブ ウィンドウの子ウィンドウです。 ユーザーがアクティブ ウィンドウを識別できるように、システムはそれを Z オーダーの一番上に配置し、タイトル バー(存在する場合) と境界線を強調表示します。

ユーザーは、トップレベル ウィンドウをクリックするか、Alt+TAB キーまたは Alt+ESC キーの組み合わせを使用して選択するか、タスク一覧から選択することで、トップレベル ウィンドウをアクティブ化できます。 スレッドは SetActiveWindow 関数を使用してトップレベル ウィンドウをアクティブ化できます。 作成したトップレベル ウィンドウがアクティブかどうかを判断するには、GetActiveWindow 関数を使用します。

1 つのウィンドウが非アクティブ化され、別のウィンドウがアクティブになると、システムは WM_ACTIVATE メッセージを送信します。 wParam パラメーターの下位ワードは、ウィンドウが非アクティブ化されている場合は 0、アクティブ化されている場合は 0 以外です。 既定のウィンドウ プロシージャは 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 パラメーター内のこれらのフラグの場所と値を示しています。

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

アプリケーションでは、次の値を使用して lParam の上位ワードからキーストローク フラグを取得できます。

Value 説明
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 メッセージをアプリケーションで処理できる以上に速く生成した場合にカウントをインクリメントします。 これは多くの場合、ユーザーが長い間キーを押したままにしてキーボードの自動繰り返し機能が開始された場合に発生します。 システム メッセージ キューに結果のキーダウン メッセージを入力する代わりに、システムはメッセージを 1 つのキーダウン メッセージに結合し、繰り返し回数をインクリメントします。 キーを解放して自動繰り返し機能を開始することはできないため、WM_KEYUP メッセージと WM_SYSKEYUP メッセージの繰り返し回数は常に 1 に設定されます。

スキャン コード

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

スキャン コードは、ユーザーがキーを押したときにシステムによって生成される値です。 これは、キーで表される文字ではなく、アクティブなキーボード レイアウトに関係なく、押されたキーを特定する値です。 通常、アプリケーションはスキャン コードを無視します。 代わりに、仮想キー コードを使ってキーストローク メッセージを解釈します。

最新のキーボードは、ヒューマン インターフェイス デバイス (HID) 仕様を使ってコンピューターと通信しています。 キーボード ドライバーは、キーボードから送信された HID 使用法の報告値をスキャン コードに変換し、アプリケーションに渡します。

Note

通常、デスクトップ アプリケーションにとっては仮想キー コードの方が役立ちますが、現在のキーボード レイアウトに関係なく、どのキーが押されたかを知る必要がある一部のケースでは、スキャン コードが必要になる場合があります。 たとえば、ゲーム用の WASD (W が上、A が左、S が下、D が右) キー バインドでは、英語 QWERTY またはフランス語 AZERTY キーボード レイアウトで一貫したキーの構成が保証されます。

次の表に、Windows で現在認識される一連のスキャン コードを示します。 「HID 使用法ページ」/「HID 使用法 ID」/「HID 使用法名」の値は、「HID Usage Tables」(HID 使用法テーブル) のドキュメントを参照しています。 「キーの場所」の値は、上記のキーボード画像を参照しています。

Scan 1 Make コードは、WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP および WM_INPUT メッセージで配信されます。

HID 使用法ページ名 HID 使用法の名前 HID 使用法ページ HID 使用法の ID Scan 1 Make キーの場所
汎用デスクトップ システム電源ダウン 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 と @ 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 とアンパサンド 0x0007 0x0024 0x0008 8
キーボード/キーパッド キーボードの 8 とアスタリスク 0x0007 0x0025 0x0009 9
キーボード/キーパッド キーボードの 9 と左角かっこ 0x0007 0x0026 0x000A 10
キーボード/キーパッド キーボードの 0 と右角かっこ 0x0007 0x0027 0x000B 11
キーボード/キーパッド キーボードの Return と Enter 0x0007 0x0028 0x001C 43
キーボード/キーパッド キーボードの Esc 0x0007 0x0029 0x0001 110
キーボード/キーパッド キーボードの Delete 0x0007 0x002A 0x000E 15
キーボード/キーパッド キーボードの Tab 0x0007 0x002B 0x000F 16
キーボード/キーパッド キーボードの Space キー 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
キーボード/キーパッド キーボードのグレーブ アクセントとチルダ 0x0007 0x0035 0x0029 1
キーボード/キーパッド キーボードのコンマ 0x0007 0x0036 0x0033 53
キーボード/キーパッド キーボードのピリオド 0x0007 0x0037 0x0034 54
キーボード/キーパッド キーボードの疑問符 0x0007 0x0038 0x0035 55
キーボード/キーパッド キーボードの Caps Lock 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
キーボード/キーパッド キーボードの Scroll Lock 0x0007 0x0047 0x0046 125
キーボード/キーパッド キーボードの Pause 0x0007 0x0048 0xE11D45
0xE046 *注 2
0x0045 *注 3
126
キーボード/キーパッド キーボードの Insert 0x0007 0x0049 0xE052 75
キーボード/キーパッド キーボードの Home 0x0007 0x004A 0xE047 80
キーボード/キーパッド キーボードの PageUp 0x0007 0x004B 0xE049 85
キーボード/キーパッド キーボードの Delete Forward 0x0007 0x004C 0xE053 76
キーボード/キーパッド キーボードの End 0x0007 0x004D 0xE04F 81
キーボード/キーパッド キーボードの PageDown 0x0007 0x004E 0xE051 86
キーボード/キーパッド キーボードの右矢印 0x0007 0x004F 0xE04D 89
キーボード/キーパッド キーボードの左矢印 0x0007 0x0050 0xE04B 79
キーボード/キーパッド キーボードの下矢印 0x0007 0x0051 0xE050 84
キーボード/キーパッド キーボードの上矢印 0x0007 0x0052 0xE048 83
キーボード/キーパッド キーパッドの NumLock と 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 と End 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 と Home 0x0007 0x005F 0x0047 91
キーボード/キーパッド キーパッドの 8 と上矢印 0x0007 0x0060 0x0048 96
キーボード/キーパッド キーパッドの 9 と PageUp 0x0007 0x0061 0x0049 101
キーボード/キーパッド キーパッドの 0 と Insert 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
キーボード/キーパッド キーボード International1 0x0007 0x0087 0x0073 56 *注 4、5
キーボード/キーパッド キーボード International2 0x0007 0x0088 0x0070 133 *注 5
キーボード/キーパッド キーボード International3 0x0007 0x0089 0x007D 14 *注 5
キーボード/キーパッド キーボード International4 0x0007 0x008A 0x0079 132 *注 5
キーボード/キーパッド キーボード International5 0x0007 0x008B 0x007B 131 *注 5
キーボード/キーパッド キーボード International6 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
キーボード/キーパッド キーボードの左 Ctrl 0x0007 0x00E0 0x001D 58
キーボード/キーパッド キーボードの左 Shift 0x0007 0x00E1 0x002A 44
キーボード/キーパッド キーボードの左 Alt 0x0007 0x00E2 0x0038 60
キーボード/キーパッド キーボードの左 GUI 0x0007 0x00E3 0xE05B 127
キーボード/キーパッド キーボードの右 Ctrl 0x0007 0x00E4 0xE01D 64
キーボード/キーパッド キーボードの右 Shift 0x0007 0x00E5 0x0036 57
キーボード/キーパッド キーボードの右 Alt 0x0007 0x00E6 0xE038 62
キーボード/キーパッド キーボードの右 GUI 0x0007 0x00E7 0xE05C 128
コンシューマー 次のトラックをスキャンする 0x000C 0x00B5 0xE019
コンシューマー 前のトラックをスキャンする 0x000C 0x00B6 0xE010
コンシューマー Stop 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 ホーム 0x000C 0x0223 0xE032
コンシューマー AC 戻る 0x000C 0x0224 0xE06A
コンシューマー AC 進む 0x000C 0x0225 0xE069
コンシューマー AC 停止 0x000C 0x0226 0xE068
コンシューマー AC 更新 0x000C 0x0227 0xE067
コンシューマー AC ブックマーク 0x000C 0x022A 0xE066

注:

  1. SysRq キー スキャン コードは、Alt + Print Screen キーストロークで生成されます
  2. Break キー スキャン コードは、Ctrl + Pause キーストロークで生成されます
  3. レガシ キーボード メッセージで見られます
  4. このキーはブラジル語キーボードにあります
  5. このキーは日本語キーボードにあります
  6. このスキャン コードは、キーを放すイベントでのみ生成されます

拡張キー フラグ

拡張キー フラグは、キーストローク メッセージが拡張 101/102 キーのキーボード上の追加キーの 1 つから発生したかどうかを示します。 拡張キーは、キーボードの右側にある Alt キーと Ctrl キー、テンキーの左側にまとめて配置されている INS、DEL、HOME、END、PAGE UP、PAGE DOWN、および方向キー、NUM LOCK キー、BREAK (Ctrl+PAUSE) キー、PRINT SCRN キー、テンキーの除算 (/) キーと ENTER キーで構成されます。 右側の Shift キーは拡張キーとは見なされず、代わりに別のスキャン コードがあります。

指定した場合、スキャン コードは 2 バイトのシーケンスで構成され、最初のバイトの値は 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_CHARWM_DEADCHARWM_SYSCHARWM_SYSDEADCHARWM_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" キーを入力します。 キーボード フォーカスのあるウィンドウは、次の一連のメッセージを受信します。

  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 パラメーターには、分音記号を含む文字の文字コードが含まれています。 後続のキーストロークで、分音記号と組み合わせることができない文字が生成された場合、システムは 2 つの WM_CHAR メッセージを生成します。 最初のメッセージの wParam パラメーターには、分音記号の文字コードが含まれています。2 番目のメッセージの wParam パラメーターには、後続の文字キーの文字コードが含まれています。

TranslateMessage 関数は、システム デッド キー (Alt キーと組み合わせて押されたデッド キー) からの WM_SYSKEYDOWN メッセージを処理すると、WM_SYSDEADCHAR メッセージを生成します。 アプリケーションは通常、WM_SYSDEADCHAR メッセージを無視します。

キーの状態

キーボード メッセージの処理中に、アプリケーションでは、現在のメッセージを生成したキー以外の別のキーの状態を確認する必要がある場合があります。 たとえば、ユーザーが Shift キーを押しながら END キーを押してテキスト ブロックを選択できるようにするワープロ アプリケーションでは、END キーからのキーストローク メッセージを受信したときは常に Shift キーの状態をチェックする必要があります。 アプリケーションでは GetKeyState 関数を使用して、現在のメッセージが生成された時点の仮想キーの状態を確認できます。GetAsyncKeyState 関数を使用して、仮想キーの現在の状態を取得できます。

キーボード レイアウトでは、名前の一覧が保持されます。 1 つの文字を生成するキーの名前は、そのキーによって生成される文字と同じです。 TAB キーや ENTER キーなどの文字以外のキーの名前は、文字列として格納されます。 アプリケーションは、GetKeyNameText 関数を呼び出すことによって、デバイス ドライバーから任意のキーの名前を取得できます。

キーストロークと文字変換

システムには、さまざまなキーストローク メッセージによって提供されるスキャン コード、文字コード、および仮想キー コードを変換するいくつかの特別な目的の関数が用意されています。 これらの関数には、MapVirtualKeyToAsciiToUnicodeVkKeyScan などがあります。

さらに、Microsoft Rich Edit 3.0 では HexToUnicode IME がサポートされています。これにより、ユーザーはホット キーを使用して 16 進文字と Unicode 文字間の変換を実行できます。 つまり、Microsoft Rich Edit 3.0 がアプリケーションに組み込まれている場合、アプリケーションは HexToUnicode IME の機能を継承します。

ホット キーのサポート

"ホット キー" とは、システムがキュー内の既存のメッセージをバイパスし、スレッドのメッセージ キューの先頭に配置する WM_HOTKEY メッセージを生成するキーの組み合わせです。 アプリケーションでは、ホット キーを使用して、ユーザーから優先度の高いキーボード入力を取得します。 たとえば、Ctrl+C のキーの組み合わせで構成されるホット キーを定義することで、アプリケーションでは、ユーザーが時間のかかっている操作をキャンセルできるようにすることが可能です。

ホット キーを定義するために、アプリケーションは、WM_HOTKEY メッセージを生成するキーの組み合わせ、メッセージを受信するウィンドウへのハンドル、ホット キーの識別子を指定して、RegisterHotKey 関数を呼び出します。 ユーザーがホット キーを押すと、ウィンドウを作成したスレッドのメッセージ キューに 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 では、5 つのボタンを持つマウスである Microsoft IntelliMouse Explorer もサポートされています。 2 つの追加ボタンは、ブラウザーの進むナビゲーションと戻るナビベーションをサポートします。 詳細については、「XBUTTON」を参照してください。

入力のシミュレート

中断されない一連のユーザー入力イベントをシミュレートするには、SendInput 関数を使用します。 この関数は 3 つのパラメーターを受け取ります。 最初のパラメーター cInputs は、シミュレートされる入力イベントの数を示します。 2 番目のパラメーター rgInputsINPUT 構造体の配列であり、それぞれが入力イベントの種類とそのイベントに関する追加情報を記述します。 最後のパラメーター cbSize は、INPUT 構造体のサイズ (バイト単位) を受け入れます。

SendInput 関数は、シミュレートされた一連の入力イベントをデバイスの入力ストリームに挿入することによって機能します。 その効果は、keybd_event または mouse_event 関数を繰り返し呼び出すことと似ていますが、シミュレートされたイベントと他の入力イベントが混在しないようにシステムによって保証される点が異なっています。 呼び出しが完了すると、戻り値は、正常に再生された入力イベントの数を示します。 この値が 0 の場合、入力はブロックされたということです。

SendInput 関数は、キーボードの現在の状態をリセットしません。 したがって、この関数を呼び出したときにユーザーが何らかのキーを押していた場合は、この関数によって生成されるイベントに干渉する可能性があります。 干渉の可能性が懸念される場合は、GetAsyncKeyState 関数を使用してキーボードの状態をチェックし、必要に応じて修正します。

言語、ロケール、キーボード レイアウト

"言語" は、英語、フランス語、日本語などの自然言語です。 "サブ言語" は、英国や米国で話される英語のサブ言語など、特定の地域で話される自然言語のバリアントです。 アプリケーションでは、言語識別子と呼ばれる値を使用して、言語とサブ言語を一意に識別します。

アプリケーションでは通常、"ロケール" を使用して、入力と出力を処理する言語を設定します。 たとえば、キーボードのロケールを設定すると、キーボードによって生成される文字値に影響します。 ディスプレイまたはプリンターのロケールを設定すると、表示または印刷されるグリフに影響します。 アプリケーションでは、キーボード レイアウトを読み込んで使用して、キーボードのロケールを設定します。 指定したロケールをサポートするフォントを選択して、ディスプレイまたはプリンターのロケールを設定します。

キーボード レイアウトは、キーボード上のキーの物理的な位置を指定するだけでなく、それらのキーを押すことによって生成される文字値も決定します。 各レイアウトは、現在の入力言語を識別し、どの文字値がどのキーとキーの組み合わせによって生成されるかを決定します。

すべてのキーボード レイアウトには、レイアウトと言語を識別する対応するハンドルがあります。 ハンドルの下位ワードは言語識別子です。 上位ワードは、物理レイアウトを指定するデバイス ハンドル、または既定の物理レイアウトを示す 0 です。 ユーザーは、任意の入力言語を物理レイアウトに関連付けることができます。 たとえば、フランス語で非常に頻繁に作業する英語を話すユーザーは、キーボードの物理的なレイアウトを変更することなく、キーボードの入力言語をフランス語に設定できます。 つまり、ユーザーは使い慣れた英語レイアウトを使用してフランス語でテキストを入力できます。

一般に、アプリケーションが入力言語を直接操作することは想定されていません。 代わりに、ユーザーが言語とレイアウトの組み合わせを設定してから、それらを切り替えます。 ユーザーが別の言語でマークされたテキストをクリックすると、アプリケーションは ActivateKeyboardLayout 関数を呼び出して、その言語のユーザーの既定のレイアウトをアクティブ化します。 ユーザーがアクティブな一覧にない言語でテキストを編集した場合、アプリケーションは言語を指定して LoadKeyboardLayout 関数を呼び出して、その言語に基づいたレイアウトを取得できます。

ActivateKeyboardLayout 関数は、現在のタスクの入力言語を設定します。 hkl パラメーターには、キーボード レイアウトへのハンドルまたはゼロ拡張言語識別子を指定できます。 キーボード レイアウト ハンドルは、LoadKeyboardLayout 関数または GetKeyboardLayoutList 関数から取得できます。 HKL_NEXTHKL_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 関数は、システムの既定の入力言語をアンロードできないという点で制限されています。 これにより、シェルおよびファイル システムで使用されているのと同じ文字セットを使用して、ユーザーがテキスト入力に使用できるレイアウトが常に 1 つ存在するようになります。