Server/MainForm.Hid.cs
author StephaneLenclud
Wed, 06 May 2015 22:07:32 +0200
changeset 136 8badd89fb78c
parent 130 c8d81bfa5fff
child 138 426cc984fd18
permissions -rw-r--r--
Click Once Publish
     1 using System;
     2 using System.IO;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 using System.Diagnostics;
     8 using System.Runtime.InteropServices;
     9 using System.Windows.Forms;
    10 //
    11 using Hid = SharpLib.Hid;
    12 using SharpLib.Win32;
    13 
    14 namespace SharpDisplayManager
    15 {
    16     [System.ComponentModel.DesignerCategory("Code")]
    17     public class MainFormHid : Form
    18     {
    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);
    21         //
    22         public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent);
    23 
    24         /// <summary>
    25         /// Use notably to handle green start key from IR remote control
    26         /// </summary>
    27         private Hid.Handler iHidHandler;
    28 
    29         /// <summary>
    30         /// Register HID devices so that we receive corresponding WM_INPUT messages.
    31         /// </summary>
    32         protected void RegisterHidDevices()
    33         {
    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.
    37 
    38             RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[5];
    39 
    40             int i = 0;
    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;
    45 
    46             i++;
    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;
    51 
    52             i++;
    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;
    57 
    58             i++;
    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;
    63 
    64             i++;
    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;
    69 
    70             //i++;
    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;
    75 
    76             //i++;
    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;
    81 
    82 
    83             iHidHandler = new SharpLib.Hid.Handler(rid);
    84             if (!iHidHandler.IsRegistered)
    85             {
    86                 Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
    87             }
    88             iHidHandler.OnHidEvent += HandleHidEventThreadSafe;
    89         }
    90 
    91         /// <summary>
    92         /// Here we receive HID events from our HID library.
    93         /// </summary>
    94         /// <param name="aSender"></param>
    95         /// <param name="aHidEvent"></param>
    96         public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent)
    97         {
    98             if (aHidEvent.IsStray)
    99             {
   100                 //Stray event just ignore it
   101                 return;
   102             }
   103 
   104             if (this.InvokeRequired)
   105             {
   106                 //Not in the proper thread, invoke ourselves
   107                 OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe);
   108                 this.Invoke(d, new object[] { aSender, aHidEvent });
   109             }
   110             else
   111             {
   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)
   118                 {
   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)
   123                     {
   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);
   135 
   136                         //SL: We could have used that too
   137                         //Shell32.Shell shell = new Shell32.Shell();
   138                         //shell.ShellExecute(Properties.Settings.Default.StartFileName);
   139                     }
   140                     else
   141                     {
   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);
   145                     }
   146                 }
   147             }
   148         }
   149 
   150         /// <summary>
   151         /// We need to handle WM_INPUT.
   152         /// </summary>
   153         /// <param name="message"></param>
   154         protected override void WndProc(ref Message message)
   155         {
   156             switch (message.Msg)
   157             {
   158                 case Const.WM_INPUT:
   159                     //Returning zero means we processed that message.
   160                     message.Result = new IntPtr(0);
   161                     iHidHandler.ProcessInput(ref message);
   162                     break;
   163             }
   164             //Is that needed? Check the docs.
   165             base.WndProc(ref message);
   166         }
   167     }
   168 }