RAWMOUSE 结构 (winuser.h)

包含有关鼠标状态的信息。

语法

typedef struct tagRAWMOUSE {
  USHORT usFlags;
  union {
    ULONG ulButtons;
    struct {
      USHORT usButtonFlags;
      USHORT usButtonData;
    } DUMMYSTRUCTNAME;
  } DUMMYUNIONNAME;
  ULONG  ulRawButtons;
  LONG   lLastX;
  LONG   lLastY;
  ULONG  ulExtraInformation;
} RAWMOUSE, *PRAWMOUSE, *LPRAWMOUSE;

成员

usFlags

类型:USHORT

鼠标状态。 此成员可以是以下任何合理的组合。

价值 意义
MOUSE_MOVE_RELATIVE
0x00
鼠标移动数据相对于最后一个鼠标位置。 有关鼠标运动的详细信息,请参阅以下“备注”部分。
MOUSE_MOVE_ABSOLUTE
0x01
鼠标移动数据基于绝对位置。 有关鼠标运动的详细信息,请参阅以下“备注”部分。
MOUSE_VIRTUAL_DESKTOP
0x02
鼠标坐标映射到虚拟桌面(用于多个监视器系统)。 有关鼠标运动的详细信息,请参阅以下“备注”部分。
MOUSE_ATTRIBUTES_CHANGED
0x04
鼠标属性已更改;应用程序需要查询鼠标属性。
MOUSE_MOVE_NOCOALESCE
0x08
此鼠标移动事件未合并。 默认情况下,鼠标移动事件可以合并。
Windows XP/2000:不支持此值。

DUMMYUNIONNAME

DUMMYUNIONNAME.ulButtons

类型:ULONG

保留。

DUMMYUNIONNAME.DUMMYSTRUCTNAME

DUMMYUNIONNAME.DUMMYSTRUCTNAME.usButtonFlags

类型:USHORT

鼠标按钮的转换状态。 此成员可以是以下一个或多个值。

价值 意义
RI_MOUSE_BUTTON_1_DOWN
RI_MOUSE_LEFT_BUTTON_DOWN
0x0001
向左按钮更改为向下。
RI_MOUSE_BUTTON_1_UP
RI_MOUSE_LEFT_BUTTON_UP
0x0002
左按钮已更改为向上。
RI_MOUSE_BUTTON_2_DOWN
RI_MOUSE_RIGHT_BUTTON_DOWN
0x0004
向右按钮更改为“关闭”。
RI_MOUSE_BUTTON_2_UP
RI_MOUSE_RIGHT_BUTTON_UP
0x0008
向右按钮更改为“向上”。
RI_MOUSE_BUTTON_3_DOWN
RI_MOUSE_MIDDLE_BUTTON_DOWN
0x0010
中间按钮已更改为向下。
RI_MOUSE_BUTTON_3_UP
RI_MOUSE_MIDDLE_BUTTON_UP
0x0020
中间按钮已更改为向上。
RI_MOUSE_BUTTON_4_DOWN
0x0040
XBUTTON1更改为关闭。
RI_MOUSE_BUTTON_4_UP
0x0080
XBUTTON1更改为上一个。
RI_MOUSE_BUTTON_5_DOWN
0x0100
XBUTTON2更改为关闭。
RI_MOUSE_BUTTON_5_UP
0x0200
XBUTTON2更改为上一个。
RI_MOUSE_WHEEL
0x0400
原始输入来自鼠标滚轮。 滚轮增量存储在 usButtonData中。
正值表示方向盘向前旋转,远离用户;负值指示方向盘向后旋转,向用户旋转。 有关详细信息,请参阅以下“备注”部分。
RI_MOUSE_HWHEEL
0x0800
原始输入来自水平鼠标滚轮。 滚轮增量存储在 usButtonData中。
正值指示方向盘向右旋转;负值指示方向盘向左旋转。 有关详细信息,请参阅以下“备注”部分。
Windows XP/2000:不支持此值。

DUMMYUNIONNAME.DUMMYSTRUCTNAME.usButtonData

类型:USHORT

如果 usButtonFlags 具有 RI_MOUSE_WHEELRI_MOUSE_HWHEEL,则此成员指定轮子旋转的距离。 有关详细信息,请参阅以下“备注”部分。

ulRawButtons

类型:ULONG

鼠标按钮的原始状态。 Win32 子系统不使用此成员。

lLastX

类型:LONG

X 方向的动作。 这是有符号的相对运动或绝对运动,具体取决于 usFlags的值。

lLastY

类型:LONG

Y 方向的动作。 这是有符号的相对运动或绝对运动,具体取决于 usFlags的值。

ulExtraInformation

类型:ULONG

事件的其他特定于设备的信息。 有关详细信息,请参阅 区分笔输入与鼠标和触摸

言论

如果鼠标已移动,MOUSE_MOVE_RELATIVEMOUSE_MOVE_ABSOLUTE指示,lLastXlLastY 指定有关该移动的信息。 信息指定为相对整数值或绝对整数值。

如果指定了 MOUSE_MOVE_RELATIVE 值,lLastXlLastY 指定相对于上一个鼠标事件(上一个报告位置)的移动。 正值表示鼠标向右移动(或向下):负值表示鼠标向左移动(或向上移动)。

如果指定了 MOUSE_MOVE_ABSOLUTE 值,lLastXlLastY 包含 0 到 65,535 之间的规范化绝对坐标。 坐标 (0,0) 映射到显示图面的左上角:坐标 (65535,65535) 映射到右下角。 在多监视器系统中,坐标映射到主监视器。

如果除了 MOUSE_MOVE_ABSOLUTE之外还指定了 MOUSE_VIRTUAL_DESKTOP,则坐标将映射到整个虚拟桌面。

case WM_INPUT:
{
    UINT dwSize = sizeof(RAWINPUT);
    static BYTE lpb[sizeof(RAWINPUT)];

    GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));

    RAWINPUT* raw = (RAWINPUT*)lpb;

    if (raw->header.dwType == RIM_TYPEMOUSE)
    {
        RAWMOUSE& mouse = raw->data.mouse;

        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;
            ...
        }
        ...
    }

    return 0;
}

与旧版 WM_MOUSEMOVE 窗口消息相比,原始输入鼠标事件不受控制面板 鼠标属性 工作表中鼠标速度设置的影响。 有关详细信息,请参阅 鼠标输入概述

如果移动鼠标滚轮,由 usButtonFlags中的 RI_MOUSE_WHEELRI_MOUSE_HWHEEL 指示,则 usButtonData 包含一个带符号 值,该值指定轮旋转距离。

滚轮旋转将是 WHEEL_DELTA的倍数,设置为 120。 这是要执行的操作的阈值,每个增量应发生一个此类操作(例如滚动一个增量)。

增量设置为 120,以允许Microsoft或其他供应商构建更精细的分辨率轮(无声点的自由旋转轮),以发送更多的每轮次消息,但每条消息中的值较小。 若要使用此功能,可以添加传入增量值,直到达到 WHEEL_DELTA(因此对于增量轮换,可以获得相同的响应),或滚动部分行以响应更频繁的消息。 还可以选择滚动粒度并累积增量,直到达到增量。

应用程序还可以通过使用具有 SPI_GETWHEELSCROLLLINESSPI_GETWHEELSCROLLCHARS 参数的 SystemParametersInfo API 来检索当前行到滚动和字符到滚动的用户设置。

下面是此类滚轮处理代码的示例:

RAWMOUSE& mouse = raw->data.mouse;

if ((mouse.usButtonFlags & RI_MOUSE_WHEEL) || (mouse.usButtonFlags & RI_MOUSE_HWHEEL))
{
    short wheelDelta = (short)mouse.usButtonData;
    float scrollDelta = (float)wheelDelta / WHEEL_DELTA;

    if (mouse.usButtonFlags & RI_MOUSE_HWHEEL) // Horizontal
    {
        unsigned long scrollChars = 1; // 1 is the default
        SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
        scrollDelta *= scrollChars;
        ...
    }
    else // Vertical
    {
        unsigned long scrollLines = 3; // 3 is the default
        SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
        if (scrollLines != WHEEL_PAGESCROLL)
            scrollDelta *= scrollLines;
        ...
    }
}

要求

要求 价值
最低支持的客户端 Windows XP [仅限桌面应用]
支持的最低服务器 Windows Server 2003 [仅限桌面应用]
标头 winuser.h (包括 Windows.h)

另请参阅

概念

GetRawInputDeviceInfo

RAWINPUT

原始输入

参考

MOUSEINPUT 结构

SendInput 函数

MOUSE_INPUT_DATA 结构

鼠标输入概述(旧版)

鼠标输入通知(旧版)

SystemParametersInfo