关于动态监测鼠标移入移出窗体问题的分析

文章移至这里

最近项目中用到需要动态监测鼠标是否移入或者移出窗体,用来控制窗体的显示和隐藏,常规思路:使用系统的消息WM_MOUSELEAVE(鼠标离开)和WM_MOUSEHOVER(鼠标进入)来检测,具体做法就是在鼠标移动消息中增加如下代码:

<span style="font-size:18px;"> //打开鼠标进入与离开的消息监听
TRACKMOUSEEVENT tme; 
tme.cbSize = sizeof(tme); 
tme.hwndTrack = m_hWnd; 
tme.dwFlags = TME_LEAVE | TME_HOVER; 
tme.dwHoverTime = 1; 
m_bTracking = _TrackMouseEvent(&tme); </span>
具体代码请参考这里:http://blog.csdn.net/rankun1/article/details/51659679

但是,这样做有一个问题,就是当窗体上面有子窗体的时候,鼠标移动到子窗体上,监听消息就会认为鼠标已经离开主窗体(这是正确的),但并不是我想要的效果,我想要的是只要鼠标在窗体上,不管是子窗体还是父窗体,只要在父窗体区域内,都认为鼠标还在窗体上,没有离开,于是就在WM_MOUSELEAVE和WM_MOUSEHOVER消息中增加判断鼠标位置代码,以此判断鼠标是否离开窗体:

<span style="font-size:18px;">CPoint point;
	CRect rectWindow;
	BOOL bIn = FALSE;
	GetWindowRect(rectWindow);
	GetCursorPos(&point);
	if (rectWindow.PtInRect(point))
	{
		bIn = TRUE;
	}</span>

这样貌似可以了,但是,当我快速把鼠标从窗体子控件上移出窗体的时候,有时候会捕获不到鼠标离开的消息,猜测原因可能是鼠标移动消息没有触发或者鼠标消息触发是周期性的,带着这样的疑问继续查找鼠标移动消息的资料,查资料发现:WINDOWS系统并不是在鼠标每移动一个像素时都产生WM_MOUSEMOVE消息,但奇怪的是,我鼠标移动的距离已经超出了N个像素了,为什么还没有触发那,或者触发了没有检测到鼠标离开消息,还是鼠标移动消息也是周期性的,有自己的时钟周期,不得而知,总之,上面的方案没有能解决我想要的效果。

在查检测鼠标移入移出窗体的时候,也有人提到用鼠标钩子的,处于安全考虑,没敢用,进程你的钩子钩不到鼠标移出的消息,全局的钩子还容易被杀毒软件拦截,认为是病毒误报。

后来实在没办法,就选择了一个笨方法:定时器,定时执行检查鼠标是否在窗体上,代码如下:

<span style="font-size:18px;">static int nLastStatue = -1;
	CPoint point;
	CRect rectWindow;
	BOOL bIn = FALSE;

	GetWindowRect(rectWindow);
	GetCursorPos(&point);

	if (rectWindow.PtInRect(point))
	{
		bIn = TRUE;
	}

	if (bIn && nLastStatue != 1)
	{
		nLastStatue = 1;
		//显示窗体
	}else if (!bIn && nLastStatue != 0)
	{
		nLastStatue = 0;
		//隐藏窗体
	}
</span>

当窗体失去焦点的适合也要处理一下隐藏窗体代码,这样基本就能实现自己想要的效果了

也不知道自己分析的对不对,如果有问题,请留言指正,谢谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

daiafei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值