Server/FormMain.Hid.cs
author StephaneLenclud
Sat, 20 Aug 2016 21:00:35 +0200
changeset 246 30a221eecc06
parent 245 448e6a616c22
child 247 afdbe76ab03b
permissions -rw-r--r--
Generic HID event with key recognition functional.
     1 using System;
     2 using System.IO;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 using System.Diagnostics;
     8 using System.Runtime.InteropServices;
     9 using System.Windows.Forms;
    10 using Microsoft.Win32.SafeHandles;
    11 using System.ComponentModel;
    12 //
    13 using Hid = SharpLib.Hid;
    14 using SharpLib.Win32;
    15 
    16 namespace SharpDisplayManager
    17 {
    18     /// <summary>
    19     /// Implement handling of HID input reports notably to be able to launch an application using the Green Start button from IR remotes.
    20     /// </summary>
    21     [System.ComponentModel.DesignerCategory("Code")]
    22     public class FormMainHid : Form
    23     {
    24         //
    25         public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent);
    26 
    27 
    28         /// <summary>
    29         /// Register HID devices so that we receive corresponding WM_INPUT messages.
    30         /// </summary>
    31         protected void RegisterHidDevices()
    32         {
    33             // Register the input device to receive the commands from the
    34             // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
    35             // for the vendor defined usage page.
    36 
    37             RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[6];
    38 
    39             int i = 0;
    40             rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl;
    41             rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.WindowsMediaCenter.WindowsMediaCenterRemoteControl;
    42             rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
    43             rid[i].hwndTarget = Handle;
    44 
    45             i++;
    46             rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
    47             rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.ConsumerControl;
    48             rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
    49             rid[i].hwndTarget = Handle;
    50 
    51             i++;
    52             rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
    53             rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.Selection;
    54             rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
    55             rid[i].hwndTarget = Handle;
    56 
    57             i++;
    58             rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
    59             rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.SystemControl;
    60             rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
    61             rid[i].hwndTarget = Handle;
    62 
    63             i++;
    64             rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
    65             rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.GamePad;
    66             rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
    67             rid[i].hwndTarget = Handle;
    68 
    69             i++;
    70             rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
    71             rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
    72             rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK;
    73             rid[i].hwndTarget = Handle;
    74 
    75             //i++;
    76             //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
    77             //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
    78             //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
    79             //rid[i].hwndTarget = Handle;
    80 
    81             //i++;
    82             //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
    83             //rid[i].usUsage = (ushort)Hid.UsageCollection.GenericDesktop.Mouse;
    84             //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
    85             //rid[i].hwndTarget = aHWND;
    86 
    87 
    88             Program.HidHandler = new SharpLib.Hid.Handler(rid);
    89             if (!Program.HidHandler.IsRegistered)
    90             {
    91                 Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
    92             }
    93             Program.HidHandler.OnHidEvent += HandleHidEventThreadSafe;
    94 
    95         }
    96 
    97 
    98 
    99 
   100         /// <summary>
   101         /// Here we receive HID events from our HID library.
   102         /// </summary>
   103         /// <param name="aSender"></param>
   104         /// <param name="aHidEvent"></param>
   105         public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent)
   106         {
   107             if (aHidEvent.IsStray || !aHidEvent.IsValid)
   108             {
   109                 //Stray event just ignore it
   110                 return;
   111             }
   112 
   113             if (this.InvokeRequired)
   114             {
   115                 //Not in the proper thread, invoke ourselves
   116                 OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe);
   117                 this.Invoke(d, new object[] { aSender, aHidEvent });
   118             }
   119             else
   120             {
   121                 if (aHidEvent.IsGeneric)
   122                 {
   123                     if (aHidEvent.Usages.Count == 0)
   124                     {
   125                         //No usage, nothing to do then
   126                         return;
   127                     }
   128 
   129                     //We are in the proper thread
   130                     if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl)
   131                     {
   132                         //Trigger events as needed
   133                         EventHidWindowsMediaCenter e = new EventHidWindowsMediaCenter
   134                         {
   135                             Usage = (Hid.Usage.WindowsMediaCenterRemoteControl) aHidEvent.Usages[0]
   136                         };
   137                         Properties.Settings.Default.EarManager.TriggerEvent(e);
   138                     }
   139                     else if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.Consumer)
   140                     {
   141                         //Trigger matching events if any
   142                         EventHidConsumerControl e = new EventHidConsumerControl
   143                         {
   144                             Usage = (Hid.Usage.ConsumerControl) aHidEvent.Usages[0]
   145                         };
   146                         Properties.Settings.Default.EarManager.TriggerEvent(e);
   147                     }
   148                 }
   149                 else if (aHidEvent.IsKeyboard)
   150                 {
   151                     //Trigger matching events if any
   152                     EventHidKeyboard e = new EventHidKeyboard
   153                     {
   154                         Key = aHidEvent.VirtualKey,
   155                         IsKeyUp = aHidEvent.IsButtonUp,
   156                         HasModifierAlt = aHidEvent.HasModifierAlt,
   157                         HasModifierControl = aHidEvent.HasModifierControl,
   158                         HasModifierShift = aHidEvent.HasModifierShift,
   159                         HasModifierWindows = aHidEvent.HasModifierWindows,
   160                     };
   161                     Properties.Settings.Default.EarManager.TriggerEvent(e);
   162                 }                
   163 
   164             }
   165         }
   166 
   167     
   168 
   169     
   170 
   171 
   172         /// <summary>
   173         /// We need to handle WM_INPUT.
   174         /// </summary>
   175         /// <param name="message"></param>
   176         protected override void WndProc(ref Message message)
   177         {
   178             switch (message.Msg)
   179             {
   180                 case Const.WM_INPUT:
   181                     //Returning zero means we processed that message.
   182                     message.Result = new IntPtr(0);
   183                     Program.HidHandler.ProcessInput(ref message);
   184                     break;
   185             }
   186 
   187             //Pass this on to base class.
   188             base.WndProc(ref message);
   189         }
   190     }
   191 }