More cleanup and re-org.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/RawInput.cs Fri Nov 07 22:12:22 2014 +0100
1.3 @@ -0,0 +1,94 @@
1.4 +using System;
1.5 +using System.Runtime.InteropServices;
1.6 +using System.Diagnostics;
1.7 +
1.8 +
1.9 +namespace Win32
1.10 +{
1.11 + static class RawInput
1.12 + {
1.13 + /// <summary>
1.14 + ///
1.15 + /// </summary>
1.16 + /// <param name="aRawInputHandle"></param>
1.17 + /// <param name="aRawInput"></param>
1.18 + /// <param name="rawInputBuffer">Caller must free up memory on the pointer using Marshal.FreeHGlobal</param>
1.19 + /// <returns></returns>
1.20 + public static bool GetRawInputData(IntPtr aRawInputHandle, ref RAWINPUT aRawInput, ref IntPtr rawInputBuffer)
1.21 + {
1.22 + bool success = true;
1.23 + rawInputBuffer = IntPtr.Zero;
1.24 +
1.25 + try
1.26 + {
1.27 + uint dwSize = 0;
1.28 + uint sizeOfHeader = (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
1.29 +
1.30 + //Get the size of our raw input data.
1.31 + Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);
1.32 +
1.33 + //Allocate a large enough buffer
1.34 + rawInputBuffer = Marshal.AllocHGlobal((int)dwSize);
1.35 +
1.36 + //Now read our RAWINPUT data
1.37 + if (Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, rawInputBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
1.38 + {
1.39 + return false;
1.40 + }
1.41 +
1.42 + //Cast our buffer
1.43 + aRawInput = (RAWINPUT)Marshal.PtrToStructure(rawInputBuffer, typeof(RAWINPUT));
1.44 + }
1.45 + catch
1.46 + {
1.47 + Debug.WriteLine("GetRawInputData failed!");
1.48 + success = false;
1.49 + }
1.50 +
1.51 + return success;
1.52 + }
1.53 +
1.54 + /// <summary>
1.55 + ///
1.56 + /// </summary>
1.57 + /// <param name="aRawInputHandle"></param>
1.58 + /// <param name="aUsagePage"></param>
1.59 + /// <param name="aUsage"></param>
1.60 + /// <returns></returns>
1.61 + public static bool GetDeviceInfo(IntPtr hDevice, ref RID_DEVICE_INFO deviceInfo)
1.62 + {
1.63 + bool success = true;
1.64 + IntPtr deviceInfoBuffer = IntPtr.Zero;
1.65 + try
1.66 + {
1.67 + //Get Device Info
1.68 + uint deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
1.69 + deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);
1.70 +
1.71 + int res = Win32.Function.GetRawInputDeviceInfo(hDevice, Const.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
1.72 + if (res <= 0)
1.73 + {
1.74 + Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error().ToString());
1.75 + return false;
1.76 + }
1.77 +
1.78 + //Cast our buffer
1.79 + deviceInfo = (RID_DEVICE_INFO)Marshal.PtrToStructure(deviceInfoBuffer, typeof(RID_DEVICE_INFO));
1.80 + }
1.81 + catch
1.82 + {
1.83 + Debug.WriteLine("GetRawInputData failed!");
1.84 + success = false;
1.85 + }
1.86 + finally
1.87 + {
1.88 + //Always executes, prevents memory leak
1.89 + Marshal.FreeHGlobal(deviceInfoBuffer);
1.90 + }
1.91 +
1.92 +
1.93 + return success;
1.94 + }
1.95 +
1.96 + }
1.97 +}
1.98 \ No newline at end of file
2.1 --- a/RemoteControlDevice.cs Fri Nov 07 20:49:51 2014 +0100
2.2 +++ b/RemoteControlDevice.cs Fri Nov 07 22:12:22 2014 +0100
2.3 @@ -145,9 +145,6 @@
2.4 private const int APPCOMMAND_MEDIA_CHANNEL_UP = 51;
2.5 private const int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;
2.6
2.7 - private const int RID_INPUT = 0x10000003;
2.8 - private const int RID_HEADER = 0x10000005;
2.9 -
2.10 private const int FAPPCOMMAND_MASK = 0xF000;
2.11 private const int FAPPCOMMAND_MOUSE = 0x8000;
2.12 private const int FAPPCOMMAND_KEY = 0;
2.13 @@ -349,42 +346,25 @@
2.14 {
2.15 Debug.WriteLine("================WM_INPUT================");
2.16
2.17 - uint dwSize = 0;
2.18
2.19 - uint sizeOfHeader=(uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
2.20 + //Declare a pointer
2.21 + IntPtr rawInputBuffer = IntPtr.Zero;
2.22
2.23 - //Get the size of our raw input data.
2.24 - Win32.Function.GetRawInputData(message.LParam, RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);
2.25 -
2.26 - //Allocate a large enough buffer
2.27 - IntPtr rawInputBuffer = Marshal.AllocHGlobal((int) dwSize);
2.28 - try
2.29 - {
2.30 - if(rawInputBuffer == IntPtr.Zero)
2.31 - return;
2.32 -
2.33 - //Now read our RAWINPUT data
2.34 - if (Win32.Function.GetRawInputData(message.LParam, RID_INPUT, rawInputBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
2.35 - {
2.36 - return;
2.37 - }
2.38 -
2.39 - //Cast our buffer
2.40 - RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(rawInputBuffer, typeof(RAWINPUT));
2.41 -
2.42 - //Get Device Info
2.43 - uint deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
2.44 - IntPtr deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);
2.45 -
2.46 - int res = Win32.Function.GetRawInputDeviceInfo(raw.header.hDevice, Const.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
2.47 - if (res <= 0)
2.48 + try
2.49 + {
2.50 + //Fetch raw input
2.51 + RAWINPUT raw = new RAWINPUT();
2.52 + if (!RawInput.GetRawInputData(message.LParam, ref raw, ref rawInputBuffer))
2.53 {
2.54 - Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error().ToString());
2.55 return;
2.56 }
2.57
2.58 - //Cast our buffer
2.59 - RID_DEVICE_INFO deviceInfo = (RID_DEVICE_INFO)Marshal.PtrToStructure(deviceInfoBuffer, typeof(RID_DEVICE_INFO));
2.60 + //Fetch device info
2.61 + RID_DEVICE_INFO deviceInfo = new RID_DEVICE_INFO();
2.62 + if (!RawInput.GetDeviceInfo(raw.header.hDevice, ref deviceInfo))
2.63 + {
2.64 + return;
2.65 + }
2.66
2.67 //Check type of input device and quite if we don't like it
2.68 switch (deviceInfo.dwType)
2.69 @@ -406,11 +386,15 @@
2.70 //Get Usage Page and Usage
2.71 Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
2.72
2.73 - //Check that our raw input is HID
2.74 - if (raw.header.dwType == Const.RIM_TYPEHID && raw.hid.dwSizeHid>0)
2.75 - {
2.76 +
2.77 + if (raw.header.dwType == Const.RIM_TYPEHID //Check that our raw input is HID
2.78 + && raw.hid.dwSizeHid > 1 //Make sure our HID msg size more than 1. In fact the first ushort is irrelevant to us for now
2.79 + && raw.hid.dwCount > 0) //Check that we have at least one HID msg
2.80 + {
2.81 + //TODO: for each HID message
2.82 +
2.83 //Allocate a buffer for one HID message
2.84 - byte[] bRawData = new byte[raw.hid.dwSizeHid];
2.85 + byte[] bRawData = new byte[raw.hid.dwSizeHid];
2.86
2.87 //Compute the address from which to copy our HID message
2.88 int pRawData = 0;
2.89 @@ -434,6 +418,7 @@
2.90 }
2.91 Debug.WriteLine(hidDump);
2.92
2.93 +
2.94 //Make sure both usage page and usage are matching MCE remote
2.95 if (deviceInfo.hid.usUsagePage != (ushort)Hid.UsagePage.MceRemote || deviceInfo.hid.usUsage != (ushort)Hid.UsageId.MceRemoteUsage)
2.96 {
2.97 @@ -441,27 +426,28 @@
2.98 return;
2.99 }
2.100
2.101 - if (Enum.IsDefined(typeof(MceButton), rawData) && rawData!=0) //Our button is a known MCE button
2.102 + if (Enum.IsDefined(typeof(MceButton), rawData) && rawData != 0) //Our button is a known MCE button
2.103 {
2.104 if (this.ButtonPressed != null) //What's that?
2.105 {
2.106 this.ButtonPressed(this, new RemoteControlEventArgs((MceButton)rawData, GetDevice(message.LParam.ToInt32())));
2.107 }
2.108 }
2.109 - }
2.110 - else if(raw.header.dwType == Const.RIM_TYPEMOUSE)
2.111 - {
2.112 - // do mouse handling...
2.113 - }
2.114 - else if(raw.header.dwType == Const.RIM_TYPEKEYBOARD)
2.115 - {
2.116 - // do keyboard handling...
2.117 - }
2.118 - }
2.119 - finally
2.120 - {
2.121 - Marshal.FreeHGlobal(rawInputBuffer);
2.122 - }
2.123 + }
2.124 + else if (raw.header.dwType == Const.RIM_TYPEMOUSE)
2.125 + {
2.126 + // do mouse handling...
2.127 + }
2.128 + else if (raw.header.dwType == Const.RIM_TYPEKEYBOARD)
2.129 + {
2.130 + // do keyboard handling...
2.131 + }
2.132 + }
2.133 + finally
2.134 + {
2.135 + //Always executed when leaving our try block
2.136 + Marshal.FreeHGlobal(rawInputBuffer);
2.137 + }
2.138 }
2.139
2.140
3.1 --- a/RemoteControlSample.csproj Fri Nov 07 20:49:51 2014 +0100
3.2 +++ b/RemoteControlSample.csproj Fri Nov 07 22:12:22 2014 +0100
3.3 @@ -128,6 +128,7 @@
3.4 <SubType>Form</SubType>
3.5 </Compile>
3.6 <Compile Include="HumanInterfaceDevice.cs" />
3.7 + <Compile Include="RawInput.cs" />
3.8 <Compile Include="RemoteControlDevice.cs">
3.9 <SubType>Code</SubType>
3.10 </Compile>
4.1 --- a/Win32RawInput.cs Fri Nov 07 20:49:51 2014 +0100
4.2 +++ b/Win32RawInput.cs Fri Nov 07 22:12:22 2014 +0100
4.3 @@ -45,6 +45,10 @@
4.4 /// </summary>
4.5 public const uint RIM_TYPEHID = 2;
4.6
4.7 + public const int RID_INPUT = 0x10000003;
4.8 + public const int RID_HEADER = 0x10000005;
4.9 +
4.10 +
4.11 }
4.12
4.13