陷阱光标在窗口中

时间:2016-04-21 19:49:01

标签: c++ windows camera mouse directx-11

我使用DX11在C ++中编写了自己的cameraclass。 目前我使用WM_MOUSEMOVE事件在场景中环顾四周。为了防止cursur离开窗口,每当发生WM_MOUSEMOVE事件时,我都会调用函数SetCursorPos使鼠标居中。 但如果我快速移动鼠标,光标就会离开窗口。 解决方法是使用ClipCursor函数,但是当光标碰到rect的边界时,这会导致相机的旋转动摇。所以ClipCursor解决了原来的问题,但在另一个问题上结束了。

你们有解决方法吗?

2 个答案:

答案 0 :(得分:5)

对于Windows桌面应用,只需使用ClipCursor给出窗口的矩形:

    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);

确保有办法逃避此模式,以便用户可以根据需要选择与其他窗口进行交互。通常,当您暂停'暂停时,请致电ClipCursor(nullptr);。菜单,以摆脱鼠标外观'像这样的行为。

你可以使用" raw"在桌面应用中输入,请参阅Taking Advantage of High-Definition Mouse Movement。请记住,原始输入对于相对运动和鼠标外观非常有效。行为,但(a)它不会在远程桌面上工作,并且(b)你不会得到指针弹道'这是一种非线性移动速率,使鼠标更加灵活,因此在处理绝对移动时通常应该坚持使用传统的WM_MOUSE消息。

  

对于通用Windows平台,您无法使用" raw"输入,因为它不等同于WM_INPUT,但您通过MouseDevice.MouseMoved属性从MouseDelta事件中获取高精度数据。您不需要在UWP中使用ClipCursor进行相对移动,只需通过将CoreWindow.PointerCursor属性设置为nullptr来关闭光标将阻止跟踪系统鼠标位置。同样,您应该在“暂停”时恢复系统光标。菜单。请参阅Developing mouse controls (DirectX and C++)

请参阅 DirectX工具包 Mouse帮助程序类,更重要的是implementation文件。对于相对模式,它为Windows桌面Win32实现使用ClipCursorWM_INPUT

答案 1 :(得分:2)

The regular windows message are not the best solution to drive precise controls. They inherit from the OS acceleration system, clipping and depends on other shenanigans as you can see.

The best API to receive mouse inputs is Raw Input. It has the advantage to expose the better dpi and polling rate the hardware can provide and is free of any under the hood manipulation. Once you read the mouse with this, you are free to use SetCapture and clipCursor to prevent unwanted click to an other window.

You can find the documentation here : https://msdn.microsoft.com/en-us/library/windows/desktop/ms645536(v=vs.85).aspx