Generic HID event with key recognition functional.
3 using System.Collections.Generic;
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;
13 using Hid = SharpLib.Hid;
16 namespace SharpDisplayManager
19 /// Implement handling of HID input reports notably to be able to launch an application using the Green Start button from IR remotes.
21 [System.ComponentModel.DesignerCategory("Code")]
22 public class FormMainHid : Form
25 public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent);
29 /// Register HID devices so that we receive corresponding WM_INPUT messages.
31 protected void RegisterHidDevices()
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.
37 RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[6];
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;
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;
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;
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;
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;
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;
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;
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;
88 Program.HidHandler = new SharpLib.Hid.Handler(rid);
89 if (!Program.HidHandler.IsRegistered)
91 Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
93 Program.HidHandler.OnHidEvent += HandleHidEventThreadSafe;
101 /// Here we receive HID events from our HID library.
103 /// <param name="aSender"></param>
104 /// <param name="aHidEvent"></param>
105 public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent)
107 if (aHidEvent.IsStray || !aHidEvent.IsValid)
109 //Stray event just ignore it
113 if (this.InvokeRequired)
115 //Not in the proper thread, invoke ourselves
116 OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe);
117 this.Invoke(d, new object[] { aSender, aHidEvent });
121 if (aHidEvent.IsGeneric)
123 if (aHidEvent.Usages.Count == 0)
125 //No usage, nothing to do then
129 //We are in the proper thread
130 if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl)
132 //Trigger events as needed
133 EventHidWindowsMediaCenter e = new EventHidWindowsMediaCenter
135 Usage = (Hid.Usage.WindowsMediaCenterRemoteControl) aHidEvent.Usages[0]
137 Properties.Settings.Default.EarManager.TriggerEvent(e);
139 else if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.Consumer)
141 //Trigger matching events if any
142 EventHidConsumerControl e = new EventHidConsumerControl
144 Usage = (Hid.Usage.ConsumerControl) aHidEvent.Usages[0]
146 Properties.Settings.Default.EarManager.TriggerEvent(e);
149 else if (aHidEvent.IsKeyboard)
151 //Trigger matching events if any
152 EventHidKeyboard e = new EventHidKeyboard
154 Key = aHidEvent.VirtualKey,
155 IsKeyUp = aHidEvent.IsButtonUp,
156 HasModifierAlt = aHidEvent.HasModifierAlt,
157 HasModifierControl = aHidEvent.HasModifierControl,
158 HasModifierShift = aHidEvent.HasModifierShift,
159 HasModifierWindows = aHidEvent.HasModifierWindows,
161 Properties.Settings.Default.EarManager.TriggerEvent(e);
173 /// We need to handle WM_INPUT.
175 /// <param name="message"></param>
176 protected override void WndProc(ref Message message)
181 //Returning zero means we processed that message.
182 message.Result = new IntPtr(0);
183 Program.HidHandler.ProcessInput(ref message);
187 //Pass this on to base class.
188 base.WndProc(ref message);