C# 关键事件:ProcessCmdKey

C# 关键事件:ProcessCmdKey,c#,.net,winforms,C#,.net,Winforms,我试图在一个小的测试Windows窗体应用程序上得到一些键盘响应,我有一个粗略的解决方案,就是重写ProcessCmdKey。然而,我遇到了一些问题,并且发现了一些不一致之处 不同事件:在参数ref Message msg,Keys keyData中,是否有办法判断偶数是KeyDown、keydup还是KeyPress KeyPress:我所看到的每一个地方都说,KeyPress(即重复的键盘输入)只发生在字符键上,而箭头键不是。但是,对于箭头键和字符键,事件处理程序的调用频率和行为都是一样的。

我试图在一个小的测试Windows窗体应用程序上得到一些键盘响应,我有一个粗略的解决方案,就是重写ProcessCmdKey。然而,我遇到了一些问题,并且发现了一些不一致之处

不同事件:在参数
ref Message msg,Keys keyData
中,是否有办法判断偶数是KeyDown、keydup还是KeyPress

KeyPress:我所看到的每一个地方都说,KeyPress(即重复的键盘输入)只发生在字符键上,而箭头键不是。但是,对于箭头键和字符键,事件处理程序的调用频率和行为都是一样的。这是一个按键事件,还是其他什么

理想情况下,我想要一种在表单级别处理所有键盘事件的方法,而不让它们传递给表单上的控件。然而,所有的文档都让我感到非常困惑,并且遗漏了关键点,因此我无法完成这项工作

感谢您对这些主题的帮助。谢谢

传递给的结构在其属性中包含WINAPI消息编号:

  • WM_向下键
    0x100
    (256)
  • WM_KEYUP
    0x101
    (257)
  • WM_CHAR
    (大致相当于
    KeyPress
    )是
    0x102
    (258)
  • WM_SYSKEYDOWN
    0x104
    (260)
  • WM_SYSKEYUP
    0x105
    (261)
关于您关于
KeyPress
的问题,箭头键等非字符键确实不会在内部生成
WM\u CHAR
消息,但它们确实会生成
WM\u KEYDOWN
,并且该消息也会多次发送以供重复输入


还请注意,我不确定
ProcessCmdKey()
是否是实现所需的正确方法。本文档将其描述为仅处理
主菜单命令键和MDI加速器
,它们可能只是您想要捕获的键的子集。您可能希望改为重写,它处理子控件接收的所有键盘消息。

在表单中重写ProcessCmdKey的目的是明确允许您实现自定义快捷键处理,而不仅仅是按钮和菜单项中的内置助记符处理

它仅在具有焦点的控件获得KeyDown事件之前的KeyDown事件上调用,而不管哪个客户端控件具有焦点。因此不与KeyUp和KeyPress关联。在执行快捷键功能后,当识别该键时,从覆盖返回true。这将阻止进一步处理密钥,它不会生成任何KeyDown/Press/Up事件

使用该方法的msg参数是非常罕见的,msg.msg值只有在用户按下Alt键时才会产生WM_KEYDOWN或WM_SYSKEYDOWN消息。这一点您并不关心,因为您总是可以从keyData参数获得if。像这样:

    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数据。检查MSDN文档中的WM_键下通知。msg.LParam值包含一组有关键笔划的信息

请注意,在这个方法中,您只能获得虚拟密钥。Keys.F是英文键盘布局中的F键,但不一定是用户布局中相同位置的键的相同字母。支持功能键,以避免文档头痛

按键重复是键盘控制器的一项功能,不限于键入按键。按住箭头键和功能键时,肯定会重复此操作。在这种情况下,您希望忽略按键。但是,如果您为同时也是键入键(如Keys.F)的键指定了快捷键,那么您还希望始终检查修改键,这样就不会破坏TextBox等控件

最后但并非最不重要的一点是,不要忘记按钮和菜单项控件中内置的助记符支持。编写它们的文本属性(如
&OK
)会生成一个无需任何代码的自文档快捷方式。在本例中,由用户通过键入Alt+O来操作