microsoft / win32metadata

Tooling to generate metadata for Win32 APIs in the Windows SDK.
Other
1.34k stars 116 forks source link

mouseData field of MOUSEINPUT structure is created as uint and does not allow specifying negative values. #933

Closed skotekar closed 2 years ago

skotekar commented 2 years ago

Actual behavior

Type for mouseData field inside MOUSEINPUT structure is created as a uint.

Expected behavior

According to the documentation (https://docs.microsoft.com/windows/win32/api//winuser/ns-winuser-mouseinput#members), we should be able to specify both positive and negative values to simulate forward or backward rotation of the wheel.

Repro steps

  1. NativeMethods.txt content:

    SendInput
  2. Any of your own code that should be shared? Below is the code generated for MOUSEINPUT structure in my project. Check the type for mouseData field

    namespace UI.Input.KeyboardAndMouse
    {
        /// <summary>Contains information about a simulated mouse event.</summary>
        /// <remarks>
        /// <para>If the mouse has moved, indicated by **MOUSEEVENTF_MOVE**, **dx** and **dy** specify information about that movement. The information is specified as absolute or relative integer values. If **MOUSEEVENTF_ABSOLUTE** value is specified, **dx** and **dy** contain normalized absolute coordinates between 0 and 65,535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner of the display surface; coordinate (65535,65535) maps onto the lower-right corner. In a multimonitor system, the coordinates map to the primary monitor. If **MOUSEEVENTF_VIRTUALDESK** is specified, the coordinates map to the entire virtual desktop. If the **MOUSEEVENTF_ABSOLUTE** value is not specified, **dx**and **dy** specify movement relative to the previous mouse event (the last reported position). Positive values mean the mouse moved right (or down); negative values mean the mouse moved left (or up). Relative mouse motion is subject to the effects of the mouse speed and the two-mouse threshold values. A user sets these three values with the **Pointer Speed** slider of the Control Panel's **Mouse Properties** sheet. You can obtain and set these values using the [SystemParametersInfo](/windows/desktop/api/winuser/nf-winuser-systemparametersinfoa) function. The system applies two tests to the specified relative mouse movement. If the specified distance along either the x or y axis is greater than the first mouse threshold value, and the mouse speed is not zero, the system doubles the distance. If the specified distance along either the x or y axis is greater than the second mouse threshold value, and the mouse speed is equal to two, the system doubles the distance that resulted from applying the first threshold test. It is thus possible for the system to multiply specified relative mouse movement along the x or y axis by up to four times.</para>
        /// <para><see href="https://docs.microsoft.com/windows/win32/api//winuser/ns-winuser-mouseinput#">Read more on docs.microsoft.com</see>.</para>
        /// </remarks>
        internal partial struct MOUSEINPUT
        {
            /// <summary>
            /// <para>Type: **LONG** The absolute position of the mouse, or the amount of motion since the last mouse event was generated, depending on the value of the **dwFlags** member. Absolute data is specified as the x coordinate of the mouse; relative data is specified as the number of pixels moved.</para>
            /// <para><see href="https://docs.microsoft.com/windows/win32/api//winuser/ns-winuser-mouseinput#members">Read more on docs.microsoft.com</see>.</para>
            /// </summary>
            internal int dx;
            /// <summary>
            /// <para>Type: **LONG** The absolute position of the mouse, or the amount of motion since the last mouse event was generated, depending on the value of the **dwFlags** member. Absolute data is specified as the y coordinate of the mouse; relative data is specified as the number of pixels moved.</para>
            /// <para><see href="https://docs.microsoft.com/windows/win32/api//winuser/ns-winuser-mouseinput#members">Read more on docs.microsoft.com</see>.</para>
            /// </summary>
            internal int dy;
            /// <summary>
            /// <para>Type: **DWORD** If **dwFlags** contains **MOUSEEVENTF_WHEEL**, then **mouseData** specifies the amount of wheel movement. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as **WHEEL_DELTA**, which is 120. **Windows Vista**: If *dwFlags* contains **MOUSEEVENTF_HWHEEL**, then *dwData* specifies the amount of wheel movement. A positive value indicates that the wheel was rotated to the right; a negative value indicates that the wheel was rotated to the left. One wheel click is defined as **WHEEL_DELTA**, which is 120. If **dwFlags** does not contain **MOUSEEVENTF_WHEEL**, **MOUSEEVENTF_XDOWN**, or **MOUSEEVENTF_XUP**, then **mouseData** should be zero. If **dwFlags** contains **MOUSEEVENTF_XDOWN** or **MOUSEEVENTF_XUP**, then **mouseData** specifies which X buttons were pressed or released. This value may be any combination of the following flags. | Value | Meaning | |-|-| | **XBUTTON1**<br>0x0001 | Set if the first X button is pressed or released. | | **XBUTTON2**<br>0x0002 | Set if the second X button is pressed or released. |</para>
            /// <para><see href="https://docs.microsoft.com/windows/win32/api//winuser/ns-winuser-mouseinput#members">Read more on docs.microsoft.com</see>.</para>
            /// </summary>
            internal uint mouseData;
            /// <summary>Type: **DWORD**</summary>
            internal winmdroot.UI.Input.KeyboardAndMouse.MOUSE_EVENT_FLAGS dwFlags;
            /// <summary>
            /// <para>Type: **DWORD** The time stamp for the event, in milliseconds. If this parameter is 0, the system will provide its own time stamp.</para>
            /// <para><see href="https://docs.microsoft.com/windows/win32/api//winuser/ns-winuser-mouseinput#members">Read more on docs.microsoft.com</see>.</para>
            /// </summary>
            internal uint time;
            /// <summary>
            /// <para>Type: **ULONG_PTR** An additional value associated with the mouse event. An application calls [GetMessageExtraInfo](/windows/desktop/api/winuser/nf-winuser-getmessageextrainfo) to obtain this extra information.</para>
            /// <para><see href="https://docs.microsoft.com/windows/win32/api//winuser/ns-winuser-mouseinput#members">Read more on docs.microsoft.com</see>.</para>
            /// </summary>
            internal nuint dwExtraInfo;
        }
    }

Context

skotekar commented 2 years ago

I would like to add that, by explicitly casting the negative value to an uint, it does work as expected, so may not be a bug but a nice to have may be?

AArnott commented 2 years ago

Ya, the use of DWORD in the header and the docs conflicts with the expectation of negative values, isn't it? I think we can special case this in the metadata.

taufikrh commented 2 years ago

@AArnott This from win32metadata 23.0.3.6210 See #876

// Windows.Win32.UI.Input.KeyboardAndMouse.MOUSEINPUT
using System;
using Windows.Win32.UI.Input.KeyboardAndMouse;

public struct MOUSEINPUT
{
    public int dx;

    public int dy;

    public int mouseData;

    public MOUSE_EVENT_FLAGS dwFlags;

    public uint time;

    public UIntPtr dwExtraInfo;
}
AArnott commented 2 years ago

Duplicate of #876