将光标困在 Window
Trap cursor in Window
我使用 DX11 在 C++ 中编写了自己的相机类。
目前我使用 WM_MOUSEMOVE 事件在场景中环顾四周。为防止光标脱离 window,每当 WM_MOUSEMOVE 事件发生时,我都会调用函数 SetCursorPos 使鼠标居中。
但是如果我移动鼠标非常快,光标就会离开 window。
一个解决方案是使用函数 ClipCursor,但这会导致当光标碰到矩形的边界时相机的旋转变得不稳定。所以ClipCursor解决了原来的问题,结果又是另一个问题。
你们有什么解决办法吗?
常规 windows 消息不是驱动精确控制的最佳解决方案。如您所见,它们继承自 OS 加速系统、剪辑并依赖于其他恶作剧。
接收鼠标输入的最佳API 是原始输入。它的优点是可以提供硬件可以提供的更好的 dpi 和轮询率,并且没有任何幕后操作。一旦你用这个读取鼠标,你就可以自由地使用 SetCapture 和 clipCursor 来防止不必要的点击另一个 window.
您可以在此处找到文档:https://msdn.microsoft.com/en-us/library/windows/desktop/ms645536(v=vs.85).aspx
对于 Windows 桌面应用程序,只需使用 ClipCursor 给出 window:
的矩形
RECT rect;
GetClientRect(mWindow, &rect);
POINT ul;
ul.x = rect.left;
ul.y = rect.top;
POINT lr;
lr.x = rect.right;
lr.y = rect.bottom;
MapWindowPoints(mWindow, nullptr, &ul, 1);
MapWindowPoints(mWindow, nullptr, &lr, 1);
rect.left = ul.x;
rect.top = ul.y;
rect.right = lr.x;
rect.bottom = lr.y;
ClipCursor(&rect);
确保有办法退出此模式,以便用户可以根据需要选择与其他 windows 进行交互。通常,当您转到 'pause' 菜单时,您会调用 ClipCursor(nullptr);
来摆脱这样的 'mouse-look' 行为。
您也可以在桌面应用程序中使用 "raw" 输入,请参阅 Taking Advantage of High-Definition Mouse Movement。请记住,原始输入对于相对移动 'mouse-look' 行为非常有效,但是 (a) 它不适用于远程桌面,并且 (b) 你不会得到 'pointer-ballistics' 这是一个使鼠标更灵活的非线性移动速率,因此在处理绝对移动时通常应坚持使用传统的 WM_MOUSE
消息。
For Universal Windows Platform, you can't use "raw" input as there's no equivalent to WM_INPUT
, but you do get high-precision data out of the MouseDevice.MouseMoved
event via the MouseDelta
property. You don't need to use ClipCursor
for relative movement in UWP, just turning off the cursor by setting the CoreWindow.PointerCursor
property to nullptr will prevent the system mouse position from being tracked. Again, you should restore the system cursor when you are in a 'pause' menu. See Developing mouse controls (DirectX and C++).
请参阅 DirectX 工具包 Mouse helper class and more importantly the implementation 文件。对于相对模式,它使用 ClipCursor
和 WM_INPUT
作为 Windows 桌面 Win32 实现。
我使用 DX11 在 C++ 中编写了自己的相机类。 目前我使用 WM_MOUSEMOVE 事件在场景中环顾四周。为防止光标脱离 window,每当 WM_MOUSEMOVE 事件发生时,我都会调用函数 SetCursorPos 使鼠标居中。 但是如果我移动鼠标非常快,光标就会离开 window。 一个解决方案是使用函数 ClipCursor,但这会导致当光标碰到矩形的边界时相机的旋转变得不稳定。所以ClipCursor解决了原来的问题,结果又是另一个问题。
你们有什么解决办法吗?
常规 windows 消息不是驱动精确控制的最佳解决方案。如您所见,它们继承自 OS 加速系统、剪辑并依赖于其他恶作剧。
接收鼠标输入的最佳API 是原始输入。它的优点是可以提供硬件可以提供的更好的 dpi 和轮询率,并且没有任何幕后操作。一旦你用这个读取鼠标,你就可以自由地使用 SetCapture 和 clipCursor 来防止不必要的点击另一个 window.
您可以在此处找到文档:https://msdn.microsoft.com/en-us/library/windows/desktop/ms645536(v=vs.85).aspx
对于 Windows 桌面应用程序,只需使用 ClipCursor 给出 window:
的矩形 RECT rect;
GetClientRect(mWindow, &rect);
POINT ul;
ul.x = rect.left;
ul.y = rect.top;
POINT lr;
lr.x = rect.right;
lr.y = rect.bottom;
MapWindowPoints(mWindow, nullptr, &ul, 1);
MapWindowPoints(mWindow, nullptr, &lr, 1);
rect.left = ul.x;
rect.top = ul.y;
rect.right = lr.x;
rect.bottom = lr.y;
ClipCursor(&rect);
确保有办法退出此模式,以便用户可以根据需要选择与其他 windows 进行交互。通常,当您转到 'pause' 菜单时,您会调用 ClipCursor(nullptr);
来摆脱这样的 'mouse-look' 行为。
您也可以在桌面应用程序中使用 "raw" 输入,请参阅 Taking Advantage of High-Definition Mouse Movement。请记住,原始输入对于相对移动 'mouse-look' 行为非常有效,但是 (a) 它不适用于远程桌面,并且 (b) 你不会得到 'pointer-ballistics' 这是一个使鼠标更灵活的非线性移动速率,因此在处理绝对移动时通常应坚持使用传统的 WM_MOUSE
消息。
For Universal Windows Platform, you can't use "raw" input as there's no equivalent to
WM_INPUT
, but you do get high-precision data out of theMouseDevice.MouseMoved
event via theMouseDelta
property. You don't need to useClipCursor
for relative movement in UWP, just turning off the cursor by setting theCoreWindow.PointerCursor
property to nullptr will prevent the system mouse position from being tracked. Again, you should restore the system cursor when you are in a 'pause' menu. See Developing mouse controls (DirectX and C++).
请参阅 DirectX 工具包 Mouse helper class and more importantly the implementation 文件。对于相对模式,它使用 ClipCursor
和 WM_INPUT
作为 Windows 桌面 Win32 实现。