一个关于Windows下SetCursorPos和GetCursorPos的小坑

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个关于Windows下SetCursorPos和GetCursorPos的小坑相关的知识,希望对你有一定的参考价值。

 这两天在做一个编辑特定格式Mesh的小工具,需要检查鼠标的移动,一般来说可以用WM_MOUSEMOVE事件解决的,但是我为了省事用了定时查询+设置的方式,也就是:

 1 void Frame(void)
 2 {
 3     //do something else...
 4     
 5     POINT cursorPos;
 6     GetCursorPos(&cursorPos);
 7     curMoveX = cursorPos.x - cursorBaseX;
 8     curMoveY = cursorPos.y - cursorBaseY;
 9     cursorPos.x = cursorBaseX, cursorPos.y = cursorBaseY;
10     SetCursorPos(&cursorPos);
11     
12     //do something else
13 }

很简单的逻辑,就是定期把Cursor设置到指定位置,然后过一会儿来检查Cursor跑到哪里了,看看这一段时间里Cursor移动了多少,不断重复这个过程就能得知鼠标怎么移动的(只是个小工具所以就这样实现了)。但是跑起来的时候遇到一个诡异的问题:在我没有移动鼠标的情况下,得到的Cursor位置变化量居然不是0(拔掉鼠标还是有这个现象,不是鼠标的问题),网上没有查到这个问题,我对Windows编程本来就不熟悉也不可能去仔细看文档(至少GetCursorPos和SetCursorPos的条目里没提这种现象),所以就搁下了。

后来想了想,问题可能出在我SetCursorPos的时候。于是我在Set过后立刻Get一次,然后比对Set和Get得到的值,然后发现有的时候这两个值竟然不一样(在未移动鼠标的情况下),差异也不大,但是足以干扰程序运行。知道了这一点,立刻就得出几种解决方法:一种是老老实实在窗口事件函数里用WM_MOUSEMOVE,相当于避开了这个问题;一种是当检测到的Cursor移动速度过慢的时候忽略这一移动,这样虽然能工作但不怎么漂亮;然后就是把Get和Set的量分开存储,每次Set之后立刻Get一次,下一次计算偏移量的时候就用这一次Get的值。最后我用了第三种方法,算是解决了问题。

问题本身不困难,但是算是个小坑,所以记录一下。关于导致问题的原因,我现在暂不清楚,以后学习的过程中会留意。初步猜测是在我SetCursorPos的时候系统并没有严格地把Cursor移动到我指定的位置,而是由于单位不同或者精度问题把Cursor设置到了离我指定的位置很近的另一个位置(比方说,偏移了一个像素),结果就是我没动鼠标,却发现Get和Set的值有时不一样了。

以上是关于一个关于Windows下SetCursorPos和GetCursorPos的小坑的主要内容,如果未能解决你的问题,请参考以下文章

光标通过面部中心移动?

关于windows下驱动程序开发

关于windows下C++程序移植到linux下的一些头文件对应问题

关于ffmpeg和OpenCV在windows下运行要添加的环境变量

关于MongoDB在windows下安装解压版

关于windows下activeMQ的安装