关于动态监测鼠标移入移出窗体问题的分析
2016-09-13 10:57
190 查看
文章移至这里
最近项目中用到需要动态监测鼠标是否移入或者移出窗体,用来控制窗体的显示和隐藏,常规思路:使用系统的消息WM_MOUSELEAVE(鼠标离开)和WM_MOUSEHOVER(鼠标进入)来检测,具体做法就是在鼠标移动消息中增加如下代码:
但是,这样做有一个问题,就是当窗体上面有子窗体的时候,鼠标移动到子窗体上,监听消息就会认为鼠标已经离开主窗体(这是正确的),但并不是我想要的效果,我想要的是只要鼠标在窗体上,不管是子窗体还是父窗体,只要在父窗体区域内,都认为鼠标还在窗体上,没有离开,于是就在WM_MOUSELEAVE和WM_MOUSEHOVER消息中增加判断鼠标位置代码,以此判断鼠标是否离开窗体:
这样貌似可以了,但是,当我快速把鼠标从窗体子控件上移出窗体的时候,有时候会捕获不到鼠标离开的消息,猜测原因可能是鼠标移动消息没有触发或者鼠标消息触发是周期性的,带着这样的疑问继续查找鼠标移动消息的资料,查资料发现:WINDOWS系统并不是在鼠标每移动一个像素时都产生WM_MOUSEMOVE消息,但奇怪的是,我鼠标移动的距离已经超出了N个像素了,为什么还没有触发那,或者触发了没有检测到鼠标离开消息,还是鼠标移动消息也是周期性的,有自己的时钟周期,不得而知,总之,上面的方案没有能解决我想要的效果。
在查检测鼠标移入移出窗体的时候,也有人提到用鼠标钩子的,处于安全考虑,没敢用,进程你的钩子钩不到鼠标移出的消息,全局的钩子还容易被杀毒软件拦截,认为是病毒误报。
后来实在没办法,就选择了一个笨方法:定时器,定时执行检查鼠标是否在窗体上,代码如下:
当窗体失去焦点的适合也要处理一下隐藏窗体代码,这样基本就能实现自己想要的效果了
也不知道自己分析的对不对,如果有问题,请留言指正,谢谢!!!
最近项目中用到需要动态监测鼠标是否移入或者移出窗体,用来控制窗体的显示和隐藏,常规思路:使用系统的消息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>
当窗体失去焦点的适合也要处理一下隐藏窗体代码,这样基本就能实现自己想要的效果了
也不知道自己分析的对不对,如果有问题,请留言指正,谢谢!!!
相关文章推荐
- 鼠标移入显示,移出隐藏动态网页实现
- 动态添加class名,改变标签样式(包含鼠标移入、移出及点击事件)
- 解决VMware vSphere Client与本机的鼠标无缝移出移入、剪贴板共享、共享文件夹等问题,实现虚拟机上虚拟硬件的驱动
- 鼠标移入事件 动态元素 事件委托 鼠标移入移出 弹出对话框事件
- [VB.NET]送分问题!!!我在窗体上利用鼠标动态的画矩形,就像QQ截图的矩形选框那样.可是怎么清除之前画的矩形留下的痕迹?
- 鼠标的移入移出问题 e.relatedTarget
- js中鼠标移入移出碰到的问题
- 关于Iris网络流量分析监测工具对本地TCP无法抓包的问题
- 关于页面动态创建多个highcharts图表所产生的问题汇总以及分析
- 关于Laszlo(2.x 3.0)无法动态加载资源的问题
- 关于N皇后问题高效试探回溯算法的分析
- [Delphi]让窗体感知鼠标的进入与移出并自动隐藏与显示窗口
- 动态控件的状态问题的分析 概括
- 关于非顶级窗体的输入栏控件焦点问题
- 关于"建立空文档失败"的问题的分析!(转载)
- 实现DataGrid的某一行随着鼠标的移入移出而改变颜色
- WEB窗体用户控件的变量问题(动态)
- 求救(关于窗体调用的问题)
- 关于动态生成列的DATAGRID不能出发模板列的时间问题
- 菜鸟求救!!!关于用popupmenu弹出新窗体的问题