1

我一直在开发一个 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
4

1 回答 1

0

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

您最终会收到 KeyDown、KeyPressed 和 KeyUp 消息(或类似的消息)。您可能正在拦截其中的一两条消息(正常操作,并且您围绕它编写代码)。您可能还想查看 Ascii 和 Virtual Keys。

于 2011-11-16T02:41:32.597 回答