3 using System.Collections.Generic;
6 using System.Threading.Tasks;
7 using System.Diagnostics;
8 using System.Runtime.InteropServices;
9 using System.Windows.Forms;
11 using Hid = SharpLib.Hid;
14 namespace SharpDisplayManager
16 [System.ComponentModel.DesignerCategory("Code")]
17 public class MainFormHid : Form
19 [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SwitchToThisWindow")]
20 public static extern void SwitchToThisWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hwnd, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool fUnknown);
22 public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent);
25 /// Use notably to handle green start key from IR remote control
27 private Hid.Handler iHidHandler;
30 /// Register HID devices so that we receive corresponding WM_INPUT messages.
32 protected void RegisterHidDevices()
34 // Register the input device to receive the commands from the
35 // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
36 // for the vendor defined usage page.
38 RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[5];
41 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl;
42 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.WindowsMediaCenter.WindowsMediaCenterRemoteControl;
43 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
44 rid[i].hwndTarget = Handle;
47 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
48 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.ConsumerControl;
49 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
50 rid[i].hwndTarget = Handle;
53 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
54 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.Selection;
55 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
56 rid[i].hwndTarget = Handle;
59 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
60 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.SystemControl;
61 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
62 rid[i].hwndTarget = Handle;
65 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
66 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.GamePad;
67 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
68 rid[i].hwndTarget = Handle;
71 //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
72 //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
73 //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
74 //rid[i].hwndTarget = Handle;
77 //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
78 //rid[i].usUsage = (ushort)Hid.UsageCollection.GenericDesktop.Mouse;
79 //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
80 //rid[i].hwndTarget = aHWND;
83 iHidHandler = new SharpLib.Hid.Handler(rid);
84 if (!iHidHandler.IsRegistered)
86 Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
88 iHidHandler.OnHidEvent += HandleHidEventThreadSafe;
92 /// Here we receive HID events from our HID library.
94 /// <param name="aSender"></param>
95 /// <param name="aHidEvent"></param>
96 public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent)
98 if (aHidEvent.IsStray)
100 //Stray event just ignore it
104 if (this.InvokeRequired)
106 //Not in the proper thread, invoke ourselves
107 OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe);
108 this.Invoke(d, new object[] { aSender, aHidEvent });
112 //We are in the proper thread
113 if (aHidEvent.Usages.Count > 0
114 && aHidEvent.UsagePage == (ushort)Hid.UsagePage.WindowsMediaCenterRemoteControl
115 && aHidEvent.Usages[0] == (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.GreenStart)
116 //&& aHidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer
117 //&& aHidEvent.Usages[0] == (ushort)Hid.Usage.ConsumerControl.ThinkPadFullscreenMagnifier)
119 //First check if the process we want to launch already exists
120 string procName = Path.GetFileNameWithoutExtension(Properties.Settings.Default.StartFileName);
121 Process[] existingProcesses = Process.GetProcessesByName(procName);
122 if (existingProcesses == null || existingProcesses.Length == 0)
124 // Process do not exists just try to launch it
125 ProcessStartInfo start = new ProcessStartInfo();
126 // Enter in the command line arguments, everything you would enter after the executable name itself
127 //start.Arguments = arguments;
128 // Enter the executable to run, including the complete path
129 start.FileName = Properties.Settings.Default.StartFileName;
130 start.WindowStyle = ProcessWindowStyle.Normal;
131 start.CreateNoWindow = true;
132 start.UseShellExecute = true;
133 // Run the external process & wait for it to finish
134 Process proc = Process.Start(start);
136 //SL: We could have used that too
137 //Shell32.Shell shell = new Shell32.Shell();
138 //shell.ShellExecute(Properties.Settings.Default.StartFileName);
142 //This won't work properly until we have a manifest that enables uiAccess.
143 //However uiAccess just won't work with ClickOnce so we will have to use a different deployment system.
144 SwitchToThisWindow(existingProcesses[0].MainWindowHandle, true);
151 /// We need to handle WM_INPUT.
153 /// <param name="message"></param>
154 protected override void WndProc(ref Message message)
159 //Returning zero means we processed that message.
160 message.Result = new IntPtr(0);
161 iHidHandler.ProcessInput(ref message);
164 //Is that needed? Check the docs.
165 base.WndProc(ref message);