キーボード入力のしくみ

Windows フォームは、Windows メッセージに応答してキーボード イベントを発生させることにより、キーボード入力を処理します。 多くの Windows フォーム アプリケーションは、キーボード イベントを処理することによってキーボード入力を排他的に処理します。 しかし、高度なキーボード入力のシナリオ (キーがコントロールに到達する前にインターセプトするなど) を実装するためには、キーボード メッセージのしくみについて理解することが必要です。 このトピックでは、Windows フォームが認識するキー データの種類について説明し、キーボード メッセージをルーティングする方法について概要を説明します。 キーボード イベントの詳細については、「キーボード イベントの使用」を参照してください。

キーの種類

Windows フォームでは、キーボード入力をビット単位の Keys 列挙型で表される仮想キー コードとして識別します。 Keys 列挙型を使用すると、押下された一連のキーを組み合わせて単一の値を生成できます。 これらの値は、Windows メッセージ WM_KEYDOWN および WM_SYSKEYDOWN に付随する値に対応します。 ほとんどの物理的なキーの押下は、KeyDown または KeyUp イベントを処理することによって検出できます。 文字キーは Keys 列挙型のサブセットであり、Windows メッセージ WM_CHAR および WM_SYSCHAR に付随する値に対応します。 押下されたキーを組み合わせて文字が生成される場合、KeyPress イベントを処理することにより、その文字を検出できます。 または、Visual Basic プログラミング インターフェイスによって公開される Keyboard を使用して、どのキーが押されたかの判断と、キーの送信を行うこともできます。 詳細については、「Accessing the Keyboard (キーボードへのアクセス)」を参照してください。

キーボード イベントの順序

先に説明したとおり、コントロール上では 3 つのキーボード関連のイベントが発生します。 イベントは一般に次の順序で発生します。

  1. ユーザーが "a" キーを押すと、キーが前処理されてディスパッチされ、KeyDown イベントが発生します。

  2. ユーザーは "a" キーを押したままで、キーが前処理されてディスパッチされ、KeyPress イベントが発生します。

    このイベントはユーザーがキーを押し続けているとき複数回発生します。

  3. ユーザーが "a" キーを解放すると、キーが前処理されてディスパッチされ、KeyUp イベントが発生します。

キーの前処理

他のメッセージと同様に、キーボード メッセージは、フォームまたはコントロールの WndProc メソッドで処理されます。 ただし、キーボード メッセージが処理される前に、PreProcessMessage メソッドによって 1 つ以上のメソッドが呼び出されます。これらをオーバーライドして、特殊文字キーと物理キーを扱うことができます。 これらのメソッドをオーバーライドすると、コントロールがメッセージを処理する前に、特定のキーを検出してフィルターできます。 次の表に、実行される処理と、そのとき呼び出されるメソッドを、メソッドが呼び出される順に示します。

KeyDown イベントの前処理

アクション 関連メソッド Notes
アクセラレータやメニュー ショートカットなどのコマンド キーの確認。 ProcessCmdKey このメソッドはコマンド キーを処理します。コマンド キーは通常のキーよりも優先順位が上です。 このメソッドが true を返した場合、キー メッセージはディスパッチされず、キー イベントも発生しません。 falseが返される場合、IsInputKey が呼び出されます.
前処理を必要とする特殊キーであるか、または KeyDown イベントを発生させ、コントロールにディスパッチされる必要がある通常の文字キーであるかを確認します。 IsInputKey メソッドによって trueが返される場合、コントロールが通常の文字で、KeyDown イベントが発生することを意味します。 falseの場合、ProcessDialogKey が呼び出されます。 注: コントロールでキーまたはキーの組み合わせを確実に取得するために、PreviewKeyDown イベントを処理し、対象の 1 つまたは複数のキーの PreviewKeyDownEventArgsIsInputKeytrue に設定することができます。
移動キー (Esc、Tab、Return、または方向キー) の確認。 ProcessDialogKey このメソッドはコントロール内で特別な機能 (コントロールとその親コントロールの間のフォーカスの切り替えなど) を実行する物理キーを処理します。 即時コントロールでキーが処理されない場合、親コントロールで ProcessDialogKey が呼び出されます。それでも処理されなければ、コントロールの呼び出しが階層構造の最上位のコントロールまで続けられます。 このメソッドが true を返した場合、前処理は完了し、キー イベントは生成されません。 false が返される場合、KeyDown イベントが発生します。

KeyPress イベントの前処理

アクション 関連メソッド Notes
キーがコントロールによって処理される通常の文字であるかどうかの確認 IsInputChar 文字が通常の文字である場合は、このメソッドによって true が返され、KeyPress イベントが発生します。それ以上の処理は行われません。 それ以外の場合、ProcessDialogChar が呼び出されます。
文字がニーモニック (ボタン上の &OK など) かどうかの確認 ProcessDialogChar このメソッドは、ProcessDialogKeyと同様に、コントロール階層の上位まで呼び出されます。 コントロールがコンテナー コントロールである場合、それ自体と子コントロールで ProcessMnemonic を呼び出すことにより、ニーモニックの確認が行われます。 ProcessDialogChar によって trueが返される場合、KeyPress イベントは発生しません。

キーボード メッセージの処理

キーボード メッセージは、フォームまたはコントロールの WndProc メソッドに到達すると、オーバーライド可能な一連のメソッドによって処理されます。 これらの各メソッドによって、Boolean 値が返されます。これは、キーボード メッセージがコントロールによって処理され、使用されたかどうかを指定します。 いずれかのメソッドが true を返した場合は、メッセージが処理されたと判断されるため、ベース コントロールまたは親コントロールにメッセージが渡されることはありません。 そうでない場合は、メッセージがメッセージ キューに残り、場合によってはそのコントロールのベースまたは親に含まれる別のメソッドで処理されます。 次の表に、キーボード メッセージを処理するメソッドを示します。

メソッド メモ
ProcessKeyMessage このメソッドによって、コントロールの WndProc メソッドによって受信されたすべてのキーボード メッセージが処理されます。
ProcessKeyPreview このメソッドは、キーボード メッセージを親コントロールに送信します。 ProcessKeyPreview によって trueが返された場合、キー イベントは生成されます。それ以外の場合、ProcessKeyEventArgs が呼び出されます。
ProcessKeyEventArgs このメソッドにより、必要に応じて、KeyDownKeyPressKeyUp イベントが発生します。

キーボード メソッドのオーバーライド

キーボード メッセージを処理するためにオーバーライドできるメソッドは多数ありますが、どのメソッドを選ぶかが非常に重要です。 次の表に、実行するタスクと、キーボード メソッドをオーバーライドする最善の方法を示します。 メソッドのオーバーライドの詳細については、「派生クラスのプロパティとメソッドのオーバーライド」を参照してください。

タスク メソッド
ナビゲーション キーをインターセプトして、KeyDown イベントを発生させます。 たとえば、テキスト ボックス内で Tab や Return を処理するなど。 IsInputKey をオーバーライドします。 注: または、PreviewKeyDown イベントを処理し、対象の 1 つまたは複数のキーの PreviewKeyDownEventArgsIsInputKeytrue に設定することもできます。
コントロールで特別な入力処理や移動処理を実行する。 たとえば、リスト コントロールで方向キーを使用して選択項目を変更するなど。 ProcessDialogKey をオーバーライドします。
ナビゲーション キーをインターセプトして、KeyPress イベントを発生させます。 たとえば、スピン ボックス コントロールで方向キーを複数回押して、項目の移動を加速するなど。 IsInputChar をオーバーライドします。
KeyPress イベント中に、特殊な入力またはナビゲーションの処理を実行します。 たとえば、リスト コントロール内で "r" キーを押し続けると、r の文字で始まる項目にスキップするなど。 ProcessDialogChar をオーバーライドします。
カスタムなニーモニックの処理を実行する。たとえば、ツール バーに配置されたオーナー描画ボタンのニーモニックを処理するなど。 ProcessMnemonic をオーバーライドします。

関連項目