在处理热键消息时,试图了解C#WinForms WndProc方法中真正发生的事情

时间:2011-11-16 02:19:49

标签: c# winforms hotkeys wndproc

我一直在使用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

1 个答案:

答案 0 :(得分:0)

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

您最终得到KeyDown,KeyPressed和KeyUp消息(或其等价物)。您可能正在拦截其中一条或两条消息(正常操作,并且您可以编写代码)。您可能也想查看Ascii和Virtual Keys。