フォームでキーボード入力メッセージを処理する方法

Windows フォームは、メッセージがコントロールに到達する前に、フォーム レベルでキーボード メッセージを処理する機能を提供します。 この記事では、このタスクを実行する方法について説明します。

キーボード メッセージを処理する

アクティブフォームの KeyPress または KeyDown イベントを処理し、フォームの KeyPreview プロパティを trueに設定します。 このプロパティを使用すると、フォーム上のコントロールに到達する前に、キーボード入力がフォームに到達します。 次のコード例では、すべての数値キーを検出し、KeyPress47を使用して、 イベントを処理します。

// Detect all numeric characters at the form level and consume 1, 4, and 7.
// Form.KeyPreview must be set to true for this event handler to be called.
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (char.IsDigit(e.KeyChar))
    {
        MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.");

        switch (e.KeyChar)
        {
            case '1':
            case '4':
            case '7':
                MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.");
                e.Handled = true;
                break;
        }
    }
}
' Detect all numeric characters at the form level and consume 1, 4, and 7.
' Form.KeyPreview must be set to true for this event handler to be called.
Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs)
    If Char.IsDigit(e.KeyChar) Then
        MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.")

        Select Case e.KeyChar
            Case "1"c, "4"c, "7"c
                MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.")
                e.Handled = True
        End Select
    End If

End Sub

KeyPreviewが不十分な場合

Form.KeyPreview = true設定しても、すべてのキーがフォーム レベルのイベント ハンドラーに到達するとは限りません。 特定のキーは、標準フォーム イベントを実行する前に前処理を行います。 これらの例外を理解することは、コマンド キー、ダイアログ キー、およびコントロール固有の入力を正しく処理するために重要です。

コマンドキーとダイアログキーの前処理

フォーム レベルのキーボード イベントが発生する前に、Windowsは次のメソッドを使用して特定のキーを (順番に) 前処理します。

  1. ProcessCmdKey: メニュー ショートカットやアクセラレータなどのコマンド キーをインターセプトします。 このメソッドが true を返す場合、キーは消費され、イベントは発生しません。
  2. IsInputKey: キーで KeyDown イベントを発生させるか、 ProcessDialogKeyに移動するかを決定します。
  3. ProcessDialogKey: ナビゲーション キー (エスケープ、タブ、戻る、方向キー) を処理します。 処理された場合、イベントは発生しません。

フォーカスされたコントロールが前処理中にキーを使用する場合、フォームは KeyPreviewに関係なく、キーを受け取ることはありません。

フォーム レベルのハンドラーをバイパスする特殊なケース

  • Enter キーと Escape キー: これらのキーは、フォーム イベントに到達する前に AcceptButton および CancelButton によって処理される場合があります。
  • タブ: 多くの場合、コントロール フォーカス管理によって使用され、フォーム ハンドラーに到達しません。
  • メニュー ショートカット: Alt キーの組み合わせは、メニューの前処理によって処理されます。

フォームレベルでコマンドキーを捕捉する

フォーム レベルでコマンド キー (メニュー ショートカットやダイアログ キーを含む) を処理するには、フォームの ProcessCmdKey をオーバーライドします。 これは、標準フォーム イベントの前の前処理中に実行されます。

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    // Intercept Ctrl+A for custom handling
    if (keyData == (Keys.Control | Keys.A))
    {
        MessageBox.Show("Ctrl+A intercepted at form level");
        return true; // Mark as handled
    }

    // Pass other keys to the base handler
    return base.ProcessCmdKey(ref msg, keyData);
}
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
    ' Intercept Ctrl+A for custom handling
    If keyData = (Keys.Control Or Keys.A) Then
        MessageBox.Show("Ctrl+A intercepted at form level")
        Return True ' Mark as handled
    End If

    ' Pass other keys to the base handler
    Return MyBase.ProcessCmdKey(msg, keyData)
End Function

特定のコントロールで標準イベントを発生させる必要があるキーの場合は、 PreviewKeyDown を使用し、 IsInputKey をそのコントロールの true に設定します。

こちらも参照ください