4

我已经使用注册了一个消息过滤器

Application.AddMessageFilter(m_messageFilter);

使用它,我可以记录用户在应用程序的用户界面中所做的所有鼠标点击。

但是,一个对话框在单独的线程上运行,代码如下:

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        dialog.ShowDialog();
    }
}

Thread thread = new Thread(Run);

我设置的消息过滤器看不到进入此窗口的消息。我怎样才能得到它们(最好不要太打扰)?

我试图覆盖 MyDialog.PreProcessMessage,但我很困惑这似乎永远不会被调用。

谢谢。

4

3 回答 3

3

几乎所有的应用程序方法,包括 AddMessageFilter,都是线程特定的。因此,如果您想过滤另一个线程上的消息,您必须在该线程上调用 AddMessageFilter。

只需将您的 Run 方法更改为:

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        Application.AddMessageFilter(new MyMessageFilter());
        Application.Run(dialog); 
    }
}
于 2009-07-31T17:58:54.867 回答
1

只是一个刺,但您可以利用volatile关键字,这是一个使用 volatile bool 来检查不同线程上的进程之间状态的示例。

您可能可以调整该方法以满足您的需求。根据第二个对话框中是否遇到味精来翻转它

{EDIT}关于 PreProcessMessage,我相信这仅适用于键盘输入,而不适用于鼠标。您可能必须覆盖 WndProc 才能获取这些事件,这很可能是被覆盖的 PreProcessMessage 没有触发的原因。

祝你好运!

于 2009-07-28T17:02:02.890 回答
1

我想你应该用以下方式重写你的代码

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        Application.Run();
        dialog.ShowDialog();
    }
}

或许

Application.Run(dialog);

在里面使用 { ... } 也可以

Application.Run() 开始在当前线程上运行标准应用程序消息循环。通常消息循环仅在主线程中工作。如果没有 Application.Run() 标准消息循环将不会在第二个线程中启动。

这是一篇文章在单独的线程上创建启动画面表单,其中使用了类似的技术-第二种表单(SlpashScreen)在另一个线程中启动,它们调用 Application.Run(splash); 在这第二个线程中。

从本文中可以看出,在不同线程中运行表单需要开发人员非常小心地关闭/处置表单。

于 2009-07-31T16:17:14.183 回答