Adding HID handler.
authorsl
Sat, 06 Dec 2014 23:34:02 +0100
changeset 297679a5ab194b
parent 28 6af1cbb3beb4
child 30 8ce9bdc9c5b5
Adding HID handler.
HidDevice.cs
HidEvent.cs
HidHandler.cs
HidUtil.cs
RemoteControlDevice.cs
RemoteControlSample.csproj
     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>