Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ProcessCmdKey-是否等待KeyUp?_C#_Winforms_Hotkeys - Fatal编程技术网

C# ProcessCmdKey-是否等待KeyUp?

C# ProcessCmdKey-是否等待KeyUp?,c#,winforms,hotkeys,C#,Winforms,Hotkeys,我在WinForms应用程序中遇到以下问题。 我正在尝试实现热键,每当控件处于活动状态时,我都需要处理关键消息,无论焦点是否在该控件内的文本框上,等等 重写ProcessCmdKey可以很好地实现这一点,并且完全符合我的要求,只有一个例外: 如果用户按下某个键并一直按下,ProcessCmdKey会一直触发WM_KEYDOWN事件 但是,我想实现的是,用户必须在触发另一个热键操作之前再次释放按钮(因此,如果有人坐在键盘上,它不会导致连续的热键事件)。 但是,我找不到捕捉WM_KEYUP事件的位置

我在WinForms应用程序中遇到以下问题。 我正在尝试实现热键,每当控件处于活动状态时,我都需要处理关键消息,无论焦点是否在该控件内的文本框上,等等

重写ProcessCmdKey可以很好地实现这一点,并且完全符合我的要求,只有一个例外:

如果用户按下某个键并一直按下,ProcessCmdKey会一直触发WM_KEYDOWN事件

但是,我想实现的是,用户必须在触发另一个热键操作之前再次释放按钮(因此,如果有人坐在键盘上,它不会导致连续的热键事件)。
但是,我找不到捕捉WM_KEYUP事件的位置,所以我可以设置一个标志,它是否应该再次处理ProcessCmdKey消息

有人能帮忙吗

谢谢


汤姆

我想这很容易,看看钥匙的重复计数就知道了。如果使用了修改器,则不起作用。您还需要看到密钥向上,这需要实现IMessageFilter。这起到了作用:

public partial class Form1 : Form, IMessageFilter {
    public Form1()  {
        InitializeComponent();
        Application.AddMessageFilter(this);
        this.FormClosed += (s, e) => Application.RemoveMessageFilter(this);
    }
    bool mRepeating;
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (keyData == (Keys.Control | Keys.F) && !mRepeating) {
            mRepeating = true;
            Console.WriteLine("What the Ctrl+F?");
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
    public bool PreFilterMessage(ref Message m) {
        if (m.Msg == 0x101) mRepeating = false;
        return false;
    }
}

嗯,这对我来说似乎不起作用,预处理消息似乎不会被触发。Arf,它只有在窗体有焦点时才会运行。我们需要B计划,让我考虑一下。
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;

protected override bool ProcessKeyPreview(ref Message m)
{
    if (m.Msg == WM_KEYDOWN && (Keys)m.WParam == Keys.NumPad6)
    {
        //Do something
    }
    else if (m.Msg == WM_KEYUP && (Keys)m.WParam == Keys.NumPad6)
    {
        //Do something
    }

    return base.ProcessKeyPreview(ref m);
}