我正在使用WM_MOUSEMOVE来改变鼠标位置。例如,当模拟“旋钮”时,希望让用户在没有任何限制的情况下用鼠标上下移动。在这种情况下,我隐藏光标并使用SetCursorPos在每次用户移动时更改其位置,并仅检测与原始位置的差异。
不幸的是它似乎不起作用 - 如果我设置鼠标位置,它有时会起作用,但有时会离开一个或多个像素,这是错误的。甚至更大的麻烦是,在呼叫之后,另一个WM_MOUSEMOVE似乎被传递,遗憾的是,它想要将光标再次移回原始位置。因此,它会以无限循环结束或设置鼠标位置并接收消息,直到用户释放鼠标按钮。
什么是正确的方法或问题是什么?
答案 0 :(得分:2)
原始输入系统可以执行此操作 - 它允许您注册未剪切或限制在屏幕边界的原始鼠标输入。
一般来说,您使用RegisterRawInputDevices()
注册原始输入。然后,您的窗口将收到WM_INPUT
消息,您可以使用GetRawInputData()
功能处理这些消息。
有关示例,请参阅Using Raw Input。
答案 1 :(得分:0)
我隐藏光标并使用SetCursorPos在每次用户移动时改变其位置并仅检测与原始位置的差异。
这是完全错误的。相反,使用SetCapture()
捕获鼠标。即使鼠标位于该窗口之外,所有移动都将报告为WM_MOUSEMOVE
消息,其坐标相对于指定窗口,直到您释放捕获为止。
答案 2 :(得分:0)
要求用户连续移动鼠标,即使在光标达到屏幕限制之后,对于用户界面,恕我直言也是一个非常糟糕的主意。
有些游戏有另一种方法:当鼠标达到“限制”时,游戏进入一种特殊模式:即使用户不喜欢,事物看起来也正好像一样正好在鼠标移动移动它。当用户想要退出该模式时,他只需移动限制的鼠标。
这样做需要一个计时器,当鼠标达到某个限制时会启动,定期执行代码,就像鼠标移动一样。当真正的鼠标移动使其离开极限时,计时器停止。
答案 3 :(得分:0)
好的人,所以我找到了一个简单的解决方案:
主要问题是SetCursorPos可能没有准确设置坐标,我想这是因为某些高分辨率处理,但它可能是一个错误。无论如何,如果SetCursorPos没有正确设置坐标(但在x和/或y中为+ -1),它也会将WM_MOUSEMOVE发送到目标窗口。因此,窗口执行与之前完全相同的操作,并且这种操作会继续进行。
所以解决方法就是在SetCursorPos之后立即删除所有WM_MOUSEMOVE消息:
MSG msg;
while (::PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) { };
然后使用:: GetCursorPos检索当前鼠标光标pos。 这很丑,但似乎解决了这个问题。基本上似乎在鼠标的某个位置,系统总是在任一坐标中添加或减去1,所以这样你让系统做奇怪的事情并使用新坐标而不试图说服系统你的坐标是正确的: )。