StephaneLenclud@125: using System; StephaneLenclud@126: using System.IO; StephaneLenclud@125: using System.Collections.Generic; StephaneLenclud@125: using System.Linq; StephaneLenclud@125: using System.Text; StephaneLenclud@125: using System.Threading.Tasks; StephaneLenclud@125: using System.Diagnostics; StephaneLenclud@125: using System.Runtime.InteropServices; StephaneLenclud@125: using System.Windows.Forms; StephaneLenclud@150: using Microsoft.Win32.SafeHandles; StephaneLenclud@155: using System.ComponentModel; StephaneLenclud@125: // StephaneLenclud@125: using Hid = SharpLib.Hid; StephaneLenclud@125: using SharpLib.Win32; StephaneLenclud@125: StephaneLenclud@125: namespace SharpDisplayManager StephaneLenclud@125: { StephaneLenclud@138: /// StephaneLenclud@138: /// Implement handling of HID input reports notably to be able to launch an application using the Green Start button from IR remotes. StephaneLenclud@138: /// StephaneLenclud@131: [System.ComponentModel.DesignerCategory("Code")] StephaneLenclud@226: public class FormMainHid : Form StephaneLenclud@131: { StephaneLenclud@131: // StephaneLenclud@131: public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent); StephaneLenclud@126: StephaneLenclud@126: StephaneLenclud@131: /// StephaneLenclud@131: /// Register HID devices so that we receive corresponding WM_INPUT messages. StephaneLenclud@131: /// StephaneLenclud@131: protected void RegisterHidDevices() StephaneLenclud@131: { StephaneLenclud@131: // Register the input device to receive the commands from the StephaneLenclud@131: // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp StephaneLenclud@131: // for the vendor defined usage page. StephaneLenclud@128: StephaneLenclud@241: RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[6]; StephaneLenclud@128: StephaneLenclud@131: int i = 0; StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl; StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.WindowsMediaCenter.WindowsMediaCenterRemoteControl; StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK; StephaneLenclud@131: rid[i].hwndTarget = Handle; StephaneLenclud@128: StephaneLenclud@131: i++; StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer; StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.ConsumerControl; StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK; StephaneLenclud@131: rid[i].hwndTarget = Handle; StephaneLenclud@126: StephaneLenclud@131: i++; StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer; StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.Selection; StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK; StephaneLenclud@131: rid[i].hwndTarget = Handle; StephaneLenclud@125: StephaneLenclud@131: i++; StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.SystemControl; StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK; StephaneLenclud@131: rid[i].hwndTarget = Handle; StephaneLenclud@125: StephaneLenclud@131: i++; StephaneLenclud@131: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; StephaneLenclud@131: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.GamePad; StephaneLenclud@233: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK; StephaneLenclud@131: rid[i].hwndTarget = Handle; StephaneLenclud@125: StephaneLenclud@241: i++; StephaneLenclud@241: rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; StephaneLenclud@241: rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard; StephaneLenclud@241: rid[i].dwFlags = RawInputDeviceFlags.RIDEV_INPUTSINK; StephaneLenclud@241: rid[i].hwndTarget = Handle; StephaneLenclud@241: StephaneLenclud@131: //i++; StephaneLenclud@131: //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; StephaneLenclud@131: //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard; StephaneLenclud@131: //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK; StephaneLenclud@131: //rid[i].hwndTarget = Handle; StephaneLenclud@125: StephaneLenclud@131: //i++; StephaneLenclud@131: //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls; StephaneLenclud@131: //rid[i].usUsage = (ushort)Hid.UsageCollection.GenericDesktop.Mouse; StephaneLenclud@131: //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK; StephaneLenclud@131: //rid[i].hwndTarget = aHWND; StephaneLenclud@125: StephaneLenclud@125: StephaneLenclud@246: Program.HidHandler = new SharpLib.Hid.Handler(rid); StephaneLenclud@246: if (!Program.HidHandler.IsRegistered) StephaneLenclud@131: { StephaneLenclud@131: Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString()); StephaneLenclud@131: } StephaneLenclud@246: Program.HidHandler.OnHidEvent += HandleHidEventThreadSafe; StephaneLenclud@159: StephaneLenclud@131: } StephaneLenclud@125: StephaneLenclud@159: StephaneLenclud@159: StephaneLenclud@159: StephaneLenclud@131: /// StephaneLenclud@131: /// Here we receive HID events from our HID library. StephaneLenclud@131: /// StephaneLenclud@131: /// StephaneLenclud@131: /// StephaneLenclud@131: public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent) StephaneLenclud@131: { StephaneLenclud@241: if (aHidEvent.IsStray || !aHidEvent.IsValid) StephaneLenclud@131: { StephaneLenclud@131: //Stray event just ignore it StephaneLenclud@131: return; StephaneLenclud@131: } StephaneLenclud@125: StephaneLenclud@131: if (this.InvokeRequired) StephaneLenclud@131: { StephaneLenclud@131: //Not in the proper thread, invoke ourselves StephaneLenclud@131: OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe); StephaneLenclud@131: this.Invoke(d, new object[] { aSender, aHidEvent }); StephaneLenclud@131: } StephaneLenclud@131: else StephaneLenclud@131: { StephaneLenclud@247: //Trigger corresponding EAR event if any StephaneLenclud@247: { StephaneLenclud@247: EventHid e = new EventHid(); StephaneLenclud@247: e.Copy(aHidEvent); StephaneLenclud@247: Properties.Settings.Default.EarManager.TriggerEvent(e); StephaneLenclud@247: } StephaneLenclud@247: StephaneLenclud@241: if (aHidEvent.IsGeneric) StephaneLenclud@150: { StephaneLenclud@241: if (aHidEvent.Usages.Count == 0) StephaneLenclud@241: { StephaneLenclud@241: //No usage, nothing to do then StephaneLenclud@241: return; StephaneLenclud@241: } StephaneLenclud@150: StephaneLenclud@241: //We are in the proper thread StephaneLenclud@241: if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl) StephaneLenclud@241: { StephaneLenclud@241: //Trigger events as needed StephaneLenclud@241: EventHidWindowsMediaCenter e = new EventHidWindowsMediaCenter StephaneLenclud@241: { StephaneLenclud@241: Usage = (Hid.Usage.WindowsMediaCenterRemoteControl) aHidEvent.Usages[0] StephaneLenclud@241: }; StephaneLenclud@241: Properties.Settings.Default.EarManager.TriggerEvent(e); StephaneLenclud@241: } StephaneLenclud@241: else if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.Consumer) StephaneLenclud@131: { StephaneLenclud@241: //Trigger matching events if any StephaneLenclud@241: EventHidConsumerControl e = new EventHidConsumerControl StephaneLenclud@241: { StephaneLenclud@241: Usage = (Hid.Usage.ConsumerControl) aHidEvent.Usages[0] StephaneLenclud@241: }; StephaneLenclud@241: Properties.Settings.Default.EarManager.TriggerEvent(e); StephaneLenclud@131: } StephaneLenclud@131: } StephaneLenclud@241: else if (aHidEvent.IsKeyboard) StephaneLenclud@237: { StephaneLenclud@241: //Trigger matching events if any StephaneLenclud@241: EventHidKeyboard e = new EventHidKeyboard StephaneLenclud@241: { StephaneLenclud@241: Key = aHidEvent.VirtualKey, StephaneLenclud@241: IsKeyUp = aHidEvent.IsButtonUp, StephaneLenclud@241: HasModifierAlt = aHidEvent.HasModifierAlt, StephaneLenclud@241: HasModifierControl = aHidEvent.HasModifierControl, StephaneLenclud@241: HasModifierShift = aHidEvent.HasModifierShift, StephaneLenclud@241: HasModifierWindows = aHidEvent.HasModifierWindows, StephaneLenclud@241: }; StephaneLenclud@238: Properties.Settings.Default.EarManager.TriggerEvent(e); StephaneLenclud@241: } StephaneLenclud@152: StephaneLenclud@131: } StephaneLenclud@131: } StephaneLenclud@125: StephaneLenclud@245: StephaneLenclud@155: StephaneLenclud@245: StephaneLenclud@167: StephaneLenclud@167: StephaneLenclud@131: /// StephaneLenclud@131: /// We need to handle WM_INPUT. StephaneLenclud@131: /// StephaneLenclud@131: /// StephaneLenclud@131: protected override void WndProc(ref Message message) StephaneLenclud@131: { StephaneLenclud@131: switch (message.Msg) StephaneLenclud@131: { StephaneLenclud@131: case Const.WM_INPUT: StephaneLenclud@131: //Returning zero means we processed that message. StephaneLenclud@131: message.Result = new IntPtr(0); StephaneLenclud@246: Program.HidHandler.ProcessInput(ref message); StephaneLenclud@131: break; StephaneLenclud@131: } StephaneLenclud@159: StephaneLenclud@167: //Pass this on to base class. StephaneLenclud@131: base.WndProc(ref message); StephaneLenclud@131: } StephaneLenclud@131: } StephaneLenclud@125: }