鼠标双击响应的实现「建议收藏」

鼠标双击响应的实现「建议收藏」今天在实现鼠标双击响应的时候,遇到了一些问题,下面是对我很有帮助的解释:首先对鼠标双击事件原理做一个简单的了解:在Windows平台上,鼠标左键的按下、松开、快速的两次点击会产生WM_LBUTTONDOWN、WM_LBUTTONUP和WM_LBUTTONDBLCLK消息,但是Windows根据什么来区分连续的两次鼠标按键操作,是两次独立的单击,还是一次双击呢?最近在解决一个问题时,通过使用…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

今天在实现鼠标双击响应的时候,遇到了一些问题,下面是对我很有帮助的解释:

首先对鼠标双击事件原理做一个简单的了解:

在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捕获后续的鼠标消息,转发到别的窗口,导致原窗口不能识别双击,而这个双击可能正是期望的。

上面是对鼠标双击消息的实现原理 做的一个简单介绍

下面是实现的一个例子:

在鼠标左键按下函数内做判断(计算两次鼠标左键点击的时间),如果满足条件则调用,则响应鼠标双击消息WM_LBUTTONDBLCLK,对应的处理函数为OnLButtonDblClk()

代码如下:

double m_ClickInterval=0;
void CMFCOCCView::OnLButtonDown(UINT nFlags, CPoint point)
{
	SaveSelectObject();                 //此处是无关处理代码
	myXmin=point.x;  myYmin=point.y;
	myXmax=point.x;  myYmax=point.y;


	if(GetTickCount() - m_ClickInterval < GetDoubleClickTime())//鼠标双击时间
	{
		OnLButtonDblClk(nFlags, point);
		return;
	}

	m_ClickInterval = GetTickCount();        
}


void CMFCOCCView::OnLButtonDblClk(UINT nFlags, CPoint point)  //
{
	SwitchSelectFace();
}

简单的测试了一下效果,可以实现。

参考文章:http://blog.csdn.net/cnike/archive/2009/11/25/4870064.aspx

http://blog.sina.com.cn/s/blog_634a11720100oych.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/189520.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux yum源配置文件_yum源配置文件详解

    linux yum源配置文件_yum源配置文件详解linux配置yum源的三种方法

    2022年8月13日
    7
  • java中字符串String格式转化成json格式[通俗易懂]

    java中字符串String格式转化成json格式[通俗易懂]一、将Sting转为Json在开发中,经常是前端发送一串数据过来之后,是通过一个参数带着一串值过来,这一串值是String格式的,但是里面的内容其实是json格式类型的,所以拿到值之后就要将该值转化成json格式,然后获取里面指定的key就可以拿到该值了。JSONObjectjsonObject=JSON.parseObject(tt);这样就可以将一串参数转化成json对象了,然后通过下面指定的key获取特定的值,如下面所示Stringimei=(String)jsonObjec

    2022年8月23日
    14
  • thinkphp漏洞检测工具_thinkphp渗透

    thinkphp漏洞检测工具_thinkphp渗透0x00前言由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的情况下可能的getshell漏洞,受影响的版本包括5.0和5.1版本,推荐尽快更新到最新版本。0x01影响范围5.x<5.1.31,<=5.0.230×02漏洞分析Thinkphpv5.0.x补丁地址:https://github.com/top-think/framework/com…

    2025年8月6日
    2
  • Java中的注解 – @NotNull「建议收藏」

    Java中的注解 – @NotNull「建议收藏」比如说,你写了一个后台系统,接收用户的请求,经过运算后返回结果,很通用的一个实现方案。假定所有的方法都需要校验参数是否为空,不然就可能有NullPointerException,如果系统有N个接口,每个接口参数有M个,你需要写N*M个if判断语句。如if(StringUtils.isBlank(request.getA())){thrownewIllegalArgume…

    2022年5月30日
    37
  • java8 lambada表达式Collectors.groupingBy分组顺序无序[通俗易懂]

    java8 lambada表达式Collectors.groupingBy分组顺序无序[通俗易懂]最近有个需求就是按照uuid进行分组排序,虽然最初的list是按照时间排序的,但是分组后一直数据都是错乱的,后来查了资料可以看到groupingBy有三个参数,第一个参数就是key的Function了,第二个参数是一个map工厂,也就是最终结果的容器,一般默认的是采用的HashMap::new,最后一个参数很重要是一个downstream,类型是Collector,也是一个收集器,那就是说,这三个…

    2022年8月22日
    8
  • java interface 里面的抽象方法默认public[通俗易懂]

    java interface 里面的抽象方法默认public[通俗易懂]①interface里声明的方法,会自动在方法名之前加上publicabstract②interface里声明的field,会自动在field之前加上publicstaticfinal这是因为,interface存在的目的就是要和外界公开如要在别的类里,实现interface里面的,抽象方法。这个方法的修饰符,也一定要public.也就是说,不能用比public还要受限制的修饰符。…

    2022年10月7日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号