如何将ShowDialog显示的表单中的消息附加到Application2?

时间:2010-06-23 20:49:31

标签: windows-mobile compact-framework opennetcf python-idle

我正在尝试使用此article中的代码,让您知道您的应用何时闲置。

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

但是,如果您在任何时候致电mySecondForm.ShowDialog()该对话框未通过Application2过滤其消息。

是否有任何方法(没有不良副作用)让mySecondForm上的消息通过`Application2'事件过滤器?

我试过了:

  1. mySecondForm.ShowDialog更改为Application2.Run(mySecondForm)
    • 这会导致窗口在超出范围时不清理,并在需要时不显示。
  2. mySecondForm.ShowDialog更改为Application2.ShowDialog(mySecondForm)
    • 这会导致mySecondForm上的主菜单无效(点击无效,只是发出哔哔声)。
      • 这似乎是我应该使用的那个,但我需要在屏幕上显示菜单。看来这是一个带有OpenNETCF的common problem
      • 菜单项未破坏。使用菜单的热键仍然有效。只需点击菜单不起作用。
  3. mySecondForm.ShowDialog更改为Application2.ShowDialog(mySecondForm, true)(true =清理对话框)。
    • 这不起作用,因为我需要在关闭一段时间后才能访问该对话框。
  4. 理想情况下,我想要一种方法将表单附加到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

2 个答案:

答案 0 :(得分:2)

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

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

现在你添加的过滤器驻留在主消息泵中,它正在查看那里的所有消息,但ShowDialog调用规避了 - 发送到对话框的消息永远不会到达过滤器。

现在我们确实添加了Application2.ShowDialog调用来尝试解决这个问题,但说实话,当我编写整个Application.Run/IMEssageFilter实现时,我没有做ShowDialog的解决方法而且我真的不喜欢知道它的实施情况。根据你的报告,我会冒一个“不好”的猜测,虽然它确实不是一个简单的问题需要解决。这个问题的根源在于,当您调用Show和ShowDialog时,SDF无法控制BCL中发生的事情 - 我们只是试图坐在它上面并提供我们可以做的最佳行为。在这种情况下,这是有问题的。

你是偶然的,不能使用ShowDialog的调用,而只是使用Show加上保持TopMost形式的东西?这将允许过滤器获取伪对话的所有消息。我可以直接想到的另一个选项是Dialogs的基类,它会通知回过滤机制,但开始变得难以控制。

答案 1 :(得分:0)

请原谅我,但为什么你要为这么简单的事情经历所有这些疯狂的麻烦?查看您关联的文章,它所做的只是启动计时器,并在每次WM_KEYUPWM_MOUSEMOVEWM_LBUTTONUP事件时重置该计时器。

您可以通过覆盖表单中的WndProcPreProcessMessage并让它执行计时器重置来实现相同的功能。您甚至可以创建一个基本形式(*)来执行计时器/重置事务并从中派生所有表单。对于真正的全局解决方案,请将计时器设置为静态。

(*)不要将其标记为摘要,否则表单设计师会将其标记为适合。