我正在尝试使用此article中的代码,让您知道您的应用何时闲置。
如果您的应用程序只有一个表单,则此代码非常有用。您在其上调用Application2.Run(myOnlyForm)
,所有消息都通过Application2中的过滤器进行路由。
但是,如果您在任何时候致电mySecondForm.ShowDialog()
该对话框未通过Application2过滤其消息。
是否有任何方法(没有不良副作用)让mySecondForm
上的消息通过`Application2'事件过滤器?
我试过了:
mySecondForm.ShowDialog
更改为Application2.Run(mySecondForm)
。
mySecondForm.ShowDialog
更改为Application2.ShowDialog(mySecondForm)
。
mySecondForm.ShowDialog
更改为Application2.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
答案 0 :(得分:2)
我可以解释这种行为,但可能不提供直接解决方案。
当您在任何表单上调用Show时,表单的事件将由默认消息泵(通过调用Run设置)进行处理。当您调用ShowDialog时,目标表单将获得自己独立的消息泵。
现在你添加的过滤器驻留在主消息泵中,它正在查看那里的所有消息,但ShowDialog调用规避了 - 发送到对话框的消息永远不会到达过滤器。
现在我们确实添加了Application2.ShowDialog调用来尝试解决这个问题,但说实话,当我编写整个Application.Run/IMEssageFilter实现时,我没有做ShowDialog的解决方法而且我真的不喜欢知道它的实施情况。根据你的报告,我会冒一个“不好”的猜测,虽然它确实不是一个简单的问题需要解决。这个问题的根源在于,当您调用Show和ShowDialog时,SDF无法控制BCL中发生的事情 - 我们只是试图坐在它上面并提供我们可以做的最佳行为。在这种情况下,这是有问题的。
你是偶然的,不能使用ShowDialog的调用,而只是使用Show加上保持TopMost形式的东西?这将允许过滤器获取伪对话的所有消息。我可以直接想到的另一个选项是Dialogs的基类,它会通知回过滤机制,但开始变得难以控制。
答案 1 :(得分:0)
请原谅我,但为什么你要为这么简单的事情经历所有这些疯狂的麻烦?查看您关联的文章,它所做的只是启动计时器,并在每次WM_KEYUP
,WM_MOUSEMOVE
或WM_LBUTTONUP
事件时重置该计时器。
您可以通过覆盖表单中的WndProc
或PreProcessMessage
并让它执行计时器重置来实现相同的功能。您甚至可以创建一个基本形式(*)来执行计时器/重置事务并从中派生所有表单。对于真正的全局解决方案,请将计时器设置为静态。
(*)不要将其标记为摘要,否则表单设计师会将其标记为适合。