RawInput.cs
author sl
Sat, 06 Dec 2014 01:53:55 +0100
changeset 21 fb4f80d5cf57
parent 17 8f7e35c3bfd1
child 22 8b2a3da54187
permissions -rw-r--r--
Proper UsageId definitions.
sl@10
     1
using System;
sl@10
     2
using System.Runtime.InteropServices;
sl@10
     3
using System.Diagnostics;
sl@10
     4
sl@10
     5
sl@10
     6
namespace Win32
sl@10
     7
{
sl@17
     8
    /// <summary>
sl@17
     9
    /// Provide some utility functions for raw input handling.
sl@17
    10
    /// </summary>
sl@10
    11
    static class RawInput
sl@10
    12
    {
sl@10
    13
        /// <summary>
sl@10
    14
        /// 
sl@10
    15
        /// </summary>
sl@10
    16
        /// <param name="aRawInputHandle"></param>
sl@10
    17
        /// <param name="aRawInput"></param>
sl@10
    18
        /// <param name="rawInputBuffer">Caller must free up memory on the pointer using Marshal.FreeHGlobal</param>
sl@10
    19
        /// <returns></returns>
sl@10
    20
        public static bool GetRawInputData(IntPtr aRawInputHandle, ref RAWINPUT aRawInput, ref IntPtr rawInputBuffer)
sl@10
    21
        {
sl@10
    22
            bool success = true;
sl@10
    23
            rawInputBuffer = IntPtr.Zero;
sl@10
    24
sl@10
    25
            try
sl@10
    26
            {
sl@10
    27
                uint dwSize = 0;
sl@10
    28
                uint sizeOfHeader = (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
sl@10
    29
sl@10
    30
                //Get the size of our raw input data.
sl@10
    31
                Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);
sl@10
    32
sl@10
    33
                //Allocate a large enough buffer
sl@10
    34
                 rawInputBuffer = Marshal.AllocHGlobal((int)dwSize);
sl@10
    35
sl@10
    36
                //Now read our RAWINPUT data
sl@10
    37
                if (Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, rawInputBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
sl@10
    38
                {
sl@10
    39
                    return false;
sl@10
    40
                }
sl@10
    41
sl@10
    42
                //Cast our buffer
sl@10
    43
                aRawInput = (RAWINPUT)Marshal.PtrToStructure(rawInputBuffer, typeof(RAWINPUT));
sl@10
    44
            }
sl@10
    45
            catch
sl@10
    46
            {
sl@10
    47
                Debug.WriteLine("GetRawInputData failed!");
sl@10
    48
                success = false;
sl@10
    49
            }
sl@10
    50
sl@10
    51
            return success;
sl@10
    52
        }
sl@10
    53
sl@10
    54
        /// <summary>
sl@10
    55
        /// 
sl@10
    56
        /// </summary>
sl@10
    57
        /// <param name="aRawInputHandle"></param>
sl@10
    58
        /// <param name="aUsagePage"></param>
sl@10
    59
        /// <param name="aUsage"></param>
sl@10
    60
        /// <returns></returns>
sl@10
    61
        public static bool GetDeviceInfo(IntPtr hDevice, ref RID_DEVICE_INFO deviceInfo)
sl@10
    62
        {
sl@10
    63
            bool success = true;
sl@10
    64
            IntPtr deviceInfoBuffer = IntPtr.Zero;
sl@10
    65
            try
sl@10
    66
            {
sl@10
    67
                //Get Device Info
sl@10
    68
                uint deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
sl@10
    69
                deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);
sl@10
    70
sl@10
    71
                int res = Win32.Function.GetRawInputDeviceInfo(hDevice, Const.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
sl@10
    72
                if (res <= 0)
sl@10
    73
                {
sl@10
    74
                    Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error().ToString());
sl@10
    75
                    return false;
sl@10
    76
                }
sl@10
    77
sl@10
    78
                //Cast our buffer
sl@10
    79
                deviceInfo = (RID_DEVICE_INFO)Marshal.PtrToStructure(deviceInfoBuffer, typeof(RID_DEVICE_INFO));
sl@10
    80
            }
sl@10
    81
            catch
sl@10
    82
            {
sl@10
    83
                Debug.WriteLine("GetRawInputData failed!");
sl@10
    84
                success = false;
sl@10
    85
            }
sl@10
    86
            finally
sl@10
    87
            {
sl@10
    88
                //Always executes, prevents memory leak
sl@10
    89
                Marshal.FreeHGlobal(deviceInfoBuffer);
sl@10
    90
            }
sl@10
    91
sl@10
    92
            
sl@10
    93
            return success;
sl@10
    94
        }
sl@10
    95
sl@17
    96
        /// <summary>
sl@19
    97
        /// Fetch pre-parsed data corresponding to HID descriptor for the given HID device.
sl@17
    98
        /// </summary>
sl@17
    99
        /// <param name="device"></param>
sl@17
   100
        /// <returns></returns>
sl@17
   101
        public static IntPtr GetPreParsedData(IntPtr hDevice)
sl@17
   102
        {
sl@17
   103
            uint ppDataSize = 256;
sl@17
   104
            int result = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.Const.RIDI_PREPARSEDDATA, IntPtr.Zero, ref ppDataSize);
sl@17
   105
            if (result != 0)
sl@17
   106
            {
sl@17
   107
                Debug.WriteLine("Failed to get raw input pre-parsed data size" + result + Marshal.GetLastWin32Error());
sl@17
   108
                return IntPtr.Zero;
sl@17
   109
            }
sl@17
   110
sl@17
   111
            IntPtr ppData = Marshal.AllocHGlobal((int)ppDataSize);
sl@17
   112
            result = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.Const.RIDI_PREPARSEDDATA, ppData, ref ppDataSize);
sl@17
   113
            if (result <= 0)
sl@17
   114
            {
sl@17
   115
                Debug.WriteLine("Failed to get raw input pre-parsed data" + result + Marshal.GetLastWin32Error());
sl@17
   116
                return IntPtr.Zero;
sl@17
   117
            }
sl@17
   118
            return ppData;
sl@17
   119
        }
sl@17
   120
sl@17
   121
sl@10
   122
    }
sl@10
   123
}