zl程序教程

您现在的位置是:首页 >  前端

当前栏目

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

响应 实现 建议 收藏 鼠标 双击
2023-06-13 09:14:49 时间

大家好,又见面了,我是你们的朋友全栈君。

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

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

在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.cn/189520.html原文链接:https://javaforall.cn