我的软件需要应用程序空闲时间。因此,我创建了一个帮助类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
。先感谢您。
最佳答案
造成这种情况的最可能原因是鼠标对环境噪声敏感。鼠标完全有可能会出现一点抖动,从而导致鼠标报告很小的运动,最终使位置变化为零。另外,未经验证,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)
无论何时使用硬件,都需要做好准备以将不需要的更新发送给您。例如,按下一个按钮可能会导致物理接触反弹,从而在电气水平上导致多次按下/断开信号。在大多数情况下,硬件是设计用来过滤噪声的,但有时会渗入。
关于c# - DevExpress WaitForm和PreFilterMessage-意外的MouseMove消息,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32906422/