15

少しテストしたWindowsフォームアプリケーションでキーボードの応答を取得しようとしていますが、ProcessCmdKeyをオーバーライドするという大まかな解決策があります。しかし、私が直面しているいくつかの問題と、私が見つけている矛盾があります。

さまざまなイベント:引数ref Message msg, Keys keyDataで、偶数がKeyDown、KeyUp、またはKeyPressのいずれであるかを判断する方法はありますか?

KeyPress:どこを見ても、KeyPress、つまりキーボード入力の繰り返しは、矢印キーではなく文字キーに対してのみ発生すると言われています。ただし、イベントハンドラーは、文字キーと同じように、矢印キーに対して同じ方法で同じ動作で頻繁に呼び出されます。これはKeyPressイベントに直面していますか、それとも他の何かですか?

理想的には、フォームレベルで、すべてのキーボードイベントを、フォームのコントロールに渡さずに処理する方法が必要です。しかし、すべてのドキュメントが私を十分に混乱させ、重要なポイントを見逃したため、これを完了することができませんでした。

これらのトピックのいずれかに関するヘルプをいただければ幸いです。ありがとう!

4

2 に答える 2

51

フォームでProcessCmdKeyをオーバーライドすることは、ボタンやメニュー項目に組み込まれているニーモニック処理を超えて、カスタムのショートカットキーストローク処理を実装できるようにすることを明示的に目的としています。

これは、フォーカスのあるコントロールがKeyDownイベントを取得する前に、どのクライアントコントロールがフォーカスを持っているかに関係なく、キーダウンイベントでのみ呼び出されます。したがって、KeyUpやKeyPressには関連付けられていません。ショートカット関数を実行した後、キーを認識すると、オーバーライドからtrueを返します。これにより、キーがそれ以上処理されなくなり、KeyDown / Press/Upイベントが生成されなくなります。

メソッドのmsg引数を使用することは非常にまれです。msg.Msg値はWM_KEYDOWNまたはWM_SYSKEYDOWNのみになり、後者のメッセージはユーザーがAltキーを押したときに生成されます。keyData引数からいつでも取得できるので気にしないでください。このような:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (keyData == (Keys.Alt | Keys.F)) {
            // Alt+F pressed
            doSomething();
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

|で確認したい他の修飾子 ここで使用される演算子は、Keys.ShiftとKeys.Controlです。したがって、(Keys.Shift | Keys.Control | Keys.F1)はCtrl + Shift+F1をチェックします。繰り返しキーをチェックするなどの異常なことをしたい場合は、msgデータを解釈できます。WM_KEYDOWN通知については、MSDNドキュメントを確認してください。msg.LParam値には、キーストロークに関する一連の情報が含まれています。

このメソッドでは仮想キーのみを取得することに注意してください。Keys.Fは、英語のキーボードレイアウトのFキーですが、ユーザーのレイアウトの同じ場所にあるキーと同じ文字である必要はありません。ドキュメントの問題を回避するために、ファンクションキーを使用してください。

キーの繰り返しはキーボードコントローラーの機能であり、キーの入力に限定されません。矢印キーとファンクションキーは、押したままにすると確実に繰り返されます。このシナリオでは、KeyPressを無視します。ただし、タイピングキー(Keys.Fなど)でもあるキーにショートカットキーを割り当てる場合は、TextBoxのようなコントロールを壊さないように、常に修飾キーもチェックする必要があります。

最後になりましたが、ボタンとメニュー項目のコントロールに組み込まれているニーモニックのサポートを忘れないでください。のようにTextプロパティを&OK作成すると、コードを必要とせずに自己文書化ショートカットが作成されます。この例では、Alt+Oと入力してユーザーが操作します。

于 2012-05-06T13:41:12.777 に答える
18

ProcessCmdKey()に渡されるメッセージ構造には、そのMsgプロパティにWINAPIメッセージ番号が含まれています

  • WM_KEYDOWN0x100(256)、
  • WM_KEYUP0x101(257)、
  • WM_CHAR(とほぼ同等KeyPress)は0x102(258)、
  • WM_SYSKEYDOWN0x104(260)、
  • WM_SYSKEYUP0x105(261)です。

についての質問ですKeyPressが、矢印キーなどの文字以外のキーはWM_CHAR内部でメッセージを生成しませんが、生成WM_KEYDOWNします。また、そのメッセージは繰り返し入力するために複数回送信されます。

ProcessCmdKey()また、あなたが望むことを達成するための正しい方法がわからないことにも注意してください。ドキュメントではmain menu command keys and MDI accelerators、それを処理のみとして説明しています。これは、キャッチしたいキーのサブセットにすぎない場合があります。代わりに、子コントロールが受信したすべてのキーボードメッセージを処理するProcessKeyPreview()をオーバーライドすることをお勧めします。

于 2012-05-06T07:14:28.700 に答える