# HG changeset patch # User StephaneLenclud # Date 1426409617 -3600 # Node ID 471b1d45c46a0d752967cadfc8d3901a92a09bfe # Parent c28dd93b94c5be1ce8144e9871f59042650abc09 Adding button count property to HID device. Adding device list refresh button. Better reporting of input value capabilities description. diff -r c28dd93b94c5 -r 471b1d45c46a HidDevice.cs --- a/HidDevice.cs Thu Mar 05 10:12:37 2015 +0100 +++ b/HidDevice.cs Sun Mar 15 09:53:37 2015 +0100 @@ -47,6 +47,9 @@ public HIDP_VALUE_CAPS[] InputValueCapabilities { get { return iInputValueCapabilities; } } private HIDP_VALUE_CAPS[] iInputValueCapabilities; + // + public int ButtonCount { get; private set; } + /// /// Class constructor will fetch this object properties from HID sub system. /// @@ -167,6 +170,8 @@ { throw new Exception("HidDevice: HidP_GetButtonCaps failed: " + status.ToString()); } + + ComputeButtonCount(); } //Get input value caps if needed @@ -182,6 +187,23 @@ } } + + /// + /// Useful for gamepads. + /// + void ComputeButtonCount() + { + ButtonCount = 0; + foreach (HIDP_BUTTON_CAPS bc in iInputButtonCapabilities) + { + if (bc.IsRange) + { + ButtonCount += (bc.Range.UsageMax - bc.Range.UsageMin + 1); + } + } + } + + /// /// /// @@ -273,7 +295,8 @@ } /// - /// + /// Provide a description for the given capabilities. + /// Notably describes axis on a gamepad/joystick. /// /// /// @@ -281,7 +304,20 @@ { if (!aCaps.IsRange && Enum.IsDefined(typeof(UsagePage), Capabilities.UsagePage)) { - return "Input Value: " + Enum.GetName(Utils.UsageType((UsagePage)Capabilities.UsagePage), aCaps.NotRange.Usage); + Type usageType=Utils.UsageType((UsagePage)Capabilities.UsagePage); + string name = Enum.GetName(usageType, aCaps.NotRange.Usage); + if (name == null) + { + //Could not find that usage in our enum. + //Provide a relevant warning instead. + name = "Usage 0x" + aCaps.NotRange.Usage.ToString("X2") + " not defined in " + usageType.Name; + } + else + { + //Prepend our usage type name + name = usageType.Name + "." + name; + } + return "Input Value: " + name; } return null; diff -r c28dd93b94c5 -r 471b1d45c46a HidEvent.cs --- a/HidEvent.cs Thu Mar 05 10:12:37 2015 +0100 +++ b/HidEvent.cs Sun Mar 15 09:53:37 2015 +0100 @@ -22,6 +22,9 @@ public bool IsBackground { get { return !IsForeground; } } public bool IsMouse { get; private set; } public bool IsKeyboard { get; private set; } + /// + /// If this not a mouse or keyboard event then it's a generic HID event. + /// public bool IsGeneric { get; private set; } public bool IsButtonDown { get { return Usages.Count == 1 && Usages[0] != 0; } } public bool IsButtonUp { get { return Usages.Count == 0; } } @@ -29,6 +32,8 @@ public uint RepeatCount { get; private set; } public HidDevice Device { get; private set; } + public RAWINPUT RawInput { get {return iRawInput;} } + private RAWINPUT iRawInput; public ushort UsagePage { get; private set; } public ushort UsageCollection { get; private set; } @@ -76,7 +81,6 @@ IsKeyboard = false; IsGeneric = false; - Time = DateTime.Now; OriginalTime = DateTime.Now; Timer = new System.Timers.Timer(); @@ -105,8 +109,8 @@ try { //Fetch raw input - RAWINPUT rawInput = new RAWINPUT(); - if (!Win32.RawInput.GetRawInputData(aMessage.LParam, ref rawInput, ref rawInputBuffer)) + iRawInput = new RAWINPUT(); + if (!Win32.RawInput.GetRawInputData(aMessage.LParam, ref iRawInput, ref rawInputBuffer)) { Debug.WriteLine("GetRawInputData failed!"); return; @@ -114,13 +118,13 @@ //Our device can actually be null. //This is notably happening for some keyboard events - if (rawInput.header.hDevice != IntPtr.Zero) + if (RawInput.header.hDevice != IntPtr.Zero) { //Get various information about this HID device - Device = new Hid.HidDevice(rawInput.header.hDevice); + Device = new Hid.HidDevice(RawInput.header.hDevice); } - if (rawInput.header.dwType == Win32.RawInputDeviceType.RIM_TYPEHID) //Check that our raw input is HID + if (RawInput.header.dwType == Win32.RawInputDeviceType.RIM_TYPEHID) //Check that our raw input is HID { IsGeneric = true; @@ -130,31 +134,31 @@ UsagePage = Device.Info.hid.usUsagePage; UsageCollection = Device.Info.hid.usUsage; - if (!(rawInput.hid.dwSizeHid > 1 //Make sure our HID msg size more than 1. In fact the first ushort is irrelevant to us for now - && rawInput.hid.dwCount > 0)) //Check that we have at least one HID msg + if (!(RawInput.hid.dwSizeHid > 1 //Make sure our HID msg size more than 1. In fact the first ushort is irrelevant to us for now + && RawInput.hid.dwCount > 0)) //Check that we have at least one HID msg { return; } //Allocate a buffer for one HID input - InputReport = new byte[rawInput.hid.dwSizeHid]; + InputReport = new byte[RawInput.hid.dwSizeHid]; - Debug.WriteLine("Raw input contains " + rawInput.hid.dwCount + " HID input report(s)"); + Debug.WriteLine("Raw input contains " + RawInput.hid.dwCount + " HID input report(s)"); //For each HID input report in our raw input - for (int i = 0; i < rawInput.hid.dwCount; i++) + for (int i = 0; i < RawInput.hid.dwCount; i++) { //Compute the address from which to copy our HID input int hidInputOffset = 0; unsafe { byte* source = (byte*)rawInputBuffer; - source += sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + (rawInput.hid.dwSizeHid * i); + source += sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + (RawInput.hid.dwSizeHid * i); hidInputOffset = (int)source; } //Copy HID input into our buffer - Marshal.Copy(new IntPtr(hidInputOffset), InputReport, 0, (int)rawInput.hid.dwSizeHid); + Marshal.Copy(new IntPtr(hidInputOffset), InputReport, 0, (int)RawInput.hid.dwSizeHid); //Print HID input report in our debug output //string hidDump = "HID input report: " + InputReportString(); @@ -196,14 +200,14 @@ } } } - else if (rawInput.header.dwType == RawInputDeviceType.RIM_TYPEMOUSE) + else if (RawInput.header.dwType == RawInputDeviceType.RIM_TYPEMOUSE) { IsMouse = true; Debug.WriteLine("WM_INPUT source device is Mouse."); // do mouse handling... } - else if (rawInput.header.dwType == RawInputDeviceType.RIM_TYPEKEYBOARD) + else if (RawInput.header.dwType == RawInputDeviceType.RIM_TYPEKEYBOARD) { IsKeyboard = true; diff -r c28dd93b94c5 -r 471b1d45c46a MainForm.Designer.cs --- a/MainForm.Designer.cs Thu Mar 05 10:12:37 2015 +0100 +++ b/MainForm.Designer.cs Sun Mar 15 09:53:37 2015 +0100 @@ -29,15 +29,16 @@ this.buttonTreeViewExpandAll = new System.Windows.Forms.Button(); this.buttonTreeViewCollapseAll = new System.Windows.Forms.Button(); this.treeViewDevices = new System.Windows.Forms.TreeView(); + this.tabPageTests = new System.Windows.Forms.TabPage(); + this.textBoxTests = new System.Windows.Forms.TextBox(); this.statusStrip = new System.Windows.Forms.StatusStrip(); this.toolStripStatusLabelDevice = new System.Windows.Forms.ToolStripStatusLabel(); - this.tabPageTests = new System.Windows.Forms.TabPage(); - this.textBoxTests = new System.Windows.Forms.TextBox(); + this.buttonRefresh = new System.Windows.Forms.Button(); this.tabControl.SuspendLayout(); this.tabPageMessages.SuspendLayout(); this.tabPageDevices.SuspendLayout(); + this.tabPageTests.SuspendLayout(); this.statusStrip.SuspendLayout(); - this.tabPageTests.SuspendLayout(); this.SuspendLayout(); // // labelButtonName @@ -150,6 +151,7 @@ // // tabPageDevices // + this.tabPageDevices.Controls.Add(this.buttonRefresh); this.tabPageDevices.Controls.Add(this.buttonTreeViewExpandAll); this.tabPageDevices.Controls.Add(this.buttonTreeViewCollapseAll); this.tabPageDevices.Controls.Add(this.treeViewDevices); @@ -190,22 +192,6 @@ this.treeViewDevices.Size = new System.Drawing.Size(713, 492); this.treeViewDevices.TabIndex = 0; // - // statusStrip - // - this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripStatusLabelDevice}); - this.statusStrip.Location = new System.Drawing.Point(0, 547); - this.statusStrip.Name = "statusStrip"; - this.statusStrip.Size = new System.Drawing.Size(935, 22); - this.statusStrip.TabIndex = 5; - this.statusStrip.Text = "statusStrip1"; - // - // toolStripStatusLabelDevice - // - this.toolStripStatusLabelDevice.Name = "toolStripStatusLabelDevice"; - this.toolStripStatusLabelDevice.Size = new System.Drawing.Size(61, 17); - this.toolStripStatusLabelDevice.Text = "No Device"; - // // tabPageTests // this.tabPageTests.Controls.Add(this.textBoxTests); @@ -224,6 +210,32 @@ this.textBoxTests.Size = new System.Drawing.Size(887, 499); this.textBoxTests.TabIndex = 0; // + // statusStrip + // + this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripStatusLabelDevice}); + this.statusStrip.Location = new System.Drawing.Point(0, 547); + this.statusStrip.Name = "statusStrip"; + this.statusStrip.Size = new System.Drawing.Size(935, 22); + this.statusStrip.TabIndex = 5; + this.statusStrip.Text = "statusStrip1"; + // + // toolStripStatusLabelDevice + // + this.toolStripStatusLabelDevice.Name = "toolStripStatusLabelDevice"; + this.toolStripStatusLabelDevice.Size = new System.Drawing.Size(61, 17); + this.toolStripStatusLabelDevice.Text = "No Device"; + // + // buttonRefresh + // + this.buttonRefresh.Location = new System.Drawing.Point(813, 64); + this.buttonRefresh.Name = "buttonRefresh"; + this.buttonRefresh.Size = new System.Drawing.Size(75, 23); + this.buttonRefresh.TabIndex = 3; + this.buttonRefresh.Text = "Refresh"; + this.buttonRefresh.UseVisualStyleBackColor = true; + this.buttonRefresh.Click += new System.EventHandler(this.buttonRefresh_Click); + // // MainForm // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); @@ -238,10 +250,10 @@ this.tabPageMessages.ResumeLayout(false); this.tabPageMessages.PerformLayout(); this.tabPageDevices.ResumeLayout(false); + this.tabPageTests.ResumeLayout(false); + this.tabPageTests.PerformLayout(); this.statusStrip.ResumeLayout(false); this.statusStrip.PerformLayout(); - this.tabPageTests.ResumeLayout(false); - this.tabPageTests.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -254,6 +266,7 @@ private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelDevice; private System.Windows.Forms.TabPage tabPageTests; private System.Windows.Forms.TextBox textBoxTests; + private System.Windows.Forms.Button buttonRefresh; } } diff -r c28dd93b94c5 -r 471b1d45c46a MainForm.cs --- a/MainForm.cs Thu Mar 05 10:12:37 2015 +0100 +++ b/MainForm.cs Sun Mar 15 09:53:37 2015 +0100 @@ -177,5 +177,11 @@ treeViewDevices.ExpandAll(); } + private void buttonRefresh_Click(object sender, EventArgs e) + { + treeViewDevices.Nodes.Clear(); + Win32.RawInput.PopulateDeviceList(treeViewDevices); + } + } } diff -r c28dd93b94c5 -r 471b1d45c46a RawInput.cs --- a/RawInput.cs Thu Mar 05 10:12:37 2015 +0100 +++ b/RawInput.cs Sun Mar 15 09:53:37 2015 +0100 @@ -207,6 +207,10 @@ node.Nodes.Add(hidDevice.InputCapabilitiesDescription); } + //Add button count + node.Nodes.Add("Button Count: " + hidDevice.ButtonCount); + + //Those can be joystick/gamepad axis if (hidDevice.InputValueCapabilities != null) { foreach (HIDP_VALUE_CAPS caps in hidDevice.InputValueCapabilities) diff -r c28dd93b94c5 -r 471b1d45c46a Win32Hid.cs --- a/Win32Hid.cs Thu Mar 05 10:12:37 2015 +0100 +++ b/Win32Hid.cs Sun Mar 15 09:53:37 2015 +0100 @@ -302,10 +302,10 @@ /// Union Range/NotRange [FieldOffset(56)] - HIDP_BUTTON_CAPS_RANGE Range; + public HIDP_BUTTON_CAPS_RANGE Range; [FieldOffset(56)] - HIDP_BUTTON_CAPS_NOT_RANGE NotRange; + public HIDP_BUTTON_CAPS_NOT_RANGE NotRange; } ///