using System; using System.Runtime.InteropServices; namespace Vanara.PInvoke { public static partial class User32 { /// /// The type of device that sent the input message. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ne-winuser-input_message_device_type typedef enum // tagINPUT_MESSAGE_DEVICE_TYPE { IMDT_UNAVAILABLE, IMDT_KEYBOARD, IMDT_MOUSE, IMDT_TOUCH, IMDT_PEN, IMDT_TOUCHPAD } INPUT_MESSAGE_DEVICE_TYPE; [PInvokeData("winuser.h", MSDNShortId = "aaaa8d9b-1056-4fa3-afcf-43d2c4b41c0e")] [Flags] public enum INPUT_MESSAGE_DEVICE_TYPE { /// The device type isn't identified. IMDT_UNAVAILABLE = 0x00, /// Keyboard input. IMDT_KEYBOARD = 0x01, /// Mouse input. IMDT_MOUSE = 0x02, /// Touch input. IMDT_TOUCH = 0x04, /// Pen or stylus input. IMDT_PEN = 0x08, /// Touchpad input (Windows 8.1 and later). IMDT_TOUCHPAD = 0x10, } /// The ID of the input message source. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ne-winuser-input_message_origin_id typedef enum // tagINPUT_MESSAGE_ORIGIN_ID { IMO_UNAVAILABLE, IMO_HARDWARE, IMO_INJECTED, IMO_SYSTEM } INPUT_MESSAGE_ORIGIN_ID; [PInvokeData("winuser.h", MSDNShortId = "5637bf3a-9fd8-4c89-acd0-4e0e47c0a3bf")] [Flags] public enum INPUT_MESSAGE_ORIGIN_ID { /// The source isn't identified. IMO_UNAVAILABLE = 0x00, /// /// The input message is from a hardware device or has been injected into the message queue by an application that has the /// UIAccess attribute set to TRUE in its manifest file. For more information about the UIAccess attribute and application /// manifests, see UAC References. /// IMO_HARDWARE = 0x01, /// /// The input message has been injected (through the SendInput function) by an application that doesn't have the UIAccess /// attribute set to TRUE in its manifest file. /// IMO_INJECTED = 0x02, /// The system has injected the input message. IMO_SYSTEM = 0x04, } /// Type for structure. [PInvokeData("winuser.h", MSDNShortId = "")] public enum INPUTTYPE { /// The event is a mouse event. Use the mi structure of the union. INPUT_MOUSE = 0, /// The event is a keyboard event. Use the ki structure of the union. INPUT_KEYBOARD = 1, /// The event is a hardware event. Use the hi structure of the union. INPUT_HARDWARE = 2, } /// The mouse state flags. [PInvokeData("winuser.h")] [Flags] public enum MouseState : ushort { /// Mouse attributes changed; application needs to query the mouse attributes. MOUSE_ATTRIBUTES_CHANGED = 0x04, /// Mouse movement data is relative to the last mouse position. MOUSE_MOVE_RELATIVE = 0, /// Mouse movement data is based on absolute position. MOUSE_MOVE_ABSOLUTE = 1, /// Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system). MOUSE_VIRTUAL_DESKTOP = 0x02, /// Do not coalesce mouse moves. MOUSE_MOVE_NOCOALESCE = 0x08, } /// Flags for scan code information. [PInvokeData("winuser.h")] [Flags] public enum RI_KEY : ushort { /// The key is down. RI_KEY_MAKE = 0, /// The key is up. RI_KEY_BREAK = 1, /// The scan code has the E0 prefix. RI_KEY_E0 = 2, /// The scan code has the E1 prefix. RI_KEY_E1 = 4, /// Undocumented RI_KEY_TERMSRV_SET_LED = 8, /// Undocumented RI_KEY_TERMSRV_SHADOW = 0x10 } /// Mouse button transition state indicators. [PInvokeData("winuser.h")] [Flags] public enum RI_MOUSE : ushort { /// Left button changed to down. RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001, /// Left button changed to up. RI_MOUSE_LEFT_BUTTON_UP = 0x0002, /// Right button changed to down. RI_MOUSE_RIGHT_BUTTON_DOWN = 0x0004, /// Right button changed to up. RI_MOUSE_RIGHT_BUTTON_UP = 0x0008, /// Middle button changed to down. RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010, /// Middle button changed to up. RI_MOUSE_MIDDLE_BUTTON_UP = 0x0020, /// RI_MOUSE_LEFT_BUTTON_DOWN RI_MOUSE_BUTTON_1_DOWN = RI_MOUSE_LEFT_BUTTON_DOWN, /// RI_MOUSE_LEFT_BUTTON_UP RI_MOUSE_BUTTON_1_UP = RI_MOUSE_LEFT_BUTTON_UP, /// RI_MOUSE_RIGHT_BUTTON_DOWN RI_MOUSE_BUTTON_2_DOWN = RI_MOUSE_RIGHT_BUTTON_DOWN, /// RI_MOUSE_RIGHT_BUTTON_UP RI_MOUSE_BUTTON_2_UP = RI_MOUSE_RIGHT_BUTTON_UP, /// RI_MOUSE_MIDDLE_BUTTON_DOWN RI_MOUSE_BUTTON_3_DOWN = RI_MOUSE_MIDDLE_BUTTON_DOWN, /// RI_MOUSE_MIDDLE_BUTTON_UP RI_MOUSE_BUTTON_3_UP = RI_MOUSE_MIDDLE_BUTTON_UP, /// XBUTTON1 changed to down. RI_MOUSE_BUTTON_4_DOWN = 0x0040, /// XBUTTON1 changed to up. RI_MOUSE_BUTTON_4_UP = 0x0080, /// XBUTTON2 changed to down. RI_MOUSE_BUTTON_5_DOWN = 0x0100, /// XBUTTON2 changed to up. RI_MOUSE_BUTTON_5_UP = 0x0200, /// Raw input comes from a mouse wheel. The wheel delta is stored in usButtonData. RI_MOUSE_WHEEL = 0x0400, /// Raw input comes from a mouse horizontal wheel. The wheel delta is stored in usButtonData. RI_MOUSE_HWHEEL = 0x0800, } /// The command flag for . [PInvokeData("winuser.h", MSDNShortId = "")] public enum RID { /// Get the raw data from the RAWINPUT structure. RID_INPUT = 0x10000003, /// Get the header information from the RAWINPUT structure. RID_HEADER = 0x10000005 } /// Mode flag that specifies how to interpret the information provided by usUsagePage and usUsage in . [PInvokeData("winuser.h", MSDNShortId = "")] [Flags] public enum RIDEV : uint { /// /// If set, the application command keys are handled. RIDEV_APPKEYS can be specified only if RIDEV_NOLEGACY is specified for a /// keyboard device. /// RIDEV_APPKEYS = 0x00000400, /// If set, the mouse button click does not activate the other window. RIDEV_CAPTUREMOUSE = 0x00000200, /// /// If set, this enables the caller to receive WM_INPUT_DEVICE_CHANGE notifications for device arrival and device removal. /// Windows XP: This flag is not supported until Windows Vista /// RIDEV_DEVNOTIFY = 0x00002000, /// /// If set, this specifies the top level collections to exclude when reading a complete usage page. This flag only affects a TLC /// whose usage page is already specified with RIDEV_PAGEONLY. /// RIDEV_EXCLUDE = 0x00000010, /// /// If set, this enables the caller to receive input in the background only if the foreground application does not process it. In /// other words, if the foreground application is not registered for raw input, then the background application that is /// registered will receive the input. Windows XP: This flag is not supported until Windows Vista /// RIDEV_EXINPUTSINK = 0x00001000, /// /// If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that hwndTarget must /// be specified. /// RIDEV_INPUTSINK = 0x00000100, /// /// If set, the application-defined keyboard device hotkeys are not handled. However, the system hotkeys; for example, ALT+TAB /// and CTRL+ALT+DEL, are still handled. By default, all keyboard hotkeys are handled. RIDEV_NOHOTKEYS can be specified even if /// RIDEV_NOLEGACY is not specified and hwndTarget is NULL. /// RIDEV_NOHOTKEYS = 0x00000200, /// /// If set, this prevents any devices specified by usUsagePage or usUsage from generating legacy messages. This is only for the /// mouse and keyboard. See Remarks. /// RIDEV_NOLEGACY = 0x00000030, /// /// If set, this specifies all devices whose top level collection is from the specified usUsagePage. Note that usUsage must be /// zero. To exclude a particular top level collection, use RIDEV_EXCLUDE. /// RIDEV_PAGEONLY = 0x00000020, /// /// If set, this removes the top level collection from the inclusion list. This tells the operating system to stop reading from a /// device which matches the top level collection. /// RIDEV_REMOVE = 0x00000001, } /// The type of raw input. [PInvokeData("winuser.h")] public enum RIM_TYPE { /// Raw input comes from some device that is not a keyboard or a mouse. RIM_TYPEHID = 2, /// Raw input comes from the keyboard. RIM_TYPEKEYBOARD = 1, /// Raw input comes from the mouse. RIM_TYPEMOUSE = 0, } /// /// Calls the default raw input procedure to provide default processing for any raw input messages that an application does not /// process. This function ensures that every message is processed. DefRawInputProc is called with the same parameters /// received by the window procedure. /// /// /// Type: PRAWINPUT* /// An array of RAWINPUT structures. /// /// /// Type: INT /// The number of RAWINPUT structures pointed to by paRawInput. /// /// /// Type: UINT /// The size, in bytes, of the RAWINPUTHEADER structure. /// /// /// Type: LRESULT /// If successful, the function returns S_OK. Otherwise it returns an error value. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-defrawinputproc LRESULT DefRawInputProc( PRAWINPUT // *paRawInput, INT nInput, UINT cbSizeHeader ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h")] public static extern IntPtr DefRawInputProc(RAWINPUT[] paRawInput, int nInput, uint cbSizeHeader); /// Retrieves the source of the input message. /// /// The INPUT_MESSAGE_SOURCE structure that holds the device type and the ID of the input message source. /// /// NotedeviceType in INPUT_MESSAGE_SOURCE is set to IMDT_UNAVAILABLE when SendMessage is used to inject input (system /// generated or through messages such as WM_PAINT). This remains true until SendMessage returns. /// /// /// /// If this function succeeds, it returns TRUE. Otherwise, it returns FALSE. To retrieve extended error information, call the /// GetLastError function. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getcurrentinputmessagesource BOOL // GetCurrentInputMessageSource( INPUT_MESSAGE_SOURCE *inputMessageSource ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "35e4ebf5-df9d-4168-9996-355204c2ab93")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetCurrentInputMessageSource(ref INPUT_MESSAGE_SOURCE inputMessageSource); /// Retrieves the time of the last input event. /// /// Type: PLASTINPUTINFO /// A pointer to a LASTINPUTINFO structure that receives the time of the last input event. /// /// /// Type: BOOL /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. /// /// /// /// This function is useful for input idle detection. However, GetLastInputInfo does not provide system-wide user input /// information across all running sessions. Rather, GetLastInputInfo provides session-specific user input information for /// only the session that invoked the function. /// /// /// The tick count when the last input event was received (see LASTINPUTINFO) is not guaranteed to be incremental. In some cases, the /// value might be less than the tick count of a prior event. For example, this can be caused by a timing gap between the raw input /// thread and the desktop thread or an event raised by SendInput, which supplies its own tick count. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getlastinputinfo BOOL GetLastInputInfo( PLASTINPUTINFO // plii ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); /// Performs a buffered read of the raw input data. /// /// Type: PRAWINPUT /// /// A pointer to a buffer of RAWINPUT structures that contain the raw input data. If NULL, the minimum required buffer, in /// bytes, is returned in *pcbSize. /// /// /// /// Type: PUINT /// The size, in bytes, of a RAWINPUT structure. /// /// /// Type: UINT /// The size, in bytes, of the RAWINPUTHEADER structure. /// /// /// Type: UINT /// /// If pData is NULL and the function is successful, the return value is zero. If pData is not NULL and the function is successful, /// the return value is the number of RAWINPUT structures written to pData. /// /// If an error occurs, the return value is ( UINT)-1. Call GetLastError for the error code. /// /// /// /// Using GetRawInputBuffer, the raw input data is buffered in the array of RAWINPUT structures. For an unbuffered read, use /// the GetMessage function to read in the raw input data. /// /// The NEXTRAWINPUTBLOCK macro allows an application to traverse an array of RAWINPUT structures. /// /// Note To get the correct size of the raw input buffer, do not use *pcbSize, use *pcbSize * 8 instead. To ensure /// GetRawInputBuffer behaves properly on WOW64, you must align the RAWINPUT structure by 8 bytes. The following code shows /// how to align RAWINPUT for WOW64. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getrawinputbuffer UINT GetRawInputBuffer( PRAWINPUT pData, // PUINT pcbSize, UINT cbSizeHeader ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint GetRawInputBuffer(IntPtr pData, ref uint pcbSize, uint cbSizeHeader); /// Retrieves the raw input from the specified device. /// /// Type: HRAWINPUT /// A handle to the RAWINPUT structure. This comes from the lParam in WM_INPUT. /// /// /// Type: UINT /// The command flag. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// RID_HEADER 0x10000005 /// Get the header information from the RAWINPUT structure. /// /// /// RID_INPUT 0x10000003 /// Get the raw data from the RAWINPUT structure. /// /// /// /// /// Type: LPVOID /// /// A pointer to the data that comes from the RAWINPUT structure. This depends on the value of uiCommand. If pData is NULL, /// the required size of the buffer is returned in *pcbSize. /// /// /// /// Type: PUINT /// The size, in bytes, of the data in pData. /// /// /// Type: UINT /// The size, in bytes, of the RAWINPUTHEADER structure. /// /// /// Type: UINT /// /// If pData is NULL and the function is successful, the return value is 0. If pData is not NULL and the function is /// successful, the return value is the number of bytes copied into pData. /// /// If there is an error, the return value is ( UINT)-1. /// /// /// GetRawInputData gets the raw input one RAWINPUT structure at a time. In contrast, GetRawInputBuffer gets an array of /// RAWINPUT structures. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getrawinputdata UINT GetRawInputData( HRAWINPUT hRawInput, // UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h")] public static extern uint GetRawInputData(HRAWINPUT hRawInput, RID uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader); /// Retrieves information about the raw input device. /// /// Type: HANDLE /// A handle to the raw input device. This comes from the hDevice member of RAWINPUTHEADER or from GetRawInputDeviceList. /// /// /// Type: UINT /// Specifies what data will be returned in pData. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// RIDI_DEVICENAME 0x20000007 /// /// pData points to a string that contains the device name. For this uiCommand only, the value in pcbSize is the character count (not /// the byte count). /// /// /// /// RIDI_DEVICEINFO 0x2000000b /// pData points to an RID_DEVICE_INFO structure. /// /// /// RIDI_PREPARSEDDATA 0x20000005 /// pData points to the previously parsed data. /// /// /// /// /// Type: LPVOID /// /// A pointer to a buffer that contains the information specified by uiCommand. If uiCommand is RIDI_DEVICEINFO, set the /// cbSize member of RID_DEVICE_INFO to before calling GetRawInputDeviceInfo. /// /// /// /// Type: PUINT /// The size, in bytes, of the data in pData. /// /// /// Type: UINT /// If successful, this function returns a non-negative number indicating the number of bytes copied to pData. /// /// If pData is not large enough for the data, the function returns -1. If pData is NULL, the function returns a value of /// zero. In both of these cases, pcbSize is set to the minimum size required for the pData buffer. /// /// Call GetLastError to identify any other errors. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getrawinputdeviceinfoa UINT GetRawInputDeviceInfoA( HANDLE // hDevice, UINT uiCommand, LPVOID pData, PUINT pcbSize ); [DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint GetRawInputDeviceInfo(HANDLE hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize); /// Enumerates the raw input devices attached to the system. /// /// Type: PRAWINPUTDEVICELIST /// /// An array of RAWINPUTDEVICELIST structures for the devices attached to the system. If NULL, the number of devices are /// returned in *puiNumDevices. /// /// /// /// Type: PUINT /// /// If pRawInputDeviceList is NULL, the function populates this variable with the number of devices attached to the system; /// otherwise, this variable specifies the number of RAWINPUTDEVICELIST structures that can be contained in the buffer to which /// pRawInputDeviceList points. If this value is less than the number of devices attached to the system, the function returns the /// actual number of devices in this variable and fails with ERROR_INSUFFICIENT_BUFFER. /// /// /// /// Type: UINT /// The size of a RAWINPUTDEVICELIST structure, in bytes. /// /// /// Type: UINT /// If the function is successful, the return value is the number of devices stored in the buffer pointed to by pRawInputDeviceList. /// On any other error, the function returns ( UINT) -1 and GetLastError returns the error indication. /// /// /// The devices returned from this function are the mouse, the keyboard, and other Human Interface Device (HID) devices. /// To get more detailed information about the attached devices, call GetRawInputDeviceInfo using the hDevice from RAWINPUTDEVICELIST. /// Examples /// The following sample code shows a typical call to GetRawInputDeviceList: /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getrawinputdevicelist UINT GetRawInputDeviceList( // PRAWINPUTDEVICELIST pRawInputDeviceList, PUINT puiNumDevices, UINT cbSize ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint GetRawInputDeviceList([In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] RAWINPUTDEVICELIST[] pRawInputDeviceList, ref uint puiNumDevices, uint cbSize); /// Retrieves the information about the raw input devices for the current application. /// /// Type: PRAWINPUTDEVICE /// An array of RAWINPUTDEVICE structures for the application. /// /// /// Type: PUINT /// The number of RAWINPUTDEVICE structures in *pRawInputDevices. /// /// /// Type: UINT /// The size, in bytes, of a RAWINPUTDEVICE structure. /// /// /// Type: UINT /// /// If successful, the function returns a non-negative number that is the number of RAWINPUTDEVICE structures written to the buffer. /// /// /// If the pRawInputDevices buffer is too small or NULL, the function sets the last error as ERROR_INSUFFICIENT_BUFFER, /// returns -1, and sets puiNumDevices to the required number of devices. If the function fails for any other reason, it returns -1. /// For more details, call GetLastError. /// /// /// To receive raw input from a device, an application must register it by using RegisterRawInputDevices. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getregisteredrawinputdevices UINT // GetRegisteredRawInputDevices( PRAWINPUTDEVICE pRawInputDevices, PUINT puiNumDevices, UINT cbSize ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint GetRegisteredRawInputDevices([In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] RAWINPUTDEVICE[] pRawInputDevices, ref uint puiNumDevices, uint cbSize); /// Registers the devices that supply the raw input data. /// /// Type: PCRAWINPUTDEVICE /// An array of RAWINPUTDEVICE structures that represent the devices that supply the raw input. /// /// /// Type: UINT /// The number of RAWINPUTDEVICE structures pointed to by pRawInputDevices. /// /// /// Type: UINT /// The size, in bytes, of a RAWINPUTDEVICE structure. /// /// /// Type: BOOL /// TRUE if the function succeeds; otherwise, FALSE. If the function fails, call GetLastError for more information. /// /// /// /// To receive WM_INPUT messages, an application must first register the raw input devices using RegisterRawInputDevices. By /// default, an application does not receive raw input. /// /// /// To receive WM_INPUT_DEVICE_CHANGE messages, an application must specify the RIDEV_DEVNOTIFY flag for each device class that is /// specified by the usUsagePage and usUsage fields of the RAWINPUTDEVICE structure . By default, an application does not receive /// WM_INPUT_DEVICE_CHANGE notifications for raw input device arrival and removal. /// /// /// If a RAWINPUTDEVICE structure has the RIDEV_REMOVE flag set and the hwndTarget parameter is not set to NULL, then parameter /// validation will fail. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registerrawinputdevices BOOL RegisterRawInputDevices( // PCRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool RegisterRawInputDevices([In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] RAWINPUTDEVICE[] pRawInputDevices, uint uiNumDevices, uint cbSize); /// Synthesizes keystrokes, mouse motions, and button clicks. /// /// Type: UINT /// The number of structures in the pInputs array. /// /// /// Type: LPINPUT /// An array of INPUT structures. Each structure represents an event to be inserted into the keyboard or mouse input stream. /// /// /// Type: int /// The size, in bytes, of an INPUT structure. If cbSize is not the size of an INPUT structure, the function fails. /// /// /// Type: UINT /// /// The function returns the number of events that it successfully inserted into the keyboard or mouse input stream. If the function /// returns zero, the input was already blocked by another thread. To get extended error information, call GetLastError. /// /// /// This function fails when it is blocked by UIPI. Note that neither GetLastError nor the return value will indicate the failure was /// caused by UIPI blocking. /// /// /// /// /// This function is subject to UIPI. Applications are permitted to inject input only into applications that are at an equal or /// lesser integrity level. /// /// /// The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. These /// events are not interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse) or /// by calls to keybd_event, mouse_event, or other calls to SendInput. /// /// /// This function does not reset the keyboard's current state. Any keys that are already pressed when the function is called might /// interfere with the events that this function generates. To avoid this problem, check the keyboard's state with the /// GetAsyncKeyState function and correct as necessary. /// /// /// Because the touch keyboard uses the surrogate macros defined in winnls.h to send input to the system, a listener on the keyboard /// event hook must decode input originating from the touch keyboard. For more information, see Surrogates and Supplementary Characters. /// /// /// An accessibility application can use SendInput to inject keystrokes corresponding to application launch shortcut keys that /// are handled by the shell. This functionality is not guaranteed to work for other types of applications. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendinput UINT SendInput( UINT cInputs, LPINPUT pInputs, // int cbSize ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint SendInput(uint cInputs, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] INPUT[] pInputs, int cbSize); /// Contains information about a simulated message generated by an input device other than a keyboard or mouse. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-taghardwareinput typedef struct tagHARDWAREINPUT { DWORD // uMsg; WORD wParamL; WORD wParamH; } HARDWAREINPUT, *PHARDWAREINPUT, *LPHARDWAREINPUT; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct HARDWAREINPUT { /// /// Type: DWORD /// The message generated by the input hardware. /// public uint uMsg; /// /// Type: WORD /// The low-order word of the lParam parameter for uMsg. /// public ushort wParamL; /// /// Type: WORD /// The high-order word of the lParam parameter for uMsg. /// public ushort wParamH; } /// Provides a handle to a RAWINPUT structure. [StructLayout(LayoutKind.Sequential)] public struct HRAWINPUT : IHandle { private IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HRAWINPUT(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static HRAWINPUT NULL => new HRAWINPUT(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(HRAWINPUT h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator HRAWINPUT(IntPtr h) => new HRAWINPUT(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(HRAWINPUT h1, HRAWINPUT h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(HRAWINPUT h1, HRAWINPUT h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is HRAWINPUT h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// /// Used by SendInput to store information for synthesizing input events such as keystrokes, mouse movement, and mouse clicks. /// /// /// INPUT_KEYBOARD supports nonkeyboard input methods, such as handwriting recognition or voice recognition, as if it were /// text input by using the KEYEVENTF_UNICODE flag. For more information, see the remarks section of KEYBDINPUT. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-taginput typedef struct tagINPUT { DWORD type; union { // MOUSEINPUT mi; KEYBDINPUT ki; HARDWAREINPUT hi; } DUMMYUNIONNAME; } INPUT, *PINPUT, *LPINPUT; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Explicit)] public struct INPUT { /// /// Type: DWORD /// The type of the input event. This member can be one of the following values. /// /// /// Value /// Meaning /// /// /// INPUT_MOUSE 0 /// The event is a mouse event. Use the mi structure of the union. /// /// /// INPUT_KEYBOARD 1 /// The event is a keyboard event. Use the ki structure of the union. /// /// /// INPUT_HARDWARE 2 /// The event is a hardware event. Use the hi structure of the union. /// /// /// [FieldOffset(0)] public INPUTTYPE type; /// /// Type: MOUSEINPUT /// The information about a simulated mouse event. /// [FieldOffset(4)] public MOUSEINPUT mi; /// /// Type: KEYBDINPUT /// The information about a simulated keyboard event. /// [FieldOffset(4)] public KEYBDINPUT ki; /// /// Type: HARDWAREINPUT /// The information about a simulated hardware event. /// [FieldOffset(4)] public HARDWAREINPUT hi; } /// Contains information about the source of the input message. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-taginput_message_source typedef struct // tagINPUT_MESSAGE_SOURCE { INPUT_MESSAGE_DEVICE_TYPE deviceType; INPUT_MESSAGE_ORIGIN_ID originId; } INPUT_MESSAGE_SOURCE; [PInvokeData("winuser.h", MSDNShortId = "75437c0a-925a-44d9-9254-43095b281c21")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct INPUT_MESSAGE_SOURCE { /// The device type (INPUT_MESSAGE_DEVICE_TYPE) of the source of the input message. public INPUT_MESSAGE_DEVICE_TYPE deviceType; /// The ID (INPUT_MESSAGE_ORIGIN_ID) of the source of the input message. public INPUT_MESSAGE_ORIGIN_ID originId; } /// Contains the time of the last input. /// This function is useful for input idle detection. For more information on tick counts, see GetTickCount. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-taglastinputinfo typedef struct tagLASTINPUTINFO { UINT // cbSize; DWORD dwTime; } LASTINPUTINFO, *PLASTINPUTINFO; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct LASTINPUTINFO { /// /// Type: UINT /// The size of the structure, in bytes. This member must be set to sizeof(LASTINPUTINFO). /// public uint cbSize; /// /// Type: DWORD /// The tick count when the last input event was received. /// public uint dwTime; } /// Contains information about a simulated mouse event. /// /// /// 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 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. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagmouseinput typedef struct tagMOUSEINPUT { LONG dx; LONG // dy; DWORD mouseData; DWORD dwFlags; DWORD time; ULONG_PTR dwExtraInfo; } MOUSEINPUT, *PMOUSEINPUT, *LPMOUSEINPUT; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct MOUSEINPUT { /// /// 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. /// /// public int dx; /// /// 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. /// /// public int dy; /// /// 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 0x0001 /// Set if the first X button is pressed or released. /// /// /// XBUTTON2 0x0002 /// Set if the second X button is pressed or released. /// /// /// public uint mouseData; /// /// Type: DWORD /// /// A set of bit flags that specify various aspects of mouse motion and button clicks. The bits in this member can be any /// reasonable combination of the following values. /// /// /// The bit flags that specify mouse button status are set to indicate changes in status, not ongoing conditions. For example, if /// the left mouse button is pressed and held down, MOUSEEVENTF_LEFTDOWN is set when the left button is first pressed, but /// not for subsequent motions. Similarly, MOUSEEVENTF_LEFTUP is set only when the button is first released. /// /// /// You cannot specify both the MOUSEEVENTF_WHEEL flag and either MOUSEEVENTF_XDOWN or MOUSEEVENTF_XUP flags /// simultaneously in the dwFlags parameter, because they both require use of the mouseData field. /// /// /// /// Value /// Meaning /// /// /// MOUSEEVENTF_ABSOLUTE 0x8000 /// /// The dx and dy members contain normalized absolute coordinates. If the flag is not set, dxand dy contain relative data (the /// change in position since the last reported position). This flag can be set, or not set, regardless of what kind of mouse or /// other pointing device, if any, is connected to the system. For further information about relative mouse motion, see the /// following Remarks section. /// /// /// /// MOUSEEVENTF_HWHEEL 0x01000 /// /// The wheel was moved horizontally, if the mouse has a wheel. The amount of movement is specified in mouseData. Windows /// XP/2000: This value is not supported. /// /// /// /// MOUSEEVENTF_MOVE 0x0001 /// Movement occurred. /// /// /// MOUSEEVENTF_MOVE_NOCOALESCE 0x2000 /// /// The WM_MOUSEMOVE messages will not be coalesced. The default behavior is to coalesce WM_MOUSEMOVE messages. Windows XP/2000: /// This value is not supported. /// /// /// /// MOUSEEVENTF_LEFTDOWN 0x0002 /// The left button was pressed. /// /// /// MOUSEEVENTF_LEFTUP 0x0004 /// The left button was released. /// /// /// MOUSEEVENTF_RIGHTDOWN 0x0008 /// The right button was pressed. /// /// /// MOUSEEVENTF_RIGHTUP 0x0010 /// The right button was released. /// /// /// MOUSEEVENTF_MIDDLEDOWN 0x0020 /// The middle button was pressed. /// /// /// MOUSEEVENTF_MIDDLEUP 0x0040 /// The middle button was released. /// /// /// MOUSEEVENTF_VIRTUALDESK 0x4000 /// Maps coordinates to the entire desktop. Must be used with MOUSEEVENTF_ABSOLUTE. /// /// /// MOUSEEVENTF_WHEEL 0x0800 /// The wheel was moved, if the mouse has a wheel. The amount of movement is specified in mouseData. /// /// /// MOUSEEVENTF_XDOWN 0x0080 /// An X button was pressed. /// /// /// MOUSEEVENTF_XUP 0x0100 /// An X button was released. /// /// /// public uint dwFlags; /// /// Type: DWORD /// The time stamp for the event, in milliseconds. If this parameter is 0, the system will provide its own time stamp. /// public uint time; /// /// Type: ULONG_PTR /// /// An additional value associated with the mouse event. An application calls GetMessageExtraInfo to obtain this extra information. /// /// public UIntPtr dwExtraInfo; } /// Describes the format of the raw input from a Human Interface Device (HID). /// /// Each WM_INPUT can indicate several inputs, but all of the inputs come from the same HID. The size of the bRawData array is /// dwSizeHid * dwCount. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawhid typedef struct tagRAWHID { DWORD dwSizeHid; // DWORD dwCount; BYTE bRawData[1]; } RAWHID, *PRAWHID, *LPRAWHID; [PInvokeData("winuser.h")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct RAWHID { /// /// Type: DWORD /// The size, in bytes, of each HID input in bRawData. /// public uint dwSizeHid; /// /// Type: DWORD /// The number of HID inputs in bRawData. /// public uint dwCount; /// /// Type: BYTE[1] /// The raw input data, as an array of bytes. /// public IntPtr bRawData; } /// Contains the raw input from a device. /// /// The handle to this structure is passed in the lParam parameter of WM_INPUT. /// To get detailed information -- such as the header and the content of the raw input -- call GetRawInputData. /// To read the RAWINPUT in the message loop as a buffered read, call GetRawInputBuffer. /// To get device specific information, call GetRawInputDeviceInfo with the hDevice from RAWINPUTHEADER. /// Raw input is available only when the application calls RegisterRawInputDevices with valid device specifications. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawinput typedef struct tagRAWINPUT { RAWINPUTHEADER // header; union { RAWMOUSE mouse; RAWKEYBOARD keyboard; RAWHID hid; } data; } RAWINPUT, *PRAWINPUT, *LPRAWINPUT; [PInvokeData("winuser.h")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct RAWINPUT { /// /// Type: RAWINPUTHEADER /// The raw input data. /// public RAWINPUTHEADER header; /// The data public DATA data; /// [StructLayout(LayoutKind.Explicit)] public struct DATA { /// Type: RAWMOUSE If the data comes from a mouse, this is the raw input data. [FieldOffset(0)] public RAWMOUSE mouse; /// Type: RAWKEYBOARD If the data comes from a keyboard, this is the raw input data. [FieldOffset(0)] public RAWKEYBOARD keyboard; /// Type: RAWHID If the data comes from an HID, this is the raw input data. [FieldOffset(0)] public RAWHID hid; } } /// Defines information for the raw input devices. /// /// /// If RIDEV_NOLEGACY is set for a mouse or a keyboard, the system does not generate any legacy message for that device for /// the application. For example, if the mouse TLC is set with RIDEV_NOLEGACY, WM_LBUTTONDOWN and related legacy mouse /// messages are not generated. Likewise, if the keyboard TLC is set with RIDEV_NOLEGACY, WM_KEYDOWN and related legacy /// keyboard messages are not generated. /// /// /// If RIDEV_REMOVE is set and the hwndTarget member is not set to NULL, then parameter validation will fail. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawinputdevice typedef struct tagRAWINPUTDEVICE { // USHORT usUsagePage; USHORT usUsage; DWORD dwFlags; HWND hwndTarget; } RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct RAWINPUTDEVICE { /// /// Type: USHORT /// Top level collection Usage page for the raw input device. /// public ushort usUsagePage; /// /// Type: USHORT /// Top level collection Usage for the raw input device. /// public ushort usUsage; /// /// Type: DWORD /// /// Mode flag that specifies how to interpret the information provided by usUsagePage and usUsage. It can be zero /// (the default) or one of the following values. By default, the operating system sends raw input from devices with the /// specified top level collection (TLC) to the registered application as long as it has the window focus. /// /// /// /// Value /// Meaning /// /// /// RIDEV_APPKEYS 0x00000400 /// /// If set, the application command keys are handled. RIDEV_APPKEYS can be specified only if RIDEV_NOLEGACY is specified for a /// keyboard device. /// /// /// /// RIDEV_CAPTUREMOUSE 0x00000200 /// If set, the mouse button click does not activate the other window. /// /// /// RIDEV_DEVNOTIFY 0x00002000 /// /// If set, this enables the caller to receive WM_INPUT_DEVICE_CHANGE notifications for device arrival and device removal. /// Windows XP: This flag is not supported until Windows Vista /// /// /// /// RIDEV_EXCLUDE 0x00000010 /// /// If set, this specifies the top level collections to exclude when reading a complete usage page. This flag only affects a TLC /// whose usage page is already specified with RIDEV_PAGEONLY. /// /// /// /// RIDEV_EXINPUTSINK 0x00001000 /// /// If set, this enables the caller to receive input in the background only if the foreground application does not process it. In /// other words, if the foreground application is not registered for raw input, then the background application that is /// registered will receive the input. Windows XP: This flag is not supported until Windows Vista /// /// /// /// RIDEV_INPUTSINK 0x00000100 /// /// If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that hwndTarget must /// be specified. /// /// /// /// RIDEV_NOHOTKEYS 0x00000200 /// /// If set, the application-defined keyboard device hotkeys are not handled. However, the system hotkeys; for example, ALT+TAB /// and CTRL+ALT+DEL, are still handled. By default, all keyboard hotkeys are handled. RIDEV_NOHOTKEYS can be specified even if /// RIDEV_NOLEGACY is not specified and hwndTarget is NULL. /// /// /// /// RIDEV_NOLEGACY 0x00000030 /// /// If set, this prevents any devices specified by usUsagePage or usUsage from generating legacy messages. This is only for the /// mouse and keyboard. See Remarks. /// /// /// /// RIDEV_PAGEONLY 0x00000020 /// /// If set, this specifies all devices whose top level collection is from the specified usUsagePage. Note that usUsage must be /// zero. To exclude a particular top level collection, use RIDEV_EXCLUDE. /// /// /// /// RIDEV_REMOVE 0x00000001 /// /// If set, this removes the top level collection from the inclusion list. This tells the operating system to stop reading from a /// device which matches the top level collection. /// /// /// /// public RIDEV dwFlags; /// /// Type: HWND /// A handle to the target window. If NULL it follows the keyboard focus. /// public HWND hwndTarget; } /// Contains information about a raw input device. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawinputdevicelist typedef struct tagRAWINPUTDEVICELIST // { HANDLE hDevice; DWORD dwType; } RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct RAWINPUTDEVICELIST { /// /// Type: HANDLE /// A handle to the raw input device. /// public HANDLE hDevice; /// /// Type: DWORD /// The type of device. This can be one of the following values. /// /// /// Value /// Meaning /// /// /// RIM_TYPEHID 2 /// The device is an HID that is not a keyboard and not a mouse. /// /// /// RIM_TYPEKEYBOARD 1 /// The device is a keyboard. /// /// /// RIM_TYPEMOUSE 0 /// The device is a mouse. /// /// /// public RIM_TYPE dwType; } /// /// Contains the header information that is part of the raw input data. /// /// /// To get more information on the device, use hDevice in a call to GetRawInputDeviceInfo. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawinputheader typedef struct tagRAWINPUTHEADER { DWORD // dwType; DWORD dwSize; HANDLE hDevice; WPARAM wParam; } RAWINPUTHEADER, *PRAWINPUTHEADER, *LPRAWINPUTHEADER; [PInvokeData("winuser.h")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct RAWINPUTHEADER { /// /// Type: DWORD /// The type of raw input. It can be one of the following values. /// /// /// Value /// Meaning /// /// /// RIM_TYPEHID 2 /// Raw input comes from some device that is not a keyboard or a mouse. /// /// /// RIM_TYPEKEYBOARD 1 /// Raw input comes from the keyboard. /// /// /// RIM_TYPEMOUSE 0 /// Raw input comes from the mouse. /// /// /// public RIM_TYPE dwType; /// /// Type: DWORD /// /// The size, in bytes, of the entire input packet of data. This includes RAWINPUT plus possible extra input reports in the /// RAWHID variable length array. /// /// public uint dwSize; /// /// Type: HANDLE /// A handle to the device generating the raw input data. /// public HANDLE hDevice; /// /// Type: WPARAM /// The value passed in the wParam parameter of the WM_INPUT message. /// public IntPtr wParam; } /// Contains information about the state of the keyboard. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawkeyboard typedef struct tagRAWKEYBOARD { USHORT // MakeCode; USHORT Flags; USHORT Reserved; USHORT VKey; UINT Message; ULONG ExtraInformation; } RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD; [PInvokeData("winuser.h")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct RAWKEYBOARD { /// /// Type: USHORT /// The scan code from the key depression. The scan code for keyboard overrun is KEYBOARD_OVERRUN_MAKE_CODE. /// public ushort MakeCode; /// /// Type: USHORT /// Flags for scan code information. It can be one or more of the following. /// /// /// Value /// Meaning /// /// /// RI_KEY_BREAK 1 /// The key is up. /// /// /// RI_KEY_E0 2 /// The scan code has the E0 prefix. /// /// /// RI_KEY_E1 4 /// The scan code has the E1 prefix. /// /// /// RI_KEY_MAKE 0 /// The key is down. /// /// /// public RI_KEY Flags; /// /// Type: USHORT /// Reserved; must be zero. /// public ushort Reserved; /// /// Type: USHORT /// Windows message compatible virtual-key code. For more information, see Virtual Key Codes. /// public ushort VKey; /// /// Type: UINT /// The corresponding window message, for example WM_KEYDOWN, WM_SYSKEYDOWN, and so forth. /// public uint Message; /// /// Type: ULONG /// The device-specific additional information for the event. /// public uint ExtraInformation; } /// Contains information about the state of the mouse. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse 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; [PInvokeData("winuser.h")] [StructLayout(LayoutKind.Explicit)] public struct RAWMOUSE { /// /// Type: USHORT /// The mouse state. This member can be any reasonable combination of the following. /// /// /// Value /// Meaning /// /// /// MOUSE_ATTRIBUTES_CHANGED 0x04 /// Mouse attributes changed; application needs to query the mouse attributes. /// /// /// MOUSE_MOVE_RELATIVE 0 /// Mouse movement data is relative to the last mouse position. /// /// /// MOUSE_MOVE_ABSOLUTE 1 /// Mouse movement data is based on absolute position. /// /// /// MOUSE_VIRTUAL_DESKTOP 0x02 /// Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system). /// /// /// [FieldOffset(0)] public MouseState usFlags; /// /// Type: ULONG /// Reserved. /// [FieldOffset(2)] public uint ulButtons; /// /// Type: USHORT /// The transition state of the mouse buttons. This member can be one or more of the following values. /// /// /// Value /// Meaning /// /// /// RI_MOUSE_LEFT_BUTTON_DOWN 0x0001 /// Left button changed to down. /// /// /// RI_MOUSE_LEFT_BUTTON_UP 0x0002 /// Left button changed to up. /// /// /// RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010 /// Middle button changed to down. /// /// /// RI_MOUSE_MIDDLE_BUTTON_UP 0x0020 /// Middle button changed to up. /// /// /// RI_MOUSE_RIGHT_BUTTON_DOWN 0x0004 /// Right button changed to down. /// /// /// RI_MOUSE_RIGHT_BUTTON_UP 0x0008 /// Right button changed to up. /// /// /// RI_MOUSE_BUTTON_1_DOWN 0x0001 /// RI_MOUSE_LEFT_BUTTON_DOWN /// /// /// RI_MOUSE_BUTTON_1_UP 0x0002 /// RI_MOUSE_LEFT_BUTTON_UP /// /// /// RI_MOUSE_BUTTON_2_DOWN 0x0004 /// RI_MOUSE_RIGHT_BUTTON_DOWN /// /// /// RI_MOUSE_BUTTON_2_UP 0x0008 /// RI_MOUSE_RIGHT_BUTTON_UP /// /// /// RI_MOUSE_BUTTON_3_DOWN 0x0010 /// RI_MOUSE_MIDDLE_BUTTON_DOWN /// /// /// RI_MOUSE_BUTTON_3_UP 0x0020 /// RI_MOUSE_MIDDLE_BUTTON_UP /// /// /// RI_MOUSE_BUTTON_4_DOWN 0x0040 /// XBUTTON1 changed to down. /// /// /// RI_MOUSE_BUTTON_4_UP 0x0080 /// XBUTTON1 changed to up. /// /// /// RI_MOUSE_BUTTON_5_DOWN 0x100 /// XBUTTON2 changed to down. /// /// /// RI_MOUSE_BUTTON_5_UP 0x0200 /// XBUTTON2 changed to up. /// /// /// RI_MOUSE_WHEEL 0x0400 /// Raw input comes from a mouse wheel. The wheel delta is stored in usButtonData. /// /// /// [FieldOffset(2)] public RI_MOUSE usButtonFlags; /// /// Type: USHORT /// If usButtonFlags is RI_MOUSE_WHEEL, this member is a signed value that specifies the wheel delta. /// [FieldOffset(4)] public ushort usButtonData; /// /// Type: ULONG /// The raw state of the mouse buttons. /// [FieldOffset(6)] public uint ulRawButtons; /// /// Type: LONG /// The motion in the X direction. This is signed relative motion or absolute motion, depending on the value of usFlags. /// [FieldOffset(10)] public int lLastX; /// /// Type: LONG /// The motion in the Y direction. This is signed relative motion or absolute motion, depending on the value of usFlags. /// [FieldOffset(14)] public int lLastY; /// /// Type: ULONG /// The device-specific additional information for the event. /// [FieldOffset(18)] public uint ulExtraInformation; } /// Defines the raw input data coming from any device. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrid_device_info typedef struct tagRID_DEVICE_INFO { // DWORD cbSize; DWORD dwType; union { RID_DEVICE_INFO_MOUSE mouse; RID_DEVICE_INFO_KEYBOARD keyboard; RID_DEVICE_INFO_HID hid; } // DUMMYUNIONNAME; } RID_DEVICE_INFO, *PRID_DEVICE_INFO, *LPRID_DEVICE_INFO; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Explicit)] public struct RID_DEVICE_INFO { /// /// Type: DWORD /// The size, in bytes, of the RID_DEVICE_INFO structure. /// [FieldOffset(0)] public uint cbSize; /// /// Type: DWORD /// The type of raw input data. This member can be one of the following values. /// /// /// Value /// Meaning /// /// /// RIM_TYPEHID 2 /// Data comes from an HID that is not a keyboard or a mouse. /// /// /// RIM_TYPEKEYBOARD 1 /// Data comes from a keyboard. /// /// /// RIM_TYPEMOUSE 0 /// Data comes from a mouse. /// /// /// [FieldOffset(4)] public RIM_TYPE dwType; /// /// Type: RID_DEVICE_INFO_MOUSE /// If dwType is RIM_TYPEMOUSE, this is the RID_DEVICE_INFO_MOUSE structure that defines the mouse. /// [FieldOffset(8)] public RID_DEVICE_INFO_MOUSE mouse; /// /// Type: RID_DEVICE_INFO_KEYBOARD /// If dwType is RIM_TYPEKEYBOARD, this is the RID_DEVICE_INFO_KEYBOARD structure that defines the keyboard. /// [FieldOffset(8)] public RID_DEVICE_INFO_KEYBOARD keyboard; /// /// Type: RID_DEVICE_INFO_HID /// If dwType is RIM_TYPEHID, this is the RID_DEVICE_INFO_HID structure that defines the HID device. /// [FieldOffset(8)] public RID_DEVICE_INFO_HID hid; } /// Defines the raw input data coming from the specified Human Interface Device (HID). // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrid_device_info_hid typedef struct // tagRID_DEVICE_INFO_HID { DWORD dwVendorId; DWORD dwProductId; DWORD dwVersionNumber; USHORT usUsagePage; USHORT usUsage; } // RID_DEVICE_INFO_HID, *PRID_DEVICE_INFO_HID; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct RID_DEVICE_INFO_HID { /// /// Type: DWORD /// The vendor identifier for the HID. /// public uint dwVendorId; /// /// Type: DWORD /// The product identifier for the HID. /// public uint dwProductId; /// /// Type: DWORD /// The version number for the HID. /// public uint dwVersionNumber; /// /// Type: USHORT /// The top-level collection Usage Page for the device. /// public ushort usUsagePage; /// /// Type: USHORT /// The top-level collection Usage for the device. /// public ushort usUsage; } /// Defines the raw input data coming from the specified keyboard. /// For the keyboard, the Usage Page is 1 and the Usage is 6. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrid_device_info_keyboard typedef struct // tagRID_DEVICE_INFO_KEYBOARD { DWORD dwType; DWORD dwSubType; DWORD dwKeyboardMode; DWORD dwNumberOfFunctionKeys; DWORD // dwNumberOfIndicators; DWORD dwNumberOfKeysTotal; } RID_DEVICE_INFO_KEYBOARD, *PRID_DEVICE_INFO_KEYBOARD; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct RID_DEVICE_INFO_KEYBOARD { /// /// Type: DWORD /// The type of the keyboard. /// public uint dwType; /// /// Type: DWORD /// The subtype of the keyboard. /// public uint dwSubType; /// /// Type: DWORD /// The scan code mode. /// public uint dwKeyboardMode; /// /// Type: DWORD /// The number of function keys on the keyboard. /// public uint dwNumberOfFunctionKeys; /// /// Type: DWORD /// The number of LED indicators on the keyboard. /// public uint dwNumberOfIndicators; /// /// Type: DWORD /// The total number of keys on the keyboard. /// public uint dwNumberOfKeysTotal; } /// Defines the raw input data coming from the specified mouse. /// For the mouse, the Usage Page is 1 and the Usage is 2. // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrid_device_info_mouse typedef struct // tagRID_DEVICE_INFO_MOUSE { DWORD dwId; DWORD dwNumberOfButtons; DWORD dwSampleRate; BOOL fHasHorizontalWheel; } // RID_DEVICE_INFO_MOUSE, *PRID_DEVICE_INFO_MOUSE; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct RID_DEVICE_INFO_MOUSE { /// /// Type: DWORD /// The identifier of the mouse device. /// public uint dwId; /// /// Type: DWORD /// The number of buttons for the mouse. /// public uint dwNumberOfButtons; /// /// Type: DWORD /// The number of data points per second. This information may not be applicable for every mouse device. /// public uint dwSampleRate; /// /// Type: BOOL /// TRUE if the mouse has a wheel for horizontal scrolling; otherwise, FALSE. /// Windows XP: This member is only supported starting with Windows Vista. /// [MarshalAs(UnmanagedType.Bool)] public bool fHasHorizontalWheel; } } }