Fixing clients management.
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
17 /// Implement handling of HID input reports notably to be able to launch an application using the Green Start button from IR remotes.
19 [System.ComponentModel.DesignerCategory("Code")]
20 public class MainFormHid : Form
22 [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SwitchToThisWindow")]
23 public static extern void SwitchToThisWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hwnd, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool fUnknown);
25 public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent);
28 /// Use notably to handle green start key from IR remote control
30 private Hid.Handler iHidHandler;
33 /// Register HID devices so that we receive corresponding WM_INPUT messages.
35 protected void RegisterHidDevices()
37 // Register the input device to receive the commands from the
38 // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
39 // for the vendor defined usage page.
41 RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[5];
44 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl;
45 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.WindowsMediaCenter.WindowsMediaCenterRemoteControl;
46 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
47 rid[i].hwndTarget = Handle;
50 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
51 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.ConsumerControl;
52 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
53 rid[i].hwndTarget = Handle;
56 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer;
57 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.Selection;
58 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
59 rid[i].hwndTarget = Handle;
62 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
63 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.SystemControl;
64 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
65 rid[i].hwndTarget = Handle;
68 rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
69 rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.GamePad;
70 rid[i].dwFlags = Const.RIDEV_INPUTSINK;
71 rid[i].hwndTarget = Handle;
74 //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls;
75 //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard;
76 //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
77 //rid[i].hwndTarget = Handle;
80 //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
81 //rid[i].usUsage = (ushort)Hid.UsageCollection.GenericDesktop.Mouse;
82 //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
83 //rid[i].hwndTarget = aHWND;
86 iHidHandler = new SharpLib.Hid.Handler(rid);
87 if (!iHidHandler.IsRegistered)
89 Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
91 iHidHandler.OnHidEvent += HandleHidEventThreadSafe;
95 /// Here we receive HID events from our HID library.
97 /// <param name="aSender"></param>
98 /// <param name="aHidEvent"></param>
99 public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent)
101 if (aHidEvent.IsStray)
103 //Stray event just ignore it
107 if (this.InvokeRequired)
109 //Not in the proper thread, invoke ourselves
110 OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe);
111 this.Invoke(d, new object[] { aSender, aHidEvent });
115 //We are in the proper thread
116 if (aHidEvent.Usages.Count > 0
117 && aHidEvent.UsagePage == (ushort)Hid.UsagePage.WindowsMediaCenterRemoteControl
118 && aHidEvent.Usages[0] == (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.GreenStart)
119 //&& aHidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer
120 //&& aHidEvent.Usages[0] == (ushort)Hid.Usage.ConsumerControl.ThinkPadFullscreenMagnifier)
122 //First check if the process we want to launch already exists
123 string procName = Path.GetFileNameWithoutExtension(Properties.Settings.Default.StartFileName);
124 Process[] existingProcesses = Process.GetProcessesByName(procName);
125 if (existingProcesses == null || existingProcesses.Length == 0)
127 // Process do not exists just try to launch it
128 ProcessStartInfo start = new ProcessStartInfo();
129 // Enter in the command line arguments, everything you would enter after the executable name itself
130 //start.Arguments = arguments;
131 // Enter the executable to run, including the complete path
132 start.FileName = Properties.Settings.Default.StartFileName;
133 start.WindowStyle = ProcessWindowStyle.Normal;
134 start.CreateNoWindow = true;
135 start.UseShellExecute = true;
136 // Run the external process & wait for it to finish
137 Process proc = Process.Start(start);
139 //SL: We could have used that too
140 //Shell32.Shell shell = new Shell32.Shell();
141 //shell.ShellExecute(Properties.Settings.Default.StartFileName);
145 //This won't work properly until we have a manifest that enables uiAccess.
146 //However uiAccess just won't work with ClickOnce so we will have to use a different deployment system.
147 SwitchToThisWindow(existingProcesses[0].MainWindowHandle, true);
154 /// We need to handle WM_INPUT.
156 /// <param name="message"></param>
157 protected override void WndProc(ref Message message)
162 //Returning zero means we processed that message.
163 message.Result = new IntPtr(0);
164 iHidHandler.ProcessInput(ref message);
167 //Is that needed? Check the docs.
168 base.WndProc(ref message);