我需要在我的软件中使用应用程序空闲时间。出于这个原因,我创建了一个帮助类ApplicationIdleHelper
,它实现了IMessageFilter
接口。
这很好用,如果我的应用程序闲置一段时间,我会使用以下代码行显示DevExpress WaitForm
:
SplashScreenManager.ShowForm(typeof(WaitForm));
在此WaitForm
中,我向用户显示有关在后台执行操作的信息。如果用户移动鼠标或按下某些键,我会关闭WaitForm,如下所示:
SplashScreenManager.CloseForm();
以下是步骤中解释的问题:
WaitForm
。MouseMove message
方法中出现PreFilterMessage
了吗?但为什么?老鼠没动。没有按键?因为我的应用程序认为MouseMove message
,用户会做一些输入并自动关闭WaitForm
。如果我关闭WaitForm
,行为相同。
这是一个示例应用程序,因此您应该能够重现该行为: https://drive.google.com/file/d/0BxabrokJG-OWV3FLV2hNNVk5NjQ/view?usp=sharing
DevExpress文档说:
等待表单和启动画面由启动画面管理器显示 在另一个线程中。
也许这与这种行为有关?
希望有人可以解释我,为什么我在显示或关闭MouseMove message
之后,在PreFilterMessage
函数中找到了WaitForm
。
提前谢谢。
答案 0 :(得分:2)
最可能的原因是鼠标对环境噪音很敏感。鼠标完全有可能经历一点点抖动,导致它报告非常小的运动,最终导致零位变化。或者,这未经验证,系统上的Windows或其他软件可能会生成额外的鼠标移动消息,以确保每个人都与当前鼠标位置保持同步。
无论哪种方式,最稳定的解决方案是决定你认为“真实”的运动量(见下面的threshold
),然后:
每次收到WM_MOUSEMOVE
消息(或MouseMove事件)时,都会计算该动作的数量,如:
Point cached; // from when you went to sleep
Point current; // determined from the window message/event
double move = Math.Sqrt(Math.Pow(cached.X - current.X, 2) +
Math.Pow(cached.Y - current.Y, 2))
if (move > threshold)
{
// Wake up
}
else
{
// Ignore and optionally update the cached position
// in case the mouse is slowly drifting
}
(请注意,您不一定需要计算实际距离,您可以使用ΔX+ΔY)
每当您处理硬件时,您需要准备好向它发送您不期望的更新。例如,按下按钮可能导致物理接触反弹,从而导致电气水平的多个按压/断开信号。大多数情况下,硬件设计用于过滤噪声,但有时会渗透。