GetRawInputData (user32)
Last changed: tkirk9155@gmail.com-74.4.30.222

.
Summary
Function to read raw data from an input device such as a keyboard, mouse or other HID.

C# Signature:

    /// <summary>
    /// Function to retrieve raw input data.
    /// </summary>
    /// <param name="hRawInput">Handle to the raw input.</param>
    /// <param name="uiCommand">Command to issue when retrieving data.</param>
    /// <param name="pData">Raw input data.</param>
    /// <param name="pcbSize">Number of bytes in the array.</param>
    /// <param name="cbSizeHeader">Size of the header.</param>
    /// <returns>0 if successful if pData is null, otherwise number of bytes if pData is not null.</returns>
    [DllImport("user32.dll")]
    public static extern int GetRawInputData(IntPtr hRawInput, RawInputCommand uiCommand, out RAWINPUT pData, ref int pcbSize, int cbSizeHeader);

or

    /// <summary>
    /// Function to retrieve raw input data.
    /// </summary>
    /// <param name="hRawInput">Handle to the raw input.</param>
    /// <param name="uiCommand">Command to issue when retrieving data.</param>
    /// <param name="pData">Raw input data.</param>
    /// <param name="pcbSize">Number of bytes in the array.</param>
    /// <param name="cbSizeHeader">Size of the header.</param>
    /// <returns>0 if successful if pData is null, otherwise number of bytes if pData is not null.</returns>
    [DllImport("user32.dll")]
    public static extern int GetRawInputData(IntPtr hRawInput, RawInputCommand uiCommand, byte[] pData, ref int pcbSize, int cbSizeHeader);

VB Signature:

Declare Function GetRawInputData Lib "user32.dll" (TODO) As TODO

User-Defined Types:

Enumerations:

    /// <summary>
    /// Enumeration containing the type device the raw input is coming from.
    /// </summary>
    public enum RawInputType
    {
        /// <summary>
        /// Mouse input.
        /// </summary>
        Mouse = 0,
        /// <summary>
        /// Keyboard input.
        /// </summary>
        Keyboard = 1,
        /// <summary>
        /// Another device that is not the keyboard or the mouse.
        /// </summary>
        HID = 2
    }

    /// <summary>
    /// Enumeration containing the flags for raw mouse data.
    /// </summary>
    [Flags()]
    public enum RawMouseFlags
        : ushort
    {
        /// <summary>Relative to the last position.</summary>
        MoveRelative = 0,
        /// <summary>Absolute positioning.</summary>
        MoveAbsolute = 1,
        /// <summary>Coordinate data is mapped to a virtual desktop.</summary>
        VirtualDesktop = 2,
        /// <summary>Attributes for the mouse have changed.</summary>
        AttributesChanged = 4
    }

    /// <summary>
    /// Enumeration containing the button data for raw mouse input.
    /// </summary>
    [Flags()]
    public enum RawMouseButtons
        : ushort
    {
        /// <summary>No button.</summary>
        None = 0,
        /// <summary>Left (button 1) down.</summary>
        LeftDown = 0x0001,
        /// <summary>Left (button 1) up.</summary>
        LeftUp = 0x0002,
        /// <summary>Right (button 2) down.</summary>
        RightDown = 0x0004,
        /// <summary>Right (button 2) up.</summary>
        RightUp = 0x0008,
        /// <summary>Middle (button 3) down.</summary>
        MiddleDown = 0x0010,
        /// <summary>Middle (button 3) up.</summary>
        MiddleUp = 0x0020,
        /// <summary>Button 4 down.</summary>
        Button4Down = 0x0040,
        /// <summary>Button 4 up.</summary>
        Button4Up = 0x0080,
        /// <summary>Button 5 down.</summary>
        Button5Down = 0x0100,
        /// <summary>Button 5 up.</summary>
        Button5Up = 0x0200,
        /// <summary>Mouse wheel moved.</summary>
        MouseWheel = 0x0400
    }

    /// <summary>
    /// Enumeration containing flags for raw keyboard input.
    /// </summary>
    [Flags()]
    public enum RawKeyboardFlags
        : ushort
    {
        /// <summary></summary>
        KeyMake = 0,
        /// <summary></summary>
        KeyBreak = 1,
        /// <summary></summary>
        KeyE0 = 2,
        /// <summary></summary>
        KeyE1 = 4,
        /// <summary></summary>
        TerminalServerSetLED = 8,
        /// <summary></summary>
        TerminalServerShadow = 0x10,
        /// <summary></summary>
        TerminalServerVKPACKET = 0x20
    }

    /// <summary>
    /// Enumeration contanining the command types to issue.
    /// </summary>
    public enum RawInputCommand
    {
        /// <summary>
        /// Get input data.
        /// </summary>
        Input = 0x10000003,
        /// <summary>
        /// Get header data.
        /// </summary>
        Header = 0x10000005
    }

Value types:

    /// <summary>
    /// Value type for a raw input header.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTHEADER
    {
        /// <summary>Type of device the input is coming from.</summary>
        public RawInputType Type;
        /// <summary>Size of the packet of data.</summary>
        public int Size;
        /// <summary>Handle to the device sending the data.</summary>
        public IntPtr Device;
        /// <summary>wParam from the window message.</summary>
        public IntPtr wParam;
    }

    /// <summary>
    /// Value type for raw input from a mouse.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTMOUSE
    {
        /// <summary>Flags for the event.</summary>
        public RawMouseFlags Flags;
        /// <summary>If the mouse wheel is moved, this will contain the delta amount.</summary>
        public ushort ButtonData;
        /// <summary>Flags for the event.</summary>
        public RawMouseButtons ButtonFlags;
        /// <summary>Raw button data.</summary>
        public uint RawButtons;
        /// <summary>Relative direction of motion, depending on flags.</summary>
        public int LastX;
        /// <summary>Relative direction of motion, depending on flags.</summary>
        public int LastY;
        /// <summary>Extra information.</summary>
        public uint ExtraInformation;
    }

    /// <summary>
    /// Value type for raw input from a keyboard.
    /// </summary>    
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTKEYBOARD
    {
        /// <summary>Scan code for key depression.</summary>
        public short MakeCode;
        /// <summary>Scan code information.</summary>
        public RawKeyboardFlags Flags;
        /// <summary>Reserved.</summary>
        public short Reserved;
        /// <summary>Virtual key code.</summary>
        public VirtualKeys VirtualKey;
        /// <summary>Corresponding window message.</summary>
        public WindowMessages Message;
        /// <summary>Extra information.</summary>
        public int ExtraInformation;
    }

    /// <summary>
    /// Value type for raw input from a HID.
    /// </summary>    
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTHID
    {
        /// <summary>Size of the HID data in bytes.</summary>
        public int Size;
        /// <summary>Number of HID in Data.</summary>
        public int Count;
        /// <summary>Data for the HID.</summary>
        public IntPtr Data;
    }

    /// <summary>
    /// Value type for raw input.
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public struct RAWINPUT
    {
        /// <summary>Header for the data.</summary>
        [FieldOffset(0)]
        public RAWINPUTHEADER Header;
        /// <summary>Mouse raw input data.</summary>
        [FieldOffset(16)]
        public RAWINPUTMOUSE Mouse;
        /// <summary>Keyboard raw input data.</summary>
        [FieldOffset(16)]
        public RAWINPUTKEYBOARD Keyboard;
        /// <summary>HID raw input data.</summary>
        [FieldOffset(16)]
        public RAWINPUTHID HID;
    }

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

The VirtualKeys enumeration has been omitted as it's quite lengthy. They're just mapped to the VK_* constants.

Tips & Tricks:

Please add some!

Sample Code:

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == (int)WindowMessages.RawInput)  // WindowMessages.RawInput = 0x00FF (WM_INPUT)
        {
            RAWINPUT input = new RAWINPUT();
            int outSize = 0;
            int size = Marshal.SizeOf(typeof(RAWINPUT));

            outSize = Win32API.GetRawInputData(m.LParam, RawInputCommand.Input, out input, ref size, Marshal.SizeOf(typeof(RAWINPUTHEADER)));
            if (outSize != -1)
            {
                if (input.Header.Type == RawInputType.Mouse)
                {
                    p.X += input.Mouse.LastX;
                    p.Y += input.Mouse.LastY;
                    label1.Text = "Mouse: " + p.X.ToString() + "x" + p.Y.ToString() + " " + input.Mouse.ButtonFlags.ToString();
                }
            }
        }
        base.WndProc(ref m);
    }

Documentation