4

我正在尝试使用本文中的代码让您知道您的应用程序何时空闲..

如果您的应用程序只有一个表单,则此代码非常有用。您调用Application2.Run(myOnlyForm)它,所有消息都会通过 Application2 中的过滤器进行路由。

但是,如果您在任何时候调用mySecondForm.ShowDialog()该对话框都不会通过 Application2 过滤其消息。

有什么方法(没有不良副作用)让消息mySecondForm通过“Application2”事件过滤器?

我努力了:

  1. 更改mySecondForm.ShowDialogApplication2.Run(mySecondForm).
    • 这会导致窗口在超出范围时不清理,并且在需要时不显示。
  2. 更改mySecondForm.ShowDialogApplication2.ShowDialog(mySecondForm).
    • 这会导致主菜单mySecondForm无法正常工作(单击无效,只会发出哔声)。
      • 这似乎是我应该使用的,但我需要在我的屏幕上有菜单。这似乎是 OpenNETCF 的一个常见 问题
      • 菜单项没有损坏。使用菜单的热键仍然有效。只是点击菜单不起作用。
  3. 更改mySecondForm.ShowDialogApplication2.ShowDialog(mySecondForm, true)(true = 清理对话框)。
    • 这不起作用,因为我需要在对话框关闭几次后访问它。

理想情况下,我想要一种将表单附加到 Application2 的消息功能的方法。

但我欢迎任何建议。


编辑:根据对 ctacke 的建议,这就是我所做的:

public static DialogResult ShowDialog2(this Form form)
{
    //form.Activated += InsertMenu;
    //Application2.ShowDialog(form);
    form.Show();
    try
    {
        do
        {
            Application2.DoEvents();
        } while (form.Visible);
    }
    catch (ObjectDisposedException)
    {
        // This just means that the form was closed.  Not a big deal.
    }
    return form.DialogResult;

}

我最终调用 ShowDialog2 而不是 ShowDialog

4

2 回答 2

2

我可以解释这种行为,但可能无法提供直接的解决方案。

当您在任何表单上调用 Show 时,表单的事件将由默认消息泵处理(通过调用 Run 进行设置)。当您调用 ShowDialog 时,目标 Form 将获得自己的独立消息泵。

现在,您添加的过滤器位于主消息泵中,它正在查看那里的所有消息,但 ShowDialog 调用绕过了这一点 - 发送到对话框的消息永远不会到达过滤器。

现在我们确实添加了 Application2.ShowDialog 调用作为解决此问题的尝试,但老实说,虽然我编写了整个 Application.Run/IMEssageFilter 实现,但我没有执行 ShowDialog 解决方法,我真的不知道如何好吧,它被实施了。根据您的报告,我会冒险猜测“不太好”,尽管这确实不是一个简单的问题要解决。这个问题的根源在于,当您调用 Show 和 ShowDialog 时,SDF 无法控制 BCL 中发生的事情——我们只是试图坐在它之上并提供我们所能提供的最佳行为。在这种情况下,这是有问题的。

您能否碰巧不使用对 ShowDialog 的调用,而只是使用 Show 加上诸如保持 TopMost 表单之类的东西?这将允许过滤器获取伪对话框的所有消息。我可以立即想到的另一个选项是对话框的基类,它将通知回过滤器机制,但这开始变得真正难以控制。

于 2010-06-23T22:15:55.813 回答
0

请原谅我的提问,但你为什么要为这么简单的事情经历这么多疯狂的麻烦呢?查看您链接的文章,它所做的只是启动一个计时器并在每个WM_KEYUP事件WM_MOUSEMOVEWM_LBUTTONUP事件中重置它。

WndProc您可以通过覆盖或PreProcessMessage在您的表单中并让它执行计时器重置来实现相同的目标。您甚至可以制作一个基本表单 (*) 来执行计时器/重置操作并从中派生所有表单。对于真正的全局解决方案,将计时器设为静态。

(*) 不要将其标记为抽象的,否则表单设计师会大吃一惊。

于 2010-06-23T20:57:00.847 回答