Adding HID handler.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/HidDevice.cs Sat Dec 06 23:34:02 2014 +0100
1.3 @@ -0,0 +1,94 @@
1.4 +using System;
1.5 +using System.Windows.Forms;
1.6 +using System.Runtime.InteropServices;
1.7 +using System.Diagnostics;
1.8 +using System.Text;
1.9 +using Microsoft.Win32.SafeHandles;
1.10 +
1.11 +namespace Hid
1.12 +{
1.13 + /// <summary>
1.14 + /// Represent a HID device.
1.15 + /// </summary>
1.16 + class HidDevice
1.17 + {
1.18 + public string Name { get; private set; }
1.19 + public string Manufacturer { get; private set; }
1.20 + public string Product { get; private set; }
1.21 + public ushort VendorId { get; private set; }
1.22 + public ushort ProductId { get; private set; }
1.23 + public ushort Version { get; private set; }
1.24 +
1.25 + /// <summary>
1.26 + /// Class constructor will fetch this object properties from HID sub system.
1.27 + /// </summary>
1.28 + /// <param name="hRawInputDevice">Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice</param>
1.29 + public HidDevice(IntPtr hRawInputDevice)
1.30 + {
1.31 + //Fetch various information defining the given HID device
1.32 + Name = Win32.RawInput.GetDeviceName(hRawInputDevice);
1.33 +
1.34 + //Open our device from the device name/path
1.35 + SafeFileHandle handle=Win32.Function.CreateFile(Name,
1.36 + Win32.FileAccess.NONE,
1.37 + Win32.FileShare.FILE_SHARE_READ|Win32.FileShare.FILE_SHARE_WRITE,
1.38 + IntPtr.Zero,
1.39 + Win32.CreationDisposition.OPEN_EXISTING,
1.40 + Win32.FileFlagsAttributes.FILE_FLAG_OVERLAPPED,
1.41 + IntPtr.Zero
1.42 + );
1.43 +
1.44 + if (handle.IsInvalid)
1.45 + {
1.46 + Debug.WriteLine("Failed to CreateFile from device name " + Marshal.GetLastWin32Error().ToString());
1.47 + }
1.48 + else
1.49 + {
1.50 + //Get manufacturer string
1.51 + StringBuilder manufacturerString = new StringBuilder(256);
1.52 + if (Win32.Function.HidD_GetManufacturerString(handle, manufacturerString, manufacturerString.Capacity))
1.53 + {
1.54 + Manufacturer = manufacturerString.ToString();
1.55 + }
1.56 +
1.57 + //Get product string
1.58 + StringBuilder productString = new StringBuilder(256);
1.59 + if (Win32.Function.HidD_GetProductString(handle, productString, productString.Capacity))
1.60 + {
1.61 + Product = productString.ToString();
1.62 + }
1.63 +
1.64 + //Get attributes
1.65 + Win32.HIDD_ATTRIBUTES attributes=new Win32.HIDD_ATTRIBUTES();
1.66 + if (Win32.Function.HidD_GetAttributes(handle, ref attributes))
1.67 + {
1.68 + VendorId = attributes.VendorID;
1.69 + ProductId = attributes.ProductID;
1.70 + Version = attributes.VersionNumber;
1.71 + }
1.72 +
1.73 + handle.Close();
1.74 + }
1.75 + }
1.76 +
1.77 + /// <summary>
1.78 + /// Print information about this device to our debug output.
1.79 + /// </summary>
1.80 + public void DebugWrite()
1.81 + {
1.82 + Debug.WriteLine("================ HID =========================================================================================");
1.83 + Debug.WriteLine("==== Name: " + Name);
1.84 + Debug.WriteLine("==== Manufacturer: " + Manufacturer);
1.85 + Debug.WriteLine("==== Product: " + Product);
1.86 + Debug.WriteLine("==== VendorID: 0x" + VendorId.ToString("X4"));
1.87 + Debug.WriteLine("==== ProductID: 0x" + ProductId.ToString("X4"));
1.88 + Debug.WriteLine("==== Version: " + Version.ToString());
1.89 + Debug.WriteLine("==============================================================================================================");
1.90 + }
1.91 +
1.92 +
1.93 +
1.94 +
1.95 + }
1.96 +
1.97 +}
1.98 \ No newline at end of file
2.1 --- a/HidEvent.cs Sat Dec 06 22:59:55 2014 +0100
2.2 +++ b/HidEvent.cs Sat Dec 06 23:34:02 2014 +0100
2.3 @@ -21,6 +21,8 @@
2.4 public bool IsMouse { get; private set; }
2.5 public bool IsKeyboard { get; private set; }
2.6 public bool IsGeneric { get; private set; }
2.7 + public bool IsButtonDown { get { return Usages.Count == 1 && Usages[0] != 0; } }
2.8 + public bool IsButtonUp { get { return Usages.Count == 1 && Usages[0] == 0; } }
2.9
2.10 public HidDevice Device { get; private set; }
2.11
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/HidHandler.cs Sat Dec 06 23:34:02 2014 +0100
3.3 @@ -0,0 +1,48 @@
3.4 +using System;
3.5 +using System.Windows.Forms;
3.6 +using System.Runtime.InteropServices;
3.7 +using System.Diagnostics;
3.8 +using System.Text;
3.9 +using Microsoft.Win32.SafeHandles;
3.10 +using Win32;
3.11 +using System.Collections.Generic;
3.12 +
3.13 +
3.14 +namespace Hid
3.15 +{
3.16 +
3.17 +
3.18 + /// <summary>
3.19 + /// Our HID handler manages raw input registrations, processes WM_INPUT messages and broadcasts HID events in return.
3.20 + /// </summary>
3.21 + class HidHandler
3.22 + {
3.23 + public delegate void HidEventHandler(object aSender, HidEvent aHidEvent);
3.24 + public event HidEventHandler OnHidEvent;
3.25 +
3.26 + public bool IsRegistered { get; private set; }
3.27 +
3.28 + public HidHandler(RAWINPUTDEVICE[] aRawInputDevices)
3.29 + {
3.30 + IsRegistered = Function.RegisterRawInputDevices(aRawInputDevices, (uint)aRawInputDevices.Length, (uint)Marshal.SizeOf(aRawInputDevices[0]));
3.31 + }
3.32 +
3.33 +
3.34 + public void ProcessInput(Message aMessage)
3.35 + {
3.36 + Hid.HidEvent hidEvent = new Hid.HidEvent(aMessage);
3.37 + hidEvent.DebugWrite();
3.38 +
3.39 + if (!hidEvent.IsValid || !hidEvent.IsGeneric)
3.40 + {
3.41 + Debug.WriteLine("Skipping HID message.");
3.42 + return;
3.43 + }
3.44 +
3.45 + //Broadcast our events
3.46 + OnHidEvent(this, hidEvent);
3.47 + }
3.48 +
3.49 + }
3.50 +
3.51 +}
3.52 \ No newline at end of file
4.1 --- a/HidUtil.cs Sat Dec 06 22:59:55 2014 +0100
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,94 +0,0 @@
4.4 -using System;
4.5 -using System.Windows.Forms;
4.6 -using System.Runtime.InteropServices;
4.7 -using System.Diagnostics;
4.8 -using System.Text;
4.9 -using Microsoft.Win32.SafeHandles;
4.10 -
4.11 -namespace Hid
4.12 -{
4.13 - /// <summary>
4.14 - /// Represent a HID device.
4.15 - /// </summary>
4.16 - class HidDevice
4.17 - {
4.18 - public string Name { get; private set; }
4.19 - public string Manufacturer { get; private set; }
4.20 - public string Product { get; private set; }
4.21 - public ushort VendorId { get; private set; }
4.22 - public ushort ProductId { get; private set; }
4.23 - public ushort Version { get; private set; }
4.24 -
4.25 - /// <summary>
4.26 - /// Class constructor will fetch this object properties from HID sub system.
4.27 - /// </summary>
4.28 - /// <param name="hRawInputDevice">Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice</param>
4.29 - public HidDevice(IntPtr hRawInputDevice)
4.30 - {
4.31 - //Fetch various information defining the given HID device
4.32 - Name = Win32.RawInput.GetDeviceName(hRawInputDevice);
4.33 -
4.34 - //Open our device from the device name/path
4.35 - SafeFileHandle handle=Win32.Function.CreateFile(Name,
4.36 - Win32.FileAccess.NONE,
4.37 - Win32.FileShare.FILE_SHARE_READ|Win32.FileShare.FILE_SHARE_WRITE,
4.38 - IntPtr.Zero,
4.39 - Win32.CreationDisposition.OPEN_EXISTING,
4.40 - Win32.FileFlagsAttributes.FILE_FLAG_OVERLAPPED,
4.41 - IntPtr.Zero
4.42 - );
4.43 -
4.44 - if (handle.IsInvalid)
4.45 - {
4.46 - Debug.WriteLine("Failed to CreateFile from device name " + Marshal.GetLastWin32Error().ToString());
4.47 - }
4.48 - else
4.49 - {
4.50 - //Get manufacturer string
4.51 - StringBuilder manufacturerString = new StringBuilder(256);
4.52 - if (Win32.Function.HidD_GetManufacturerString(handle, manufacturerString, manufacturerString.Capacity))
4.53 - {
4.54 - Manufacturer = manufacturerString.ToString();
4.55 - }
4.56 -
4.57 - //Get product string
4.58 - StringBuilder productString = new StringBuilder(256);
4.59 - if (Win32.Function.HidD_GetProductString(handle, productString, productString.Capacity))
4.60 - {
4.61 - Product = productString.ToString();
4.62 - }
4.63 -
4.64 - //Get attributes
4.65 - Win32.HIDD_ATTRIBUTES attributes=new Win32.HIDD_ATTRIBUTES();
4.66 - if (Win32.Function.HidD_GetAttributes(handle, ref attributes))
4.67 - {
4.68 - VendorId = attributes.VendorID;
4.69 - ProductId = attributes.ProductID;
4.70 - Version = attributes.VersionNumber;
4.71 - }
4.72 -
4.73 - handle.Close();
4.74 - }
4.75 - }
4.76 -
4.77 - /// <summary>
4.78 - /// Print information about this device to our debug output.
4.79 - /// </summary>
4.80 - public void DebugWrite()
4.81 - {
4.82 - Debug.WriteLine("================ HID =========================================================================================");
4.83 - Debug.WriteLine("==== Name: " + Name);
4.84 - Debug.WriteLine("==== Manufacturer: " + Manufacturer);
4.85 - Debug.WriteLine("==== Product: " + Product);
4.86 - Debug.WriteLine("==== VendorID: 0x" + VendorId.ToString("X4"));
4.87 - Debug.WriteLine("==== ProductID: 0x" + ProductId.ToString("X4"));
4.88 - Debug.WriteLine("==== Version: " + Version.ToString());
4.89 - Debug.WriteLine("==============================================================================================================");
4.90 - }
4.91 -
4.92 -
4.93 -
4.94 -
4.95 - }
4.96 -
4.97 -}
4.98 \ No newline at end of file
5.1 --- a/RemoteControlDevice.cs Sat Dec 06 22:59:55 2014 +0100
5.2 +++ b/RemoteControlDevice.cs Sat Dec 06 23:34:02 2014 +0100
5.3 @@ -166,6 +166,8 @@
5.4 /// <returns></returns>
5.5 public delegate bool HidUsageHandler(ushort aUsage);
5.6
5.7 + Hid.HidHandler iHidHandler;
5.8 +
5.9
5.10 //-------------------------------------------------------------
5.11 // constructors
5.12 @@ -216,10 +218,12 @@
5.13 //rid[i].hwndTarget = aHWND;
5.14
5.15
5.16 - if (!Function.RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0])))
5.17 + iHidHandler = new Hid.HidHandler(rid);
5.18 + if (!iHidHandler.IsRegistered)
5.19 {
5.20 - throw new ApplicationException("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
5.21 + Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
5.22 }
5.23 + iHidHandler.OnHidEvent += HandleHidEvent;
5.24 }
5.25
5.26
5.27 @@ -367,31 +371,35 @@
5.28 }
5.29 }
5.30
5.31 -
5.32 + /// <summary>
5.33 + ///
5.34 + /// </summary>
5.35 + /// <param name="message"></param>
5.36 private void ProcessInputCommand(ref Message message)
5.37 {
5.38 //We received a WM_INPUT message
5.39 Debug.WriteLine("================WM_INPUT================");
5.40
5.41 - Hid.HidEvent hidEvent = new Hid.HidEvent(message);
5.42 - hidEvent.DebugWrite();
5.43 + iHidHandler.ProcessInput(message);
5.44
5.45 - if (!hidEvent.IsValid || !hidEvent.IsGeneric)
5.46 - {
5.47 - Debug.WriteLine("Skipping HID message.");
5.48 - return;
5.49 - }
5.50 + }
5.51
5.52 -
5.53 + /// <summary>
5.54 + ///
5.55 + /// </summary>
5.56 + /// <param name="aSender"></param>
5.57 + /// <param name="aHidEvent"></param>
5.58 + void HandleHidEvent(object aSender, Hid.HidEvent aHidEvent)
5.59 + {
5.60 HidUsageHandler usagePageHandler = null;
5.61
5.62 //Check if this an MCE remote HID message
5.63 - if (hidEvent.UsagePage == (ushort)Hid.UsagePage.MceRemote && hidEvent.UsageCollection == (ushort)Hid.UsageIdMce.MceRemote)
5.64 + if (aHidEvent.UsagePage == (ushort)Hid.UsagePage.MceRemote && aHidEvent.UsageCollection == (ushort)Hid.UsageIdMce.MceRemote)
5.65 {
5.66 usagePageHandler = HidMceRemoteHandler;
5.67 }
5.68 //Check if this is a consumer control HID message
5.69 - else if (hidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer && hidEvent.UsageCollection == (ushort)Hid.UsageCollectionConsumer.ConsumerControl)
5.70 + else if (aHidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer && aHidEvent.UsageCollection == (ushort)Hid.UsageCollectionConsumer.ConsumerControl)
5.71 {
5.72 usagePageHandler = HidConsumerDeviceHandler;
5.73 }
5.74 @@ -402,7 +410,7 @@
5.75 return;
5.76 }
5.77
5.78 - foreach (ushort usage in hidEvent.Usages)
5.79 + foreach (ushort usage in aHidEvent.Usages)
5.80 {
5.81 usagePageHandler(usage);
5.82 }
6.1 --- a/RemoteControlSample.csproj Sat Dec 06 22:59:55 2014 +0100
6.2 +++ b/RemoteControlSample.csproj Sat Dec 06 23:34:02 2014 +0100
6.3 @@ -127,9 +127,10 @@
6.4 <Compile Include="Form1.cs">
6.5 <SubType>Form</SubType>
6.6 </Compile>
6.7 + <Compile Include="HidDevice.cs" />
6.8 <Compile Include="HidEvent.cs" />
6.9 + <Compile Include="HidHandler.cs" />
6.10 <Compile Include="HidUsageTables.cs" />
6.11 - <Compile Include="HidUtil.cs" />
6.12 <Compile Include="RawInput.cs" />
6.13 <Compile Include="RemoteControlDevice.cs">
6.14 <SubType>Code</SubType>