Device Info moves where it belongs into our device class.
2 using System.Windows.Forms;
3 using System.Runtime.InteropServices;
4 using System.Diagnostics;
6 using Microsoft.Win32.SafeHandles;
13 namespace Devices.RemoteControl
16 public enum InputDevice
24 public enum RemoteControlButton
81 #region RemoteControlEventArgs
83 public class RemoteControlEventArgs : EventArgs
85 RemoteControlButton _rcb;
87 WindowsMediaCenterRemoteControl iMceButton;
88 ConsumerControl iConsumerControl;
90 public RemoteControlEventArgs(RemoteControlButton rcb, InputDevice device)
98 public RemoteControlEventArgs(ConsumerControl aConsumerControl, InputDevice device)
102 iConsumerControl = aConsumerControl;
107 public RemoteControlEventArgs(WindowsMediaCenterRemoteControl mce, InputDevice device)
115 private void SetNullButtons()
117 iConsumerControl = ConsumerControl.Null;
118 iMceButton = WindowsMediaCenterRemoteControl.Null;
119 _rcb = RemoteControlButton.Unknown;
122 public RemoteControlEventArgs()
124 iMceButton = WindowsMediaCenterRemoteControl.Null;
125 _rcb = RemoteControlButton.Unknown;
126 _device = InputDevice.Key;
129 public RemoteControlButton Button
132 set { _rcb = value; }
135 public WindowsMediaCenterRemoteControl MceButton
137 get { return iMceButton; }
138 set { iMceButton = value; }
141 public ConsumerControl ConsumerControl
143 get { return iConsumerControl; }
144 set { iConsumerControl = value; }
147 public InputDevice Device
149 get { return _device; }
150 set { _device = value; }
154 #endregion RemoteControlEventArgs
157 public sealed class RemoteControlDevice
159 public delegate bool RemoteControlDeviceEventHandler(object sender, RemoteControlEventArgs e);
160 public event RemoteControlDeviceEventHandler ButtonPressed;
163 /// Return true if the usage was processed.
165 /// <param name="aUsage"></param>
166 /// <returns></returns>
167 public delegate bool HidUsageHandler(ushort aUsage);
169 public Hid.HidHandler iHidHandler;
172 //-------------------------------------------------------------
174 //-------------------------------------------------------------
176 public RemoteControlDevice(IntPtr aHWND)
178 // Register the input device to receive the commands from the
179 // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
180 // for the vendor defined usage page.
182 RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[4];
185 rid[i].usUsagePage = (ushort)Hid.UsagePage.WindowsMediaCenterRemoteControl;
186 rid[i].usUsage = (ushort)Hid.UsageCollectionWindowsMediaCenter.WindowsMediaCenterRemoteControl;
187 rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
188 rid[i].hwndTarget = aHWND;
191 rid[i].usUsagePage = (ushort)Hid.UsagePage.Consumer;
192 rid[i].usUsage = (ushort)Hid.UsageCollectionConsumer.ConsumerControl;
193 rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
194 rid[i].hwndTarget = aHWND;
197 rid[i].usUsagePage = (ushort)Hid.UsagePage.Consumer;
198 rid[i].usUsage = (ushort)Hid.UsageCollectionConsumer.Selection;
199 rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
200 rid[i].hwndTarget = aHWND;
203 rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
204 rid[i].usUsage = (ushort)Hid.UsageCollectionGenericDesktop.SystemControl;
205 rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
206 rid[i].hwndTarget = aHWND;
209 rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
210 rid[i].usUsage = (ushort)Hid.UsageCollectionGenericDesktop.GamePad;
211 rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
212 rid[i].hwndTarget = aHWND;
215 //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
216 //rid[i].usUsage = (ushort)Hid.UsageCollectionGenericDesktop.Keyboard;
217 //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
218 //rid[i].hwndTarget = aHWND;
221 //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
222 //rid[i].usUsage = (ushort)Hid.UsageCollectionGenericDesktop.Mouse;
223 //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
224 //rid[i].hwndTarget = aHWND;
227 iHidHandler = new Hid.HidHandler(rid);
228 if (!iHidHandler.IsRegistered)
230 Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
232 iHidHandler.OnHidEvent += HandleHidEvent;
236 //-------------------------------------------------------------
238 //-------------------------------------------------------------
240 public void ProcessMessage(Message message)
244 case Const.WM_KEYDOWN:
245 ProcessKeyDown(message.WParam);
248 //Returning zero means we processed that message.
249 message.Result = new IntPtr(0);
250 ProcessInputCommand(ref message);
257 //-------------------------------------------------------------
259 //-------------------------------------------------------------
261 private void ProcessKeyDown(IntPtr wParam)
263 RemoteControlButton rcb = RemoteControlButton.Unknown;
265 switch (wParam.ToInt32())
267 case (int)Keys.Escape:
268 rcb = RemoteControlButton.Clear;
271 rcb = RemoteControlButton.Up;
274 rcb = RemoteControlButton.Down;
277 rcb = RemoteControlButton.Left;
279 case (int)Keys.Right:
280 rcb = RemoteControlButton.Right;
282 case (int)Keys.Enter:
283 rcb = RemoteControlButton.Enter;
286 rcb = RemoteControlButton.Digit0;
289 rcb = RemoteControlButton.Digit1;
292 rcb = RemoteControlButton.Digit2;
295 rcb = RemoteControlButton.Digit3;
298 rcb = RemoteControlButton.Digit4;
301 rcb = RemoteControlButton.Digit5;
304 rcb = RemoteControlButton.Digit6;
307 rcb = RemoteControlButton.Digit7;
310 rcb = RemoteControlButton.Digit8;
313 rcb = RemoteControlButton.Digit9;
317 if (this.ButtonPressed != null && rcb != RemoteControlButton.Unknown)
319 Debug.WriteLine("KeyDown: " + rcb.ToString());
320 this.ButtonPressed(this, new RemoteControlEventArgs(rcb, InputDevice.Key));
328 /// <param name="aUsage"></param>
329 private bool HidConsumerDeviceHandler(ushort aUsage)
337 if (Enum.IsDefined(typeof(ConsumerControl), aUsage) && aUsage != 0) //Our button is a known consumer control
339 if (this.ButtonPressed != null)
341 return this.ButtonPressed(this, new RemoteControlEventArgs((ConsumerControl)aUsage, InputDevice.OEM));
347 Debug.WriteLine("Unknown Consumer Control!");
355 /// <param name="aUsage"></param>
356 private bool HidMceRemoteHandler(ushort aUsage)
365 if (Enum.IsDefined(typeof(WindowsMediaCenterRemoteControl), aUsage) && aUsage != 0) //Our button is a known MCE button
367 if (this.ButtonPressed != null)
369 return this.ButtonPressed(this, new RemoteControlEventArgs((WindowsMediaCenterRemoteControl)aUsage, InputDevice.OEM));
375 Debug.WriteLine("Unknown MCE button!");
383 /// <param name="message"></param>
384 private void ProcessInputCommand(ref Message message)
386 //We received a WM_INPUT message
387 Debug.WriteLine("================WM_INPUT================");
389 iHidHandler.ProcessInput(message);
396 /// <param name="aSender"></param>
397 /// <param name="aHidEvent"></param>
398 void HandleHidEvent(object aSender, Hid.HidEvent aHidEvent)
400 HidUsageHandler usagePageHandler = null;
402 //Check if this an MCE remote HID message
403 if (aHidEvent.UsagePage == (ushort)Hid.UsagePage.WindowsMediaCenterRemoteControl && aHidEvent.UsageCollection == (ushort)Hid.UsageCollectionWindowsMediaCenter.WindowsMediaCenterRemoteControl)
405 usagePageHandler = HidMceRemoteHandler;
407 //Check if this is a consumer control HID message
408 else if (aHidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer && aHidEvent.UsageCollection == (ushort)Hid.UsageCollectionConsumer.ConsumerControl)
410 usagePageHandler = HidConsumerDeviceHandler;
412 //Unknown HID message
415 Debug.WriteLine("Unknown HID message.");
419 foreach (ushort usage in aHidEvent.Usages)
421 usagePageHandler(usage);