试图理解什么';在处理热键消息时,C#WinForms WndProc方法中确实发生了这种情况

试图理解什么';在处理热键消息时,C#WinForms WndProc方法中确实发生了这种情况,c#,winforms,hotkeys,wndproc,C#,Winforms,Hotkeys,Wndproc,我一直在开发一个C#WinForms应用程序,该应用程序使用广受讨论的GlobalAddAtom和RegisterHotKey PInvoke方法注册了几个热键。程序以最小化模式启动,并在系统托盘中运行。每次接收到一条热键消息时,程序都会捕获关于按下哪个键的数据,并将其交给另一个对象进行处理。这已经相对有效了一段时间,但偶尔会出现一些奇怪的行为。类似于同一条消息被多次处理,或者某些消息完全丢失 在添加一些广泛的日志记录后,我发现如果用户按住热键组合(例如Win+C)的时间比正常情况稍长,或者只是

我一直在开发一个C#WinForms应用程序,该应用程序使用广受讨论的GlobalAddAtom和RegisterHotKey PInvoke方法注册了几个热键。程序以最小化模式启动,并在系统托盘中运行。每次接收到一条热键消息时,程序都会捕获关于按下哪个键的数据,并将其交给另一个对象进行处理。这已经相对有效了一段时间,但偶尔会出现一些奇怪的行为。类似于同一条消息被多次处理,或者某些消息完全丢失

在添加一些广泛的日志记录后,我发现如果用户按住热键组合(例如Win+C)的时间比正常情况稍长,或者只是简单地按住它,那么在前一条消息完成处理之前,消息循环中会收到新的热键消息

现在,在我看来,消息是在UI线程上接收的(即使它是隐藏的),并通过对不同类的实例的阻塞调用进行处理。如果这是真的,那么另一条消息如何进入当前正在处理第一条消息的同一个函数?这就是我对Win32缺乏了解的地方,让我抓狂

在我看来,第二条消息是在不同的线程上收到的。但如果这是真的,那么它将调用我的处理类的哪个实例

如果您能帮我解决这个问题,我们将不胜感激

这里有一个简化的例子。此代码

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case MultipleClipboardsDialog.WM_HOTKEY:
            HotKey hotKey = new HotKey(m.LParam);
            Log.Debug("About to process hot key " + hotKey.ToString());
            this.Processor.ProcessHotKey(hotKey);
            Log.Debug("Finished processing hot key " + hotKey.ToString());
            break;

        default:
            base.WndProc(ref m);
            break;
    }
}
…产生这样的输出

About to process hot key Win + C
About to process hot key Win + C
About to process hot key Win + C
Finished processing hot key Win + C

您要查找的消息仅在释放按钮时生成。在Windows中设置消息的方式是,每次按键最多生成三条消息。启动Spy++,看看记事本。您应该能够看到在正常Windows操作期间生成的消息


最后会出现KeyDown、KeyPressed和keypup消息(或类似消息)。您可能正在拦截其中的一到两条消息(正常操作,您需要编写代码)。您可能还需要查看Ascii键和虚拟键。

您是否尝试过向MOD_NOREPEAT注册热键,并查看是否遇到同样的问题?MOD_NOREPEAT应该停止发送额外的消息,直到释放并再次按下该键。这听起来是个好主意,但根据它的说法,它只在Windows7中起作用。我仍然可以尝试使用它,但是Spy++已经告诉我其他消息实际上可能是我问题的根源。好的,谢谢你的建议。今晚我会尝试一下。这个问题还没有完全解决,但我认为Spy++会根据我处理的消息帮助我弄清楚到底发生了什么。谢谢