アプリケーションでは、キーボードとマウスからのユーザー入力を受け入れる必要があります。 アプリケーションは、ウィンドウに投稿されたメッセージの形式でキーボード入力を受け取ります。
キーボード入力モデル
システムは、現在のキーボードに適したキーボード デバイス ドライバーをインストールすることで、アプリケーションのデバイスに依存しないキーボード サポートを提供します。 システムは、ユーザーまたはアプリケーションによって現在選択されている言語固有のキーボード レイアウトを使用して、言語に依存しないキーボード サポートを提供します。 キーボード デバイス ドライバーは、キーボードからスキャン コードを受け取り、キーボード レイアウトに送信され、メッセージに変換され、アプリケーション内の適切なウィンドウに投稿されます。
キーボードの各キーに割り当てられるのは、 スキャン コードと呼ばれる一意の値であり、キーボードのキーのデバイスに依存する識別子です。 キーボードは、ユーザーがキーを入力すると 2 つのスキャン コードを生成します。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 メッセージを連続して生成します。 その後、ユーザーがキーを解放すると、1 つの WM_KEYUP または WM_SYSKEYUP メッセージが生成されます。
このセクションは、次のトピックで構成されています。
システムキーストロークと非システムキーストローク
システムは、システムキーストロークと非システムキーストロークを区別します。 システムキーストロークは、システムキーストロークメッセージ、 WM_SYSKEYDOWN および WM_SYSKEYUPを生成します。 非システム キーストロークでは、非システム キーストローク メッセージ、 WM_KEYDOWN 、 およびWM_KEYUPが生成されます。
ウィンドウ プロシージャがシステム キーストローク メッセージを処理する必要がある場合は、メッセージの処理後にプロシージャが DefWindowProc 関数に渡されることを確認します。 それ以外の場合、ウィンドウにキーボード フォーカスがある場合は常に 、Alt キーに関連するすべてのシステム操作が無効になります。 つまり、ユーザーはウィンドウのメニューやシステム メニューにアクセスしたり、 Alt + Esc キーまたは Alt + Tab キーストロークを使用して別のウィンドウをアクティブ化したりすることはできません。
システム キーストローク メッセージは、主にアプリケーションではなくシステムで使用されます。 システムはそれらを使用して、組み込みのキーボード インターフェイスをメニューに提供し、ユーザーがアクティブなウィンドウを制御できるようにします。 システム キーストローク メッセージは、ユーザーが Alt キーと組み合わせてキーを入力したとき、またはユーザーが入力したウィンドウにキーボード フォーカスがない場合 (アクティブなアプリケーションが最小化されている場合など) に生成されます。 この場合、メッセージは、アクティブ ウィンドウに接続されているメッセージ キューにポストされます。
非システム キーストローク メッセージは、アプリケーション ウィンドウで使用されます。 DefWindowProc 関数では何も行われません。 ウィンドウ プロシージャは、不要なシステムキーストロークメッセージを破棄できます。
Virtual-Key コードについての説明
キーストローク メッセージの wParam パラメーターには、押されたキーまたは解放されたキーの 仮想キー コード が含まれています。 ウィンドウ プロシージャは、仮想キー コードの値に応じて、キーストローク メッセージを処理または無視します。
一般的なウィンドウ プロシージャは、受信したキーストローク メッセージのごく一部のみを処理し、残りは無視します。 たとえば、ウィンドウ プロシージャは 、WM_KEYDOWN キーストローク メッセージのみを処理し、カーソル移動キー、シフト キー (制御キーとも呼ばれます)、およびファンクション キーの仮想キー コードを含むメッセージのみを処理できます。 一般的なウィンドウ プロシージャでは、文字キーからのキーストローク メッセージは処理されません。 代わりに、 TranslateMessage 関数を使用してメッセージを文字メッセージに変換します。 TranslateMessage と文字メッセージの詳細については、「文字メッセージ」を参照してください。
キーストローク メッセージ フラグ
キーストローク メッセージの lParam パラメーターには、メッセージを生成したキーストロークに関する追加情報が含まれています。 この情報には、 繰り返し数、 スキャン コード、 拡張キー フラグ、 コンテキスト コード、前の キー状態フラグ、 および遷移状態フラグが含まれます。 次の図は、これらのフラグの場所と lParam パラメーターの値を示しています。
アプリケーションでは、次の値を使用して 、lParam の上位ワードからキーストローク フラグを取得できます。
価値 | 説明 |
---|---|
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 使用法の値をスキャンコードに変換し、それをアプリケーションに渡します。
注
通常、仮想キー コードはデスクトップ アプリケーションにとってより便利ですが、現在の キーボード レイアウトに関係なく、どのキーが押されているかを知る必要がある場合、スキャン コードが必要になる場合があります。 たとえば、ゲームの WASD (W が上、A が左、S がダウン、D が右) のキー バインドです。 これにより、US QWERTY または フランス語の AZERTY キーボード レイアウト全体で一貫したキーの形成が保証されます。
次の表に、Windows で現在認識されているスキャン コードのセットを示します。 HID 使用状況ページ/HID 使用状況 ID/HID 使用法名の 値は、 HID 使用法テーブル ドキュメントを参照します。 キーの場所の値は、上記のキーボード イメージを参照します。
Scan 1 Make コードは、WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUPおよびWM_INPUTメッセージで配信されます。
HID 用途ページ名 | HID 使用法名 | HID の [使用状況] ページ | HID 使用状況 ID | スキャン 1 メイク | キー位置 |
---|---|---|---|---|---|
汎用デスクトップ | システム電源ダウン | 0x0001 | 0x0081 | 0xE05E | |
汎用デスクトップ | システム スリープ | 0x0001 | 0x0082 | 0xE05F | |
汎用デスクトップ | システム ウェイク アップ | 0x0001 | 0x0083 | 0xE063 | |
キーボード/キーパッド | エラーロールオーバー | 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 | 二十四 |
キーボード/キーパッド | キーボード J | 0x0007 | 0x000D | 0x0024 | 37 |
キーボード/キーパッド | キーボード K | 0x0007 | 0x000E | 0x0025 | 三十八 |
キーボード/キーパッド | キーボード L | 0x0007 | 0x000F | 0x0026 | 39 |
キーボード/キーパッド | キーボード M | 0x0007 | 0x0010 | 0x0032 | 52 |
キーボード/キーパッド | キーボード N | 0x0007 | 0x0011 | 0x0031 | 51 |
キーボード/キーパッド | キーボード O | 0x0007 | 0x0012 | 0x0018 | 二十五 |
キーボード/キーパッド | キーボード P | 0x0007 | 0x0013 | 0x0019 | 26 |
キーボード/キーパッド | キーボード Q | 0x0007 | 0x0014 | 0x0010 | 十七 |
キーボード/キーパッド | キーボード 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 と Bang | 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 とアンパサンド | 0x0007 | 0x0024 | 0x0008 | 8 |
キーボード/キーパッド | キーボード 8 と星 | 0x0007 | 0x0025 | 0x0009 | 9 |
キーボード/キーパッド | キーボード 9 と左角括弧 | 0x0007 | 0x0026 | 0x000A | 10 |
キーボード/キーパッド | キーボード0と右ブラケット | 0x0007 | 0x0027 | 0x000B | 11 |
キーボード/キーパッド | キーボード リターン エンターキー | 0x0007 | 0x0028 | 0x001C | 43 |
キーボード/キーパッド | キーボード エスケープ | 0x0007 | 0x0029 | 0x0001 | 110 |
キーボード/キーパッド | キーボードの削除 | 0x0007 | 0x002A | 0x000E | 15 |
キーボード/キーパッド | キーボードタブ | 0x0007 | 0x002B | 0x000F | 16 |
キーボード/キーパッド | キーボードの Space キー | 0x0007 | 0x002C | 0x0039 | 61 |
キーボード/キーパッド | キーボードダッシュとアンダースコア | 0x0007 | 0x002D | 0x000C | 12 |
キーボード/キーパッド | キーボードの「=」キーと「+」キー | 0x0007 | 0x002E | 0x000D | 13 |
キーボード/キーパッド | キーボード左波括弧 | 0x0007 | 0x002F | 0x001A | 二十七 |
キーボード/キーパッド | キーボード右波括弧 | 0x0007 | 0x0030 | 0x001B | 28 |
キーボード/キーパッド | キーボードのバックスラッシュとパイプ | 0x0007 | 0x0031 | 0x002B | 二十九 |
キーボード/キーパッド | 非米国用キーボードのハッシュとチルダ | 0x0007 | 0x0032 | 0x002B | 42 |
キーボード/キーパッド | キーボードのセミコロンとコロン | 0x0007 | 0x0033 | 0x0027 | 40 |
キーボード/キーパッド | キーボードアポストロフィと二重引用符 | 0x0007 | 0x0034 | 0x0028 | 41 |
キーボード/キーパッド | キーボードグレーブ・アクセントとチルダ | 0x0007 | 0x0035 | 0x0029 | 1 |
キーボード/キーパッド | キーボードコンマと LessThan | 0x0007 | 0x0036 | 0x0033 | 53 |
キーボード/キーパッド | キーボードのピリオドと GreaterThan | 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 |
キーボード/キーパッド | キーボード印刷画面 | 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 |
キーボード/キーパッド | キーボード ページアップ | 0x0007 | 0x004B | 0xE049 | 85 |
キーボード/キーパッド | キーボードの前方削除 | 0x0007 | 0x004C | 0xE053 | 76 |
キーボード/キーパッド | キーボードの終了 | 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 |
キーボード/キーパッド | キーパッドのナムロックとクリア | 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 とホーム | 0x0007 | 0x005F | 0x0047 | 91 |
キーボード/キーパッド | キーパッド 8 と上矢印 | 0x0007 | 0x0060 | 0x0048 | 96 |
キーボード/キーパッド | キーパッド 9 と PageUp | 0x0007 | 0x0061 | 0x0049 | 101 |
キーボード/キーパッド | キーパッド 0 と挿入 | 0x0007 | 0x0062 | 0x0052 | 九十九 |
キーボード/キーパッド | キーパッドのピリオドと削除 | 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 |
キーボード/キーパッド | Keyboard International3 | 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 |
キーボード/キーパッド | キーボード 左シフト | 0x0007 | 0x00E1 | 0x002A | 44 |
キーボード/キーパッド | キーボード LeftAlt | 0x0007 | 0x00E2 | 0x0038 | 六十 |
キーボード/キーパッド | キーボードの左側のGUI | 0x0007 | 0x00E3 | 0xE05B | 127 |
キーボード/キーパッド | キーボード RightControl | 0x0007 | 0x00E4 | 0xE01D | 64 |
キーボード/キーパッド | キーボード右シフト | 0x0007 | 0x00E5 | 0x0036 | 五十七 |
キーボード/キーパッド | キーボード右Alt | 0x0007 | 0x00E6 | 0xE038 | 62 |
キーボード/キーパッド | キーボードの右にあるグラフィカルユーザーインターフェース | 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 ホームページ | 0x000C | 0x0223 | 0xE032 | |
コンシューマー | エアコンバック | 0x000C | 0x0224 | 0xE06A | |
コンシューマー | AC 転送 | 0x000C | 0x0225 | 0xE069 | |
コンシューマー | エアコン停止 | 0x000C | 0x0226 | 0xE068 | |
コンシューマー | AC 更新 | 0x000C | 0x0227 | 0xE067 | |
コンシューマー | AC ブックマーク | 0x000C | 0x022A | 0xE066 |
注記:
- SysRq キー スキャン コードが Alt + Print 画面 のキーストロークで出力される
- Ctrl + Pause キーストロークでブレーク キー スキャン コードが出力される
- 従来のキーボード メッセージに表示されるとおり
- このキーは、ブラジルのキーボードに存在します
- キーは日本語キーボードに存在します
- スキャン コードは、キー リリース イベントでのみ出力されます
Extended-Key フラグ
拡張キー フラグは、キーストローク メッセージが拡張 101/102 キー キーボードの追加キーの 1 つから送信されたかどうかを示します。 拡張キーの一覧は、キーボードの右側にある Alt キーと Ctrl キー、テンキーの左側にあるクラスターの Insert*、Delete*、Home、End、Page Up、Page Down、Arrow キー、Num ロック キー、Break (Ctrl + Pause) キー、印刷画面キー、そしてテンキーの 割る (/) キーと Enter キーから構成されています。 右側の Shift キーは拡張キーとは見なされず、代わりに別のスキャン コードがあります。
指定した場合、スキャン コードは 2 バイトのシーケンスで構成されます。最初のバイトの値は 0xE0 です。
コンテキスト コード
コンテキスト コードは、キーストローク メッセージが生成されたときに Alt キーがダウンしたかどうかを示します。 Alt キーがダウンした場合はコードは 1、アップしている場合は 0 です。
前の Key-State フラグ
前のキー状態フラグは、キーストローク メッセージを生成したキーが以前にアップまたはダウンしたかどうかを示します。 キーが以前にダウンしていた場合は 1、キーが以前にアップしていた場合は 0 です。 このフラグを使用すると、キーボードの自動繰り返し機能によって生成されたキーストローク メッセージを識別できます。 このフラグは、自動繰り返し機能によって生成された WM_KEYDOWN および WM_SYSKEYDOWN キーストローク メッセージに対して 1 に設定されます。 WM_KEYUPメッセージとWM_SYSKEYUPメッセージの場合、常に 1 に設定されます。
Transition-State フラグ
遷移状態フラグは、キーを押すか、キーを解放してキーストローク メッセージを生成したかを示します。 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 パラメーターの内容と同じです。 詳細については、「 キーストローク メッセージ フラグ」を参照してください。
Dead-Character メッセージ
一部の英語以外のキーボードには、単独で文字を生成することが想定されていない文字キーが含まれています。 代わりに、後続のキーストロークによって生成された文字に分音記号を追加するために使用されます。 これらのキーは 、デッド キーと呼ばれます。 ドイツ語キーボードの circumflex キーは、デッド キーの例です。 "o" で構成される文字を circumflex と共に入力するには、ドイツ語のユーザーは、circumflex キーの後に "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 関数を使用して、仮想キーの現在の状態を取得できます。
一部のキーは、キーボード レイアウトの状態を変更するトグル キーと見なされます。 トグル キーには、通常、 CapsLock (VK_CAPITAL)、 Num Lock (VK_NUMLOCK)、 スクロール ロック (VK_SCROLL) キーが含まれます。 ほとんどのキーボードには、これらのキーに対応する LED インジケーターがあります。
キーボード レイアウトでは、名前の一覧が保持されます。 1 つの文字を生成するキーの名前は、キーによって生成される文字と同じです。 Tab キーや Enter キーなどの文字以外のキーの名前は、文字列として格納されます。 アプリケーションは 、GetKeyNameText 関数を呼び出すことによって、キーボード レイアウトから任意のキーの名前を取得できます。
キーストロークと文字翻訳
システムには、さまざまなキーストローク メッセージによって提供されるスキャン コード、文字コード、および仮想キー コードを変換する特殊な目的の機能がいくつか含まれています。 これらの関数には、 MapVirtualKey、 ToAscii、 ToUnicode、 VkKeyScan が含まれます。
さらに、Microsoft Rich Edit 3.0 では HexToUnicode IME がサポートされています。これにより、ユーザーはホット キーを使用して 16 進文字と Unicode 文字を変換できます。 つまり、Microsoft Rich Edit 3.0 をアプリケーションに組み込むと、アプリケーションは HexToUnicode IME の機能を継承します。
Hot-Key サポート機能
ホット キーは、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 では、5 つのボタンを持つマウスである Microsoft IntelliMouse エクスプローラーもサポートされています。 2 つの追加ボタンは、前方および後方のブラウザー ナビゲーションをサポートします。 詳細については、 XBUTTON を参照してください。
入力のシミュレート
中断されない一連のユーザー入力イベントをシミュレートするには、 SendInput 関数を使用します。 この関数は、3 つのパラメーターを受け取ります。 最初のパラメーター cInputs は、シミュレートされる入力イベントの数を示します。 2 番目のパラメーター rgInputs は INPUT 構造体の配列であり、それぞれが入力イベントの種類とそのイベントに関する追加情報を記述します。 最後のパラメーター cbSize は、 INPUT 構造体のサイズをバイト単位で受け入れます。
SendInput 関数は、シミュレートされた一連の入力イベントをデバイスの入力ストリームに挿入することによって機能します。 この効果は 、keybd_event または mouse_event 関数を繰り返し呼び出すことと似ていますが、シミュレートされたイベントと他の入力イベントが混在しないようにシステムによって保証される点が異なります。 呼び出しが完了すると、戻り値は、正常に再生された入力イベントの数を示します。 この値が 0 の場合、入力はブロックされました。
SendInput 関数は、キーボードの現在の状態をリセットしません。 そのため、ユーザーがこの関数を呼び出すときに押されたキーがある場合、この関数が生成するイベントに干渉する可能性があります。 干渉の可能性が心配な場合は、 GetAsyncKeyState 関数を使用してキーボードの状態を確認し、必要に応じて修正します。
言語、ロケール、キーボード レイアウト
言語は、英語、フランス語、日本語などの自然言語です。 サブ言語は、英国と米国で話される英語のサブ言語など、特定の地理的地域で話される自然言語のバリエーションです。 アプリケーションでは、 言語識別子と呼ばれる値を使用して、言語とサブ言語を一意に識別します。
通常、アプリケーションは ロケール を使用して、入力と出力が処理される言語を設定します。 たとえば、キーボードのロケールを設定すると、キーボードによって生成される文字値に影響します。 ディスプレイまたはプリンターのロケールを設定すると、表示または印刷されるグリフに影響します。 アプリケーションでは、キーボード レイアウトを読み込んで使用することで、キーボードのロケールを設定します。 指定したロケールをサポートするフォントを選択して、ディスプレイまたはプリンターのロケールを設定します。
キーボード レイアウトは、キーボード上のキーの物理的な位置を指定するだけでなく、それらのキーを押すことによって生成される文字値も決定します。 各レイアウトは、現在の入力言語を識別し、キーとキーの組み合わせによって生成される文字値を決定します。
すべてのキーボード レイアウトには、レイアウトと言語を識別する対応するハンドルがあります。 ハンドル部分の下位ワードは言語識別子です。 高い単語は、物理レイアウトを指定するデバイス ハンドル、または既定の物理レイアウトを示す 0 です。 ユーザーは、任意の入力言語を物理レイアウトに関連付けることができます。 たとえば、フランス語で頻繁に作業する英語を話すユーザーは、キーボードの物理的なレイアウトを変更せずに、キーボードの入力言語をフランス語に設定できます。 つまり、ユーザーは使い慣れた英語レイアウトを使用してフランス語でテキストを入力できます。
通常、アプリケーションは入力言語を直接操作することは想定されていません。 代わりに、ユーザーは言語とレイアウトの組み合わせを設定し、その間で切り替えます。 ユーザーが別の言語でマークされたテキストをクリックすると、アプリケーションは ActivateKeyboardLayout 関数を呼び出して、その言語のユーザーの既定のレイアウトをアクティブにします。 ユーザーがアクティブなリストにない言語でテキストを編集した場合、アプリケーションは言語で LoadKeyboardLayout 関数を呼び出して、その言語に基づいてレイアウトを取得できます。
ActivateKeyboardLayout 関数は、現在のタスクの入力言語を設定します。 hkl パラメーターには、キーボード レイアウトのハンドルまたは 0 から拡張された言語識別子のいずれかを指定できます。 キーボード レイアウト ハンドルは、 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 つのレイアウトを入力テキストに使用できるようになります。