キーボード入力の概要
アプリケーションでは、キーボードとマウスからのユーザー入力を受け入れる必要があります。 アプリケーションは、ウィンドウに投稿されたメッセージの形式でキーボード入力を受け取ります。
キーボード入力モデル
システムは、現在のキーボードに適したキーボード デバイス ドライバーをインストールすることで、アプリケーションに対してデバイスに依存しないキーボード サポートを提供します。 システムは、ユーザーまたはアプリケーションによって現在選択されている言語固有のキーボード レイアウトを使用して、言語に依存しないキーボード サポートを提供します。 キーボード デバイス ドライバーは、キーボードからスキャン コードを受け取ります。このコードはキーボード レイアウトに送信され、そこでメッセージに変換され、アプリケーション内の適切なウィンドウに投稿されます。
キーボードの各キーに割り当てられるのは、"スキャン コード" と呼ばれる一意の値です。これは、キーボード上のキーのデバイス依存識別子です。 キーボードは、ユーザーがキーを入力すると 2 つのスキャン コードを生成します。1 つはユーザーがキーを押したときに、もう 1 つはユーザーがキーを解放したときに生成します。
キーボード デバイス ドライバーはスキャン コードを解釈し、それを "仮想キー コード" (キーの目的を識別する、システムによって定義されたデバイスに依存しない値) に変換 (マップ) します。 スキャン コードを変換すると、キーボード レイアウトによって、スキャン コード、仮想キー コード、キーストロークに関するその他の情報を含むメッセージが作成され、メッセージがシステム メッセージ キューに配置されます。 システムは、システム メッセージ待ち行列からメッセージを削除し、それを適切なスレッドのメッセージ待ち行列に投稿します。 最終的に、スレッドのメッセージ ループはメッセージを削除し、処理のために適切なウィンドウ プロシージャに渡します。 次の図は、キーボード入力モデルを示しています。
キーボード フォーカスとアクティブ化
システムは、キーボード フォーカスを持つウィンドウを作成したフォアグラウンド スレッドのメッセージ キューにキーボード メッセージを投稿します。 "キーボード フォーカス" は、ウィンドウの一時的なプロパティです。 システムは、ユーザーの指示に従ってキーボード フォーカスをあるウィンドウから別のウィンドウにシフトすることで、ディスプレイ上のすべてのウィンドウ間でキーボードを共有します。 キーボード フォーカスを持つウィンドウは、フォーカスが別のウィンドウに変わるまで、すべてのキーボード メッセージを (ウィンドウを作成したスレッドのメッセージ キューから) 受け取ります。
スレッドは 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 パラメーター内のこれらのフラグの場所と値を示しています。
アプリケーションでは、次の値を使用して 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 に設定されます。
スキャン コード
スキャン コードは、ユーザーがキーを押したときにシステムによって生成される値です。 これは、キーで表される文字ではなく、アクティブなキーボード レイアウトに関係なく、押されたキーを特定する値です。 通常、アプリケーションはスキャン コードを無視します。 代わりに、仮想キー コードを使ってキーストローク メッセージを解釈します。
最新のキーボードは、ヒューマン インターフェイス デバイス (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 |
注:
- SysRq キー スキャン コードは、Alt + Print Screen キーストロークで生成されます
- Break キー スキャン コードは、Ctrl + Pause キーストロークで生成されます
- レガシ キーボード メッセージで見られます
- このキーはブラジル語キーボードにあります
- このキーは日本語キーボードにあります
- このスキャン コードは、キーを放すイベントでのみ生成される
拡張キー フラグ
拡張キー フラグは、キーストローク メッセージが拡張 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_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 パラメーターには、分音記号を含む文字の文字コードが含まれています。 後続のキーストロークで、分音記号と組み合わせることができない文字が生成された場合、システムは 2 つの WM_CHAR メッセージを生成します。 最初のメッセージの wParam パラメーターには、分音記号の文字コードが含まれています。2 番目のメッセージの wParam パラメーターには、後続の文字キーの文字コードが含まれています。
TranslateMessage 関数は、システム デッド キー (Alt キーと組み合わせて押されたデッド キー) からの WM_SYSKEYDOWN メッセージを処理すると、WM_SYSDEADCHAR メッセージを生成します。 アプリケーションは通常、WM_SYSDEADCHAR メッセージを無視します。
キーの状態
キーボード メッセージの処理中に、アプリケーションでは、現在のメッセージを生成したキー以外の別のキーの状態を確認する必要がある場合があります。 たとえば、ユーザーが Shift キーを押しながら END キーを押してテキスト ブロックを選択できるようにするワープロ アプリケーションでは、END キーからのキーストローク メッセージを受信したときは常に Shift キーの状態をチェックする必要があります。 アプリケーションでは GetKeyState 関数を使用して、現在のメッセージが生成された時点の仮想キーの状態を確認できます。GetAsyncKeyState 関数を使用して、仮想キーの現在の状態を取得できます。
キーボード レイアウトでは、名前の一覧が保持されます。 1 つの文字を生成するキーの名前は、そのキーによって生成される文字と同じです。 TAB キーや ENTER キーなどの文字以外のキーの名前は、文字列として格納されます。 アプリケーションは、GetKeyNameText 関数を呼び出すことによって、デバイス ドライバーから任意のキーの名前を取得できます。
キーストロークと文字変換
システムには、さまざまなキーストローク メッセージによって提供されるスキャン コード、文字コード、および仮想キー コードを変換するいくつかの特別な目的の関数が用意されています。 これらの関数には、MapVirtualKey、ToAscii、ToUnicode、VkKeyScan などがあります。
さらに、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 番目のパラメーター rgInputs は INPUT 構造体の配列であり、それぞれが入力イベントの種類とそのイベントに関する追加情報を記述します。 最後のパラメーター cbSize は、INPUT 構造体のサイズ (バイト単位) を受け入れます。
SendInput 関数は、シミュレートされた一連の入力イベントをデバイスの入力ストリームに挿入することによって機能します。 その効果は、keybd_event または mouse_event 関数を繰り返し呼び出すことと似ていますが、シミュレートされたイベントと他の入力イベントが混在しないようにシステムによって保証される点が異なっています。 呼び出しが完了すると、戻り値は、正常に再生された入力イベントの数を示します。 この値が 0 の場合、入力はブロックされたということです。
SendInput 関数は、キーボードの現在の状態をリセットしません。 したがって、この関数を呼び出したときにユーザーが何らかのキーを押していた場合は、この関数によって生成されるイベントに干渉する可能性があります。 干渉の可能性が懸念される場合は、GetAsyncKeyState 関数を使用してキーボードの状態をチェックし、必要に応じて修正します。
言語、ロケール、キーボード レイアウト
"言語" は、英語、フランス語、日本語などの自然言語です。 "サブ言語" は、英国や米国で話される英語のサブ言語など、特定の地域で話される自然言語のバリアントです。 アプリケーションでは、言語識別子と呼ばれる値を使用して、言語とサブ言語を一意に識別します。
アプリケーションでは通常、"ロケール" を使用して、入力と出力を処理する言語を設定します。 たとえば、キーボードのロケールを設定すると、キーボードによって生成される文字値に影響します。 ディスプレイまたはプリンターのロケールを設定すると、表示または印刷されるグリフに影響します。 アプリケーションでは、キーボード レイアウトを読み込んで使用して、キーボードのロケールを設定します。 指定したロケールをサポートするフォントを選択して、ディスプレイまたはプリンターのロケールを設定します。
キーボード レイアウトは、キーボード上のキーの物理的な位置を指定するだけでなく、それらのキーを押すことによって生成される文字値も決定します。 各レイアウトは、現在の入力言語を識別し、どの文字値がどのキーとキーの組み合わせによって生成されるかを決定します。
すべてのキーボード レイアウトには、レイアウトと言語を識別する対応するハンドルがあります。 ハンドルの下位ワードは言語識別子です。 上位ワードは、物理レイアウトを指定するデバイス ハンドル、または既定の物理レイアウトを示す 0 です。 ユーザーは、任意の入力言語を物理レイアウトに関連付けることができます。 たとえば、フランス語で非常に頻繁に作業する英語を話すユーザーは、キーボードの物理的なレイアウトを変更することなく、キーボードの入力言語をフランス語に設定できます。 つまり、ユーザーは使い慣れた英語レイアウトを使用してフランス語でテキストを入力できます。
一般に、アプリケーションが入力言語を直接操作することは想定されていません。 代わりに、ユーザーが言語とレイアウトの組み合わせを設定してから、それらを切り替えます。 ユーザーが別の言語でマークされたテキストをクリックすると、アプリケーションは 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 関数は、システムの既定の入力言語をアンロードできないという点で制限されています。 これにより、シェルおよびファイル システムで使用されているのと同じ文字セットを使用して、ユーザーがテキスト入力に使用できるレイアウトが常に 1 つ存在するようになります。