Adding better support for multiple usage per report.
authorStephaneLenclud
Wed, 11 Feb 2015 19:46:21 +0100
changeset 492ec781e51f36
parent 48 1eb878505ae1
child 50 e6c103ebb155
Adding better support for multiple usage per report.
Now registering for gamepad input.
HidEvent.cs
HidHandler.cs
MainForm.cs
RemoteControlDevice.cs
     1.1 --- a/HidEvent.cs	Mon Feb 02 22:12:15 2015 +0100
     1.2 +++ b/HidEvent.cs	Wed Feb 11 19:46:21 2015 +0100
     1.3 @@ -23,7 +23,7 @@
     1.4          public bool IsKeyboard { get; private set; }
     1.5          public bool IsGeneric { get; private set; }
     1.6          public bool IsButtonDown { get { return Usages.Count == 1 && Usages[0] != 0; } }
     1.7 -        public bool IsButtonUp { get { return Usages.Count == 1 && Usages[0] == 0; } }
     1.8 +        public bool IsButtonUp { get { return Usages.Count == 0; } }
     1.9          public bool IsRepeat { get { return RepeatCount != 0; } }
    1.10          public uint RepeatCount { get; private set; }
    1.11  
    1.12 @@ -32,8 +32,10 @@
    1.13          public ushort UsagePage { get; private set; }
    1.14          public ushort UsageCollection { get; private set; }
    1.15          public uint UsageId { get { return ((uint)UsagePage << 16 | (uint)UsageCollection); } }
    1.16 -        public List<ushort> Usages { get; private set; }        
    1.17 -        public delegate void HidEventRepeatDelegate(HidEvent aHidEvent);
    1.18 +        public List<ushort> Usages { get; private set; }
    1.19 +		public byte[] InputReport { get; private set; }
    1.20 +		//
    1.21 +		public delegate void HidEventRepeatDelegate(HidEvent aHidEvent);
    1.22          public event HidEventRepeatDelegate OnHidEventRepeat;
    1.23  
    1.24          private System.Timers.Timer Timer { get; set; }
    1.25 @@ -138,7 +140,7 @@
    1.26                      }
    1.27  
    1.28                      //Allocate a buffer for one HID input
    1.29 -                    byte[] hidInputReport = new byte[rawInput.hid.dwSizeHid];
    1.30 +					InputReport = new byte[rawInput.hid.dwSizeHid];
    1.31  
    1.32                      Debug.WriteLine("Raw input contains " + rawInput.hid.dwCount + " HID input report(s)");
    1.33  
    1.34 @@ -155,33 +157,46 @@
    1.35                          }
    1.36  
    1.37                          //Copy HID input into our buffer
    1.38 -                        Marshal.Copy(new IntPtr(hidInputOffset), hidInputReport, 0, (int)rawInput.hid.dwSizeHid);
    1.39 +						Marshal.Copy(new IntPtr(hidInputOffset), InputReport, 0, (int)rawInput.hid.dwSizeHid);
    1.40  
    1.41                          //Print HID input report in our debug output
    1.42 -                        string hidDump = "HID input report: ";
    1.43 -                        foreach (byte b in hidInputReport)
    1.44 -                        {
    1.45 -                            hidDump += b.ToString("X2");
    1.46 -                        }
    1.47 -                        Debug.WriteLine(hidDump);
    1.48 +                        //string hidDump = "HID input report: " + InputReportString();
    1.49 +                        //Debug.WriteLine(hidDump);
    1.50  
    1.51 -                        //Proper parsing now
    1.52 -                        uint usageCount = 1; //Assuming a single usage per input report. Is that correct?
    1.53 -                        Win32.USAGE_AND_PAGE[] usages = new Win32.USAGE_AND_PAGE[usageCount];
    1.54 -                        Win32.HidStatus status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, preParsedData, hidInputReport, (uint)hidInputReport.Length);
    1.55 -                        if (status != Win32.HidStatus.HIDP_STATUS_SUCCESS)
    1.56 -                        {
    1.57 -                            Debug.WriteLine("Could not parse HID data!");
    1.58 -                        }
    1.59 -                        else
    1.60 -                        {
    1.61 -                            //Debug.WriteLine("UsagePage: 0x" + usages[0].UsagePage.ToString("X4"));
    1.62 -                            //Debug.WriteLine("Usage: 0x" + usages[0].Usage.ToString("X4"));
    1.63 -                            //Add this usage to our list
    1.64 -                            Usages.Add(usages[0].Usage);
    1.65 -                        }
    1.66 +                        //Do proper parsing of our HID report
    1.67 +						//First query our usage count
    1.68 +                        uint usageCount = 0; 
    1.69 +                        Win32.USAGE_AND_PAGE[] usages = null;
    1.70 +						Win32.HidStatus status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, preParsedData, InputReport, (uint)InputReport.Length);
    1.71 +						if (status == Win32.HidStatus.HIDP_STATUS_BUFFER_TOO_SMALL)
    1.72 +						{
    1.73 +							//Allocate a large enough buffer 
    1.74 +							usages = new Win32.USAGE_AND_PAGE[usageCount];
    1.75 +							//...and fetch our usages
    1.76 +							status = Win32.Function.HidP_GetUsagesEx(Win32.HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, preParsedData, InputReport, (uint)InputReport.Length);
    1.77 +							if (status != Win32.HidStatus.HIDP_STATUS_SUCCESS)
    1.78 +							{
    1.79 +								Debug.WriteLine("Second pass could not parse HID data: " + status.ToString());
    1.80 +							}
    1.81 +						}
    1.82 +						else if (status != Win32.HidStatus.HIDP_STATUS_SUCCESS) 
    1.83 +						{
    1.84 +							Debug.WriteLine("First pass could not parse HID data: " + status.ToString());
    1.85 +						}
    1.86 +
    1.87 +						Debug.WriteLine("Usage count: " + usageCount.ToString());
    1.88 +
    1.89 +						if (usages != null)
    1.90 +						{
    1.91 +							foreach (USAGE_AND_PAGE up in usages)
    1.92 +							{
    1.93 +								//Debug.WriteLine("UsagePage: 0x" + usages[0].UsagePage.ToString("X4"));
    1.94 +								//Debug.WriteLine("Usage: 0x" + usages[0].Usage.ToString("X4"));
    1.95 +								//Add this usage to our list
    1.96 +								Usages.Add(up.Usage);
    1.97 +							}
    1.98 +						}
    1.99                      }
   1.100 -
   1.101                  }
   1.102                  else if (rawInput.header.dwType == Const.RIM_TYPEMOUSE)
   1.103                  {
   1.104 @@ -214,35 +229,13 @@
   1.105              //
   1.106              if (IsButtonDown)
   1.107              {
   1.108 +				//TODO: Make this optional
   1.109                  StartRepeatTimer(iRepeatDelay);
   1.110              }
   1.111              
   1.112              IsValid = true;
   1.113          }
   1.114  
   1.115 -        /// <summary>
   1.116 -        /// Print information about this device to our debug output.
   1.117 -        /// </summary>
   1.118 -        public void DebugWrite()
   1.119 -        {
   1.120 -            if (!IsValid)
   1.121 -            {
   1.122 -                Debug.WriteLine("==== Invalid HidEvent");
   1.123 -                return;
   1.124 -            }
   1.125 -            Device.DebugWrite();
   1.126 -            if (IsGeneric) Debug.WriteLine("==== Generic");
   1.127 -            if (IsKeyboard) Debug.WriteLine("==== Keyboard");
   1.128 -            if (IsMouse) Debug.WriteLine("==== Mouse");
   1.129 -            Debug.WriteLine("==== Foreground: " + IsForeground.ToString());
   1.130 -            Debug.WriteLine("==== UsagePage: 0x" + UsagePage.ToString("X4"));
   1.131 -            Debug.WriteLine("==== UsageCollection: 0x" + UsageCollection.ToString("X4"));
   1.132 -            foreach (ushort usage in Usages)
   1.133 -            {
   1.134 -                Debug.WriteLine("==== Usage: 0x" + usage.ToString("X4"));
   1.135 -            }
   1.136 -        }
   1.137 -
   1.138          public void StartRepeatTimer(double aInterval)
   1.139          {
   1.140              if (Timer == null)
   1.141 @@ -277,24 +270,79 @@
   1.142              aHidEvent.OnHidEventRepeat(aHidEvent);
   1.143          }
   1.144  
   1.145 +		/// <summary>
   1.146 +		/// Print information about this device to our debug output.
   1.147 +		/// </summary>
   1.148 +		public void DebugWrite()
   1.149 +		{
   1.150 +			if (!IsValid)
   1.151 +			{
   1.152 +				Debug.WriteLine("==== Invalid HidEvent");
   1.153 +				return;
   1.154 +			}
   1.155 +			Device.DebugWrite();
   1.156 +			if (IsGeneric) Debug.WriteLine("==== Generic");
   1.157 +			if (IsKeyboard) Debug.WriteLine("==== Keyboard");
   1.158 +			if (IsMouse) Debug.WriteLine("==== Mouse");
   1.159 +			Debug.WriteLine("==== Foreground: " + IsForeground.ToString());
   1.160 +			Debug.WriteLine("==== UsagePage: 0x" + UsagePage.ToString("X4"));
   1.161 +			Debug.WriteLine("==== UsageCollection: 0x" + UsageCollection.ToString("X4"));
   1.162 +			Debug.WriteLine("==== InputReport: 0x" + InputReportString());
   1.163 +			foreach (ushort usage in Usages)
   1.164 +			{
   1.165 +				Debug.WriteLine("==== Usage: 0x" + usage.ToString("X4"));
   1.166 +			}
   1.167 +		}
   1.168 +
   1.169 +		/// <summary>
   1.170 +		/// 
   1.171 +		/// </summary>
   1.172 +		/// <returns></returns>
   1.173 +		public string InputReportString()
   1.174 +		{
   1.175 +			string hidDump = "";
   1.176 +			foreach (byte b in InputReport)
   1.177 +			{
   1.178 +				hidDump += b.ToString("X2");
   1.179 +			}
   1.180 +			return hidDump;
   1.181 +		}
   1.182 +
   1.183 +
   1.184 +		/// <summary>
   1.185 +		/// Create a list view item describing this HidEvent
   1.186 +		/// </summary>
   1.187 +		/// <returns></returns>
   1.188          public ListViewItem ToListViewItem()
   1.189          {
   1.190 -            //TODO: What to do with multiple usage
   1.191 -            string usage = "";
   1.192 -            UsagePage usagePage = (UsagePage)UsagePage;
   1.193 -            switch (usagePage)
   1.194 -            {
   1.195 -                case Hid.UsagePage.Consumer:
   1.196 -                    usage = ((Hid.UsageTables.ConsumerControl)Usages[0]).ToString();
   1.197 -                    break;
   1.198 +            string usageText = "";
   1.199  
   1.200 -                case Hid.UsagePage.WindowsMediaCenterRemoteControl:
   1.201 -                    usage = ((Hid.UsageTables.WindowsMediaCenterRemoteControl)Usages[0]).ToString();
   1.202 -                    break;
   1.203 +			foreach (ushort usage in Usages)
   1.204 +			{
   1.205 +				if (usageText != "")
   1.206 +				{
   1.207 +					//Add a separator
   1.208 +					usageText += ", ";
   1.209 +				}
   1.210  
   1.211 -            }
   1.212 +				UsagePage usagePage = (UsagePage)UsagePage;
   1.213 +				switch (usagePage)
   1.214 +				{
   1.215 +					case Hid.UsagePage.Consumer:
   1.216 +						usageText += ((Hid.UsageTables.ConsumerControl)usage).ToString();
   1.217 +						break;
   1.218  
   1.219 -            ListViewItem item = new ListViewItem(new[] { usage, UsagePage.ToString("X2"), UsageCollection.ToString("X2"), RepeatCount.ToString(), Time.ToString("HH:mm:ss:fff") });
   1.220 +					case Hid.UsagePage.WindowsMediaCenterRemoteControl:
   1.221 +						usageText += ((Hid.UsageTables.WindowsMediaCenterRemoteControl)usage).ToString();
   1.222 +						break;
   1.223 +
   1.224 +					default:
   1.225 +						usageText += usage.ToString("X2");
   1.226 +						break;
   1.227 +				}				
   1.228 +			}
   1.229 +
   1.230 +			ListViewItem item = new ListViewItem(new[] { usageText, InputReportString(), UsagePage.ToString("X2"), UsageCollection.ToString("X2"), RepeatCount.ToString(), Time.ToString("HH:mm:ss:fff") });
   1.231              return item;
   1.232          }
   1.233  
     2.1 --- a/HidHandler.cs	Mon Feb 02 22:12:15 2015 +0100
     2.2 +++ b/HidHandler.cs	Wed Feb 11 19:46:21 2015 +0100
     2.3 @@ -10,8 +10,6 @@
     2.4  
     2.5  namespace Hid
     2.6  {
     2.7 -
     2.8 -
     2.9      /// <summary>
    2.10      /// Our HID handler manages raw input registrations, processes WM_INPUT messages and broadcasts HID events in return.
    2.11      /// </summary>
    2.12 @@ -42,7 +40,7 @@
    2.13              }
    2.14  
    2.15              //
    2.16 -            if (hidEvent.Usages[0] == 0)
    2.17 +            if (hidEvent.IsButtonUp)
    2.18              {
    2.19                  //This is a key up event
    2.20                  //We need to discard any events belonging to the same page and collection
     3.1 --- a/MainForm.cs	Mon Feb 02 22:12:15 2015 +0100
     3.2 +++ b/MainForm.cs	Wed Feb 11 19:46:21 2015 +0100
     3.3 @@ -21,11 +21,13 @@
     3.4          private Label labelButtonName;
     3.5          private Label labelDeviceName;
     3.6          private ListView listViewEvents;
     3.7 -        private ColumnHeader columnHeaderUsage;
     3.8 +        private ColumnHeader columnHeaderUsages;
     3.9          private ColumnHeader columnHeaderUsagePage;
    3.10          private ColumnHeader columnHeaderUsageCollection;
    3.11          private ColumnHeader columnHeaderRepeat;
    3.12          private ColumnHeader columnHeaderTime;
    3.13 +		private Button buttonClear;
    3.14 +		private ColumnHeader columnHeaderInputReport;
    3.15  		private Timer _timer;
    3.16  
    3.17          public delegate void OnHidEventDelegate(object aSender, Hid.HidEvent aHidEvent);
    3.18 @@ -65,93 +67,113 @@
    3.19  		/// </summary>
    3.20  		private void InitializeComponent()
    3.21  		{
    3.22 -            this.labelButtonName = new System.Windows.Forms.Label();
    3.23 -            this.labelDeviceName = new System.Windows.Forms.Label();
    3.24 -            this.listViewEvents = new System.Windows.Forms.ListView();
    3.25 -            this.columnHeaderUsage = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.26 -            this.columnHeaderUsagePage = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.27 -            this.columnHeaderUsageCollection = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.28 -            this.columnHeaderRepeat = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.29 -            this.columnHeaderTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.30 -            this.SuspendLayout();
    3.31 -            // 
    3.32 -            // labelButtonName
    3.33 -            // 
    3.34 -            this.labelButtonName.AutoSize = true;
    3.35 -            this.labelButtonName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
    3.36 -            this.labelButtonName.Location = new System.Drawing.Point(600, 32);
    3.37 -            this.labelButtonName.Name = "labelButtonName";
    3.38 -            this.labelButtonName.Size = new System.Drawing.Size(103, 20);
    3.39 -            this.labelButtonName.TabIndex = 0;
    3.40 -            this.labelButtonName.Text = "Button Name";
    3.41 -            // 
    3.42 -            // labelDeviceName
    3.43 -            // 
    3.44 -            this.labelDeviceName.AutoSize = true;
    3.45 -            this.labelDeviceName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
    3.46 -            this.labelDeviceName.Location = new System.Drawing.Point(600, 12);
    3.47 -            this.labelDeviceName.Name = "labelDeviceName";
    3.48 -            this.labelDeviceName.Size = new System.Drawing.Size(103, 20);
    3.49 -            this.labelDeviceName.TabIndex = 1;
    3.50 -            this.labelDeviceName.Text = "Device Name";
    3.51 -            // 
    3.52 -            // listViewEvents
    3.53 -            // 
    3.54 -            this.listViewEvents.Alignment = System.Windows.Forms.ListViewAlignment.Left;
    3.55 -            this.listViewEvents.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
    3.56 +			this.labelButtonName = new System.Windows.Forms.Label();
    3.57 +			this.labelDeviceName = new System.Windows.Forms.Label();
    3.58 +			this.listViewEvents = new System.Windows.Forms.ListView();
    3.59 +			this.columnHeaderUsages = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.60 +			this.columnHeaderUsagePage = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.61 +			this.columnHeaderUsageCollection = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.62 +			this.columnHeaderRepeat = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.63 +			this.columnHeaderTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.64 +			this.buttonClear = new System.Windows.Forms.Button();
    3.65 +			this.columnHeaderInputReport = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
    3.66 +			this.SuspendLayout();
    3.67 +			// 
    3.68 +			// labelButtonName
    3.69 +			// 
    3.70 +			this.labelButtonName.AutoSize = true;
    3.71 +			this.labelButtonName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
    3.72 +			this.labelButtonName.Location = new System.Drawing.Point(811, 55);
    3.73 +			this.labelButtonName.Name = "labelButtonName";
    3.74 +			this.labelButtonName.Size = new System.Drawing.Size(103, 20);
    3.75 +			this.labelButtonName.TabIndex = 0;
    3.76 +			this.labelButtonName.Text = "Button Name";
    3.77 +			// 
    3.78 +			// labelDeviceName
    3.79 +			// 
    3.80 +			this.labelDeviceName.AutoSize = true;
    3.81 +			this.labelDeviceName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
    3.82 +			this.labelDeviceName.Location = new System.Drawing.Point(811, 35);
    3.83 +			this.labelDeviceName.Name = "labelDeviceName";
    3.84 +			this.labelDeviceName.Size = new System.Drawing.Size(103, 20);
    3.85 +			this.labelDeviceName.TabIndex = 1;
    3.86 +			this.labelDeviceName.Text = "Device Name";
    3.87 +			// 
    3.88 +			// listViewEvents
    3.89 +			// 
    3.90 +			this.listViewEvents.Alignment = System.Windows.Forms.ListViewAlignment.Left;
    3.91 +			this.listViewEvents.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
    3.92              | System.Windows.Forms.AnchorStyles.Left)));
    3.93 -            this.listViewEvents.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
    3.94 -            this.listViewEvents.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
    3.95 -            this.columnHeaderUsage,
    3.96 +			this.listViewEvents.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
    3.97 +			this.listViewEvents.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
    3.98 +            this.columnHeaderUsages,
    3.99 +            this.columnHeaderInputReport,
   3.100              this.columnHeaderUsagePage,
   3.101              this.columnHeaderUsageCollection,
   3.102              this.columnHeaderRepeat,
   3.103              this.columnHeaderTime});
   3.104 -            this.listViewEvents.GridLines = true;
   3.105 -            this.listViewEvents.Location = new System.Drawing.Point(12, 12);
   3.106 -            this.listViewEvents.Name = "listViewEvents";
   3.107 -            this.listViewEvents.Size = new System.Drawing.Size(582, 369);
   3.108 -            this.listViewEvents.TabIndex = 2;
   3.109 -            this.listViewEvents.UseCompatibleStateImageBehavior = false;
   3.110 -            this.listViewEvents.View = System.Windows.Forms.View.Details;
   3.111 -            // 
   3.112 -            // columnHeaderUsage
   3.113 -            // 
   3.114 -            this.columnHeaderUsage.Text = "Usage";
   3.115 -            this.columnHeaderUsage.Width = 180;
   3.116 -            // 
   3.117 -            // columnHeaderUsagePage
   3.118 -            // 
   3.119 -            this.columnHeaderUsagePage.Text = "Usage Page";
   3.120 -            this.columnHeaderUsagePage.Width = 120;
   3.121 -            // 
   3.122 -            // columnHeaderUsageCollection
   3.123 -            // 
   3.124 -            this.columnHeaderUsageCollection.Text = "Usage Collection";
   3.125 -            this.columnHeaderUsageCollection.Width = 120;
   3.126 -            // 
   3.127 -            // columnHeaderRepeat
   3.128 -            // 
   3.129 -            this.columnHeaderRepeat.Text = "Repeat";
   3.130 -            // 
   3.131 -            // columnHeaderTime
   3.132 -            // 
   3.133 -            this.columnHeaderTime.Text = "Time";
   3.134 -            this.columnHeaderTime.Width = 76;
   3.135 -            // 
   3.136 -            // MainForm
   3.137 -            // 
   3.138 -            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
   3.139 -            this.BackColor = System.Drawing.SystemColors.Control;
   3.140 -            this.ClientSize = new System.Drawing.Size(926, 393);
   3.141 -            this.Controls.Add(this.listViewEvents);
   3.142 -            this.Controls.Add(this.labelDeviceName);
   3.143 -            this.Controls.Add(this.labelButtonName);
   3.144 -            this.Name = "MainForm";
   3.145 -            this.Text = "Remote Control Sample";
   3.146 -            this.Load += new System.EventHandler(this.Form1_Load);
   3.147 -            this.ResumeLayout(false);
   3.148 -            this.PerformLayout();
   3.149 +			this.listViewEvents.GridLines = true;
   3.150 +			this.listViewEvents.Location = new System.Drawing.Point(12, 12);
   3.151 +			this.listViewEvents.Name = "listViewEvents";
   3.152 +			this.listViewEvents.Size = new System.Drawing.Size(766, 369);
   3.153 +			this.listViewEvents.TabIndex = 2;
   3.154 +			this.listViewEvents.UseCompatibleStateImageBehavior = false;
   3.155 +			this.listViewEvents.View = System.Windows.Forms.View.Details;
   3.156 +			// 
   3.157 +			// columnHeaderUsages
   3.158 +			// 
   3.159 +			this.columnHeaderUsages.Text = "Usages";
   3.160 +			this.columnHeaderUsages.Width = 180;
   3.161 +			// 
   3.162 +			// columnHeaderUsagePage
   3.163 +			// 
   3.164 +			this.columnHeaderUsagePage.Text = "Usage Page";
   3.165 +			this.columnHeaderUsagePage.Width = 87;
   3.166 +			// 
   3.167 +			// columnHeaderUsageCollection
   3.168 +			// 
   3.169 +			this.columnHeaderUsageCollection.Text = "Usage Collection";
   3.170 +			this.columnHeaderUsageCollection.Width = 134;
   3.171 +			// 
   3.172 +			// columnHeaderRepeat
   3.173 +			// 
   3.174 +			this.columnHeaderRepeat.Text = "Repeat";
   3.175 +			this.columnHeaderRepeat.Width = 68;
   3.176 +			// 
   3.177 +			// columnHeaderTime
   3.178 +			// 
   3.179 +			this.columnHeaderTime.Text = "Time";
   3.180 +			this.columnHeaderTime.Width = 76;
   3.181 +			// 
   3.182 +			// buttonClear
   3.183 +			// 
   3.184 +			this.buttonClear.Location = new System.Drawing.Point(839, 9);
   3.185 +			this.buttonClear.Name = "buttonClear";
   3.186 +			this.buttonClear.Size = new System.Drawing.Size(75, 23);
   3.187 +			this.buttonClear.TabIndex = 3;
   3.188 +			this.buttonClear.Text = "Clear";
   3.189 +			this.buttonClear.UseVisualStyleBackColor = true;
   3.190 +			this.buttonClear.Click += new System.EventHandler(this.buttonClear_Click);
   3.191 +			// 
   3.192 +			// columnHeaderInputReport
   3.193 +			// 
   3.194 +			this.columnHeaderInputReport.Text = "Input Report";
   3.195 +			this.columnHeaderInputReport.Width = 176;
   3.196 +			// 
   3.197 +			// MainForm
   3.198 +			// 
   3.199 +			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
   3.200 +			this.BackColor = System.Drawing.SystemColors.Control;
   3.201 +			this.ClientSize = new System.Drawing.Size(926, 393);
   3.202 +			this.Controls.Add(this.buttonClear);
   3.203 +			this.Controls.Add(this.listViewEvents);
   3.204 +			this.Controls.Add(this.labelDeviceName);
   3.205 +			this.Controls.Add(this.labelButtonName);
   3.206 +			this.Name = "MainForm";
   3.207 +			this.Text = "Remote Control Sample";
   3.208 +			this.Load += new System.EventHandler(this.Form1_Load);
   3.209 +			this.ResumeLayout(false);
   3.210 +			this.PerformLayout();
   3.211  
   3.212  		}
   3.213  		#endregion Windows Form Designer generated code
   3.214 @@ -247,5 +269,10 @@
   3.215  			labelButtonName.Text = "Ready...";
   3.216  		}
   3.217  
   3.218 +		private void buttonClear_Click(object sender, EventArgs e)
   3.219 +		{
   3.220 +			listViewEvents.Items.Clear();
   3.221 +		}
   3.222 +
   3.223  	}
   3.224  }
     4.1 --- a/RemoteControlDevice.cs	Mon Feb 02 22:12:15 2015 +0100
     4.2 +++ b/RemoteControlDevice.cs	Wed Feb 11 19:46:21 2015 +0100
     4.3 @@ -205,6 +205,12 @@
     4.4              rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
     4.5              rid[i].hwndTarget = aHWND;
     4.6  
     4.7 +			//i++;
     4.8 +			rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
     4.9 +			rid[i].usUsage = (ushort)Hid.UsageCollectionGenericDesktop.GamePad;
    4.10 +			rid[i].dwFlags = Const.RIDEV_EXINPUTSINK;
    4.11 +			rid[i].hwndTarget = aHWND;
    4.12 +
    4.13              //i++;
    4.14              //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls;
    4.15              //rid[i].usUsage = (ushort)Hid.UsageCollectionGenericDesktop.Keyboard;