原始输入法中的鼠标位置

发布于 2024-12-26 02:48:18 字数 130 浏览 0 评论 0原文

我正在尝试使用原始输入法获取鼠标位置。在 RAWMOUSE 结构中,我总是获取 MOUSE_MOVE_RELATIVE 值作为 usFlags,这意味着我获取最后鼠标位置的相对值。但我想要鼠标的绝对位置。如何从原始输入中获​​取鼠标的绝对位置值?

I am trying to get mouse position by using Raw input method. In the RAWMOUSE structure am always getting value MOUSE_MOVE_RELATIVE as usFlags that means am getting relative value of last mouse position. but i want absolute position of mouse. how to get absolute position value of mouse from Raw input ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千鲤 2025-01-02 02:48:18

[很奇怪看到一个 9 年前未回答的问题成为 google 搜索结果的热门,所以我会提供一个答案..迟到总比不到好!]

在原始输入 API 的级别,您将获得原始的水平/垂直运动鼠标设备——鼠标在硬件级别报告的内容。

根据文档(我尚未验证),这些增量 X/Y 值尚未由桌面鼠标速度/加速/减速设置处理。因此,即使您从已知的绝对位置开始跟踪增量,您也会很快偏离 Windows 在屏幕上定位鼠标光标的位置。

文档中不清楚的是报告这些相对 X/Y 值的单位或比例。如果能以某种方式标准化那就太好了,但我怀疑这取决于鼠标的 DPI 分辨率。 (我会找到一个具有可调节 DPI 的鼠标来测试,如果没有人先编辑我的话,然后报告回来。)

编辑/更新:我拿到了一个具有可调节 DPI 的鼠标..做了一些粗略的测试,足以确认粗略的结果lLastX/Y 值的比例似乎与硬件 DPI 相匹配。鼠标处于 1200 dpi 模式时,从左向右物理移动 1 英寸,生成 lLastX 值的净和 ~= 1200。

[Weird to see a 9 year old unanswered question as a top google search result, so I'll offer an answer.. better late than never!]

At the level of Raw Input API, you are getting the raw horizontal/vertical movement of the mouse device -- what the mouse reports at the hardware level.

According to the docs (I haven't verified) these delta X/Y values are not yet processed by the desktop mouse speed/acceleration/slowdown settings. So even if you started tracking the deltas from a known absolute location, you would quickly drift away from where Windows is positioning the mouse cursor, on-screen.

What's not clear from the docs, is what units or scale these relative X/Y values are reported in. It would be nice if it were somehow normalized, but I suspect it depends on the DPI resolution of your mouse. (I will find a mouse with adjustable DPI to test, and report back, if no one edits me first.)

Edit/Update: I got my hands on a mouse with adjustable DPI .. did some crude testing, enough to confirm the rough scale of the lLastX/Y values seems to match the hardware DPI.. eg. with the mouse in 1200 dpi mode, moving it physically 1 inch from left to right, generates a net sum of lLastX values ~= 1200.

橘寄 2025-01-02 02:48:18

RAWMOUSE 具有与 Windows 从鼠标硬件接收的完全相同的值(可能是 HID USB/蓝牙或 i8042 PS/2 鼠标等)。通常鼠标发送相对移动,但有些可以发送绝对移动 - 例如触摸屏、RDP 鼠标(耶!)。

因此,如果您需要绝对鼠标位置(例如游戏菜单),您可以使用 GetCursorPos API 用于获取 Windows 渲染的光标在屏幕上的坐标。

但它与 RAWMOUSE 中使用 MOUSE_MOVE_ABSOLUTE 标志发送的内容不同。

MOUSE_MOVE_ABSOLUTE 是设备空间(而不是屏幕空间)中 0..65535 范围内的鼠标移动。下面是一些如何将其转换为屏幕空间的代码:

if (mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
{
    RECT rect;
    if (mouse.usFlags & MOUSE_VIRTUAL_DESKTOP)
    {
        rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
        rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
        rect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
        rect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    }
    else
    {
        rect.left = 0;
        rect.top = 0;
        rect.right = GetSystemMetrics(SM_CXSCREEN);
        rect.bottom = GetSystemMetrics(SM_CYSCREEN);
    }

    int absoluteX = MulDiv(mouse.lLastX, rect.right, USHRT_MAX) + rect.left;
    int absoluteY = MulDiv(mouse.lLastY, rect.bottom, USHRT_MAX) + rect.top;
    ...
}
else if (mouse.lLastX != 0 || mouse.lLastY != 0)
{
    int relativeX = mouse.lLastX;
    int relativeY = mouse.lLastY;
    ...
}
...

额外: 这里是虚拟屏幕MOUSE_VIRTUAL_DESKTOP标志上的信息。

RAWMOUSE have exact same values that Windows received from mouse hardware (it could be HID USB/Bluetooth or i8042 PS/2 mouse etc). Usually mouses are sending relative movement, but some could send absolute - for example touch screens, RDP mouse (yay!).

So if you need absolute mouse pos (for example for game menu) you can use GetCursorPos API to get coords of Windows-rendered cursor on the screen.

But its not the same thing as sent with MOUSE_MOVE_ABSOLUTE flag in RAWMOUSE.

MOUSE_MOVE_ABSOLUTE is mouse movement in 0..65535 range in device-space, not screen-space. Here is some code how to convert it to screen-space:

if (mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
{
    RECT rect;
    if (mouse.usFlags & MOUSE_VIRTUAL_DESKTOP)
    {
        rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
        rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
        rect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
        rect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    }
    else
    {
        rect.left = 0;
        rect.top = 0;
        rect.right = GetSystemMetrics(SM_CXSCREEN);
        rect.bottom = GetSystemMetrics(SM_CYSCREEN);
    }

    int absoluteX = MulDiv(mouse.lLastX, rect.right, USHRT_MAX) + rect.left;
    int absoluteY = MulDiv(mouse.lLastY, rect.bottom, USHRT_MAX) + rect.top;
    ...
}
else if (mouse.lLastX != 0 || mouse.lLastY != 0)
{
    int relativeX = mouse.lLastX;
    int relativeY = mouse.lLastY;
    ...
}
...

Bonus: here is info on the virtual screen MOUSE_VIRTUAL_DESKTOP flag.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文