一,转自
https://blog.csdn.net/cnike/article/details/4870064
在Windows平台上,鼠标左键的按下、松开、快速的两次点击会产生WM_LBUTTONDOWN、WM_LBUTTONUP和WM_LBUTTONDBLCLK消息,但是Windows根据什么来区分连续的两次鼠标按键操作,是两次独立的单击,还是一次双击呢?最近在解决一个问题时,通过使用Spy++和查阅MSDN,弄清楚了这个问题。简单总结如下:
Windows根据两个条件来做这个区分:
(1)双击的时间间隔
这是很容易想到的。更准确的说法是这样的,两次单击会产生四个鼠标点击消息,如果第三个消息(第二次按下)和第二个消息(第一次弹起引发的WM_LBUTTONUP)间隔短于指定值,则把第三个消息处理成WM_LBUTTONDBLCLK消息;第四个消息照旧,WM_LBUTTONUP。
这个指定的时间间隔,在Windows XP SP2上缺省是
0.5秒
,其他操作系统可能相同。通过::GetDoubleClickTime调用可以得到这个值。
这个值是可以设置的。有两种方法设置这个值: ::SetDoubleClickTime调用,或者以SPI_SETDOUBLECLICKTIME为第一个参数调用::SystemParametersInfo。设置的结果对系统中其他的应用程序也起作用。
(2)两次鼠标击点的空间距离
在第一次点击时,Windows以击点为中心,检测一个矩形区域,如果第二次点击不落在这个区域内,那就不把第三个消息算作WM_LBUTTONDBLCLK消息。
这个矩形区域的缺省大小,在Windows XP SP2上缺省是
4pt×4pt
。可以以SM_CXDOUBLECLK或SM_CYDOUBLECLK为参数调用::GetSystemMetrics得到。
这个值也是可以设置的。设置的方法是通过SPI_SETDOUBLECLKWIDTH或SPI_SETDOUBLECLKHEIGHT为第一个参数来调用::SystemParametersInfo。设置的结果对系统中其他的应用程序也起作用。
因此,连续两次按下和弹起鼠标左键:
如果不符合以上两个条件,产生的消息是:
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDOWN
WM_LBUTTONUP
如果符合以上两个条件,产生的消息则是:
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBLCLK
WM_LBUTTONUP
以上结论还隐含两个要点:
(1)不管是算作两次连续的单击,还是一次双击,第一、二和四个消息都是不受影响的。在接受到一个双击消息之前,应用程序总是会先收到一个WM_LBUTTONDOWN和一个WM_LBUTTONUP消息,之后是WM_LBUTTONUP消息。应用程序应该对各种消息做出恰当的处理;
(2)第二个消息和第三个消息是关键,必须被连续发到同一个窗口过程才能被处理。开发中常见的一个错误是这样的:在处理第一个消息WM_LBUTTONDOWN或者WM_LBUTTONUP时,通过SetCapture捕获后续的鼠标消息,转发到别的窗口,导致原窗口不能识别双击,而这个双击可能正是期望的。
一,转自https://blog.csdn.net/cnike/article/details/4870064在Windows平台上,鼠标左键的按下、松开、快速的两次点击会产生WM_LBUTTONDOWN、WM_LBUTTONUP和WM_LBUTTONDBLCLK消息,但是Windows根据什么来区分连续的两次鼠标按键操作,是两次独立的单击,还是一次双击呢?最近在解决一个问题时,通过使用Spy...
本节视频教程封装的命令有:SetKeypadDelay(type,delay)、SetMouseDelay(type,delay)、SetMouseSpeed(speed)、SetSimMode(mode)、WaitKey(vk_code,time_out)
、WheelDown()、WheelUp()
视频链接:
511遇见大漠模块制作
模块源码:
在WPF
鼠标
事件
中,我们可以通过
事件
参数的
ClickCount 属性来
判断
鼠标
连续点击的次数。那么
鼠标
在多久的
时间间隔
内点击才被算作是连续点击呢?这个是可以在系统里
设置
的。
在Window7系统里,在控制面板中找到
鼠标
,选择“
双击
速度”那一项。
在Window8系统里也是一样需要找到
鼠标
点击。
鼠标
双击
的
判断
时间
可以
设置
从200毫秒到900毫秒。
鼠标
过滤驱动能修复这个Bug的原理是:
鼠标
在点击时,会触发一个硬件中断,然后发消息给过滤驱动,这时我在驱动中
判断
两次点击的
时间间隔
,如果小于100ms则认为是硬件故障,屏蔽掉该此操作
关于
鼠标
过滤,这里主要说一下IRP的取消。取消IRP还真是花费了我很多
时间
,原因是IoCancelIrp这个函数会直接回调完成例程,然后破坏了链表的结构,导致了蓝屏。(我在MyRead例程里面把IRP插入到一个链表里面,然后在MyReadComplete里面,从链表里面移除该IRP)
这样只好,在取消IRP时,复制一个新的链表,在新的链表里面对IRP进行取消,这样总算是OK了
好了,废话说完了,大家看代码吧:
普通
鼠标
使用
时间
长了,会出现误动作的现象,具体就是
鼠标
左键单击,系统自动认为是
双击
。和按键虚动有一定的关系,在不更换按键或
鼠标
的情况下,使用本程序可有效解决这个问题。
利用
时间
差,
判断
鼠标
的动作是真的
双击
,还是假的
双击
。
当两次按键动作
间隔
小于100ms时,认为是误动作,屏蔽动作。