Switch solution to 2013.
Event repeat now a Handler option.
Handler now deregisters devices when disposed.
Adding Thinkpad custom usages.
1.1 --- a/Hid/HidEvent.cs Sun Mar 15 21:26:51 2015 +0100
1.2 +++ b/Hid/HidEvent.cs Tue Mar 17 15:35:58 2015 +0100
1.3 @@ -115,7 +115,7 @@
1.4 /// Initialize an HidEvent from a WM_INPUT message
1.5 /// </summary>
1.6 /// <param name="hRawInputDevice">Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice</param>
1.7 - public Event(Message aMessage, HidEventRepeatDelegate aRepeatDelegate)
1.8 + public Event(Message aMessage, HidEventRepeatDelegate aRepeatDelegate, bool aRepeat)
1.9 {
1.10 RepeatCount = 0;
1.11 IsValid = false;
1.12 @@ -236,10 +236,10 @@
1.13 }
1.14
1.15 //
1.16 - if (IsButtonDown)
1.17 + if (IsButtonDown && aRepeat)
1.18 {
1.19 //TODO: Make this optional
1.20 - //StartRepeatTimer(iRepeatDelay);
1.21 + StartRepeatTimer(iRepeatDelay);
1.22 }
1.23
1.24 IsValid = true;
1.25 @@ -527,20 +527,12 @@
1.26 }
1.27
1.28 UsagePage usagePage = (UsagePage)UsagePage;
1.29 - switch (usagePage)
1.30 + string name = Enum.GetName(Utils.UsageType(usagePage), usage);
1.31 + if (name == null)
1.32 {
1.33 - case Hid.UsagePage.Consumer:
1.34 - usageText += ((ConsumerControl)usage).ToString();
1.35 - break;
1.36 -
1.37 - case Hid.UsagePage.WindowsMediaCenterRemoteControl:
1.38 - usageText += ((WindowsMediaCenterRemoteControl)usage).ToString();
1.39 - break;
1.40 -
1.41 - default:
1.42 - usageText += usage.ToString("X2");
1.43 - break;
1.44 + name += usage.ToString("X2");
1.45 }
1.46 + usageText += name;
1.47 }
1.48
1.49 //If we are a gamepad display axis and dpad values
2.1 --- a/Hid/HidHandler.cs Sun Mar 15 21:26:51 2015 +0100
2.2 +++ b/Hid/HidHandler.cs Tue Mar 17 15:35:58 2015 +0100
2.3 @@ -33,19 +33,40 @@
2.4 /// <summary>
2.5 /// Our HID handler manages raw input registrations, processes WM_INPUT messages and broadcasts HID events in return.
2.6 /// </summary>
2.7 - public class Handler
2.8 + public class Handler : IDisposable
2.9 {
2.10 public delegate void HidEventHandler(object aSender, Event aHidEvent);
2.11 public event HidEventHandler OnHidEvent;
2.12 List<Event> iHidEvents;
2.13 + RAWINPUTDEVICE[] iRawInputDevices;
2.14
2.15
2.16 public bool IsRegistered { get; private set; }
2.17 + public bool ManageRepeats { get; private set; }
2.18
2.19 - public Handler(RAWINPUTDEVICE[] aRawInputDevices)
2.20 + public Handler(RAWINPUTDEVICE[] aRawInputDevices, bool aManageRepeats=false)
2.21 {
2.22 - iHidEvents=new List<Event>();
2.23 - IsRegistered = Function.RegisterRawInputDevices(aRawInputDevices, (uint)aRawInputDevices.Length, (uint)Marshal.SizeOf(aRawInputDevices[0]));
2.24 + iRawInputDevices = aRawInputDevices;
2.25 + iHidEvents = new List<Event>();
2.26 + IsRegistered = Function.RegisterRawInputDevices(iRawInputDevices, (uint)iRawInputDevices.Length, (uint)Marshal.SizeOf(iRawInputDevices[0]));
2.27 + ManageRepeats = aManageRepeats;
2.28 + }
2.29 +
2.30 + /// <summary>
2.31 + /// Will de-register devices.
2.32 + /// </summary>
2.33 + public void Dispose()
2.34 + {
2.35 + //Setup device removal
2.36 + for (int i=0; i<iRawInputDevices.Length; i++)
2.37 + {
2.38 + iRawInputDevices[i].dwFlags = Const.RIDEV_REMOVE;
2.39 + iRawInputDevices[i].hwndTarget = IntPtr.Zero;
2.40 + }
2.41 +
2.42 + //De-register
2.43 + Function.RegisterRawInputDevices(iRawInputDevices, (uint)iRawInputDevices.Length, (uint)Marshal.SizeOf(iRawInputDevices[0]));
2.44 + IsRegistered = false;
2.45 }
2.46
2.47 /// <summary>
2.48 @@ -60,7 +81,7 @@
2.49 return;
2.50 }
2.51
2.52 - Event hidEvent = new Event(aMessage, OnHidEventRepeat);
2.53 + Event hidEvent = new Event(aMessage, OnHidEventRepeat, ManageRepeats);
2.54 hidEvent.DebugWrite();
2.55
2.56 if (!hidEvent.IsValid || !hidEvent.IsGeneric)
2.57 @@ -70,23 +91,26 @@
2.58 }
2.59
2.60 //
2.61 - if (hidEvent.IsButtonUp)
2.62 + if (ManageRepeats)
2.63 {
2.64 - //This is a key up event
2.65 - //We need to discard any events belonging to the same page and collection
2.66 - for (int i = (iHidEvents.Count-1); i >= 0; i--)
2.67 + if (hidEvent.IsButtonUp)
2.68 {
2.69 - if (iHidEvents[i].UsageId == hidEvent.UsageId)
2.70 + //This is a key up event
2.71 + //We need to discard any events belonging to the same page and collection
2.72 + for (int i = (iHidEvents.Count - 1); i >= 0; i--)
2.73 {
2.74 - iHidEvents[i].Dispose();
2.75 - iHidEvents.RemoveAt(i);
2.76 + if (iHidEvents[i].UsageId == hidEvent.UsageId)
2.77 + {
2.78 + iHidEvents[i].Dispose();
2.79 + iHidEvents.RemoveAt(i);
2.80 + }
2.81 }
2.82 }
2.83 - }
2.84 - else
2.85 - {
2.86 - //Keep that event until we get a key up message
2.87 - iHidEvents.Add(hidEvent);
2.88 + else
2.89 + {
2.90 + //Keep that event until we get a key up message
2.91 + iHidEvents.Add(hidEvent);
2.92 + }
2.93 }
2.94
2.95 //Broadcast our events
3.1 --- a/Hid/HidUsageTables.cs Sun Mar 15 21:26:51 2015 +0100
3.2 +++ b/Hid/HidUsageTables.cs Tue Mar 17 15:35:58 2015 +0100
3.3 @@ -22,7 +22,7 @@
3.4 /// <summary>
3.5 /// From USB HID usage tables.
3.6 /// http://www.usb.org/developers/hidpage#HID_Usage
3.7 - /// http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf
3.8 + /// http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
3.9 /// </summary>
3.10 public enum UsagePage : ushort
3.11 {
3.12 @@ -322,6 +322,19 @@
3.13 Microphone = 0x04,
3.14 Headphone = 0x05,
3.15 GraphicEqualizer = 0x06,
3.16 + ThinkPadMicrophoneMute = 0x10, //Custom
3.17 + ThinkPadVantage = 0x11, //Custom
3.18 + ThinkPadSystemLock = 0x12, //Custom
3.19 + ThinkPadPowerManagement = 0x13, //Custom
3.20 + ThinkPadWirelessNetwork = 0x14, //Custom
3.21 + ThinkPadCamera = 0x15, //Custom
3.22 + ThinkPadDisplayScheme = 0x16, //Custom
3.23 + ThinkPadMouseProperties = 0x17, //Custom
3.24 + ThinkPadEject = 0x18, //Custom
3.25 + ThinkPadSystemHibernate = 0x19, //Custom
3.26 + ThinkPadBrightnessIncrement = 0x1A, //Custom
3.27 + ThinkPadBrightnessDecrement = 0x1B, //Custom
3.28 + ThinkPadFullscreenMagnifier = 0x1D, //Custom
3.29 Plus10 = 0x20,
3.30 Plus100 = 0x21,
3.31 AmPm = 0x22,
4.1 --- a/MainForm.Designer.cs Sun Mar 15 21:26:51 2015 +0100
4.2 +++ b/MainForm.Designer.cs Tue Mar 17 15:35:58 2015 +0100
4.3 @@ -51,6 +51,7 @@
4.4 this.textBoxTests = new System.Windows.Forms.TextBox();
4.5 this.statusStrip = new System.Windows.Forms.StatusStrip();
4.6 this.toolStripStatusLabelDevice = new System.Windows.Forms.ToolStripStatusLabel();
4.7 + this.checkBoxRepeat = new System.Windows.Forms.CheckBox();
4.8 this.tabControl.SuspendLayout();
4.9 this.tabPageMessages.SuspendLayout();
4.10 this.tabPageDevices.SuspendLayout();
4.11 @@ -83,6 +84,7 @@
4.12 //
4.13 // tabPageMessages
4.14 //
4.15 + this.tabPageMessages.Controls.Add(this.checkBoxRepeat);
4.16 this.tabPageMessages.Controls.Add(this.listViewEvents);
4.17 this.tabPageMessages.Controls.Add(this.buttonClear);
4.18 this.tabPageMessages.Location = new System.Drawing.Point(4, 22);
4.19 @@ -231,6 +233,17 @@
4.20 this.toolStripStatusLabelDevice.Size = new System.Drawing.Size(61, 17);
4.21 this.toolStripStatusLabelDevice.Text = "No Device";
4.22 //
4.23 + // checkBoxRepeat
4.24 + //
4.25 + this.checkBoxRepeat.AutoSize = true;
4.26 + this.checkBoxRepeat.Location = new System.Drawing.Point(813, 46);
4.27 + this.checkBoxRepeat.Name = "checkBoxRepeat";
4.28 + this.checkBoxRepeat.Size = new System.Drawing.Size(61, 17);
4.29 + this.checkBoxRepeat.TabIndex = 4;
4.30 + this.checkBoxRepeat.Text = "Repeat";
4.31 + this.checkBoxRepeat.UseVisualStyleBackColor = true;
4.32 + this.checkBoxRepeat.CheckedChanged += new System.EventHandler(this.checkBoxRepeat_CheckedChanged);
4.33 + //
4.34 // MainForm
4.35 //
4.36 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
4.37 @@ -243,6 +256,7 @@
4.38 this.Load += new System.EventHandler(this.MainForm_Load);
4.39 this.tabControl.ResumeLayout(false);
4.40 this.tabPageMessages.ResumeLayout(false);
4.41 + this.tabPageMessages.PerformLayout();
4.42 this.tabPageDevices.ResumeLayout(false);
4.43 this.tabPageTests.ResumeLayout(false);
4.44 this.tabPageTests.PerformLayout();
4.45 @@ -273,6 +287,7 @@
4.46 private System.Windows.Forms.TabPage tabPageTests;
4.47 private System.Windows.Forms.TextBox textBoxTests;
4.48 private System.Windows.Forms.Button buttonRefresh;
4.49 + private System.Windows.Forms.CheckBox checkBoxRepeat;
4.50
4.51 }
4.52 }
5.1 --- a/MainForm.cs Sun Mar 15 21:26:51 2015 +0100
5.2 +++ b/MainForm.cs Tue Mar 17 15:35:58 2015 +0100
5.3 @@ -69,6 +69,14 @@
5.4 // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
5.5 // for the vendor defined usage page.
5.6
5.7 + if (iHidHandler!=null)
5.8 + {
5.9 + //First de-register
5.10 + iHidHandler.Dispose();
5.11 + iHidHandler = null;
5.12 + }
5.13 +
5.14 +
5.15 RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[5];
5.16
5.17 int i = 0;
5.18 @@ -114,7 +122,7 @@
5.19 //rid[i].hwndTarget = aHWND;
5.20
5.21
5.22 - iHidHandler = new SharpLib.Hid.Handler(rid);
5.23 + iHidHandler = new SharpLib.Hid.Handler(rid, checkBoxRepeat.Checked);
5.24 if (!iHidHandler.IsRegistered)
5.25 {
5.26 Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
5.27 @@ -182,5 +190,10 @@
5.28 SharpLib.Win32.RawInput.PopulateDeviceList(treeViewDevices);
5.29 }
5.30
5.31 + private void checkBoxRepeat_CheckedChanged(object sender, EventArgs e)
5.32 + {
5.33 + RegisterHidDevices();
5.34 + }
5.35 +
5.36 }
5.37 }
6.1 --- a/Rebracer.xml Sun Mar 15 21:26:51 2015 +0100
6.2 +++ b/Rebracer.xml Tue Mar 17 15:35:58 2015 +0100
6.3 @@ -11,8 +11,8 @@
6.4 <ToolsOptionsSubCategory name="TaskList">
6.5 <PropertyValue name="CommentTokens" ArrayType="VT_VARIANT" ArrayElementCount="4">
6.6 <PropertyValue name="0">TODO:2</PropertyValue>
6.7 - <PropertyValue name="1">HACK:2</PropertyValue>
6.8 - <PropertyValue name="2">UNDONE:2</PropertyValue>
6.9 + <PropertyValue name="1">UNDONE:2</PropertyValue>
6.10 + <PropertyValue name="2">HACK:2</PropertyValue>
6.11 <PropertyValue name="3">UnresolvedMergeConflict:3</PropertyValue>
6.12 </PropertyValue>
6.13 <PropertyValue name="ConfirmTaskDeletion">true</PropertyValue>
6.14 @@ -93,7 +93,7 @@
6.15 <PropertyValue name="FormatCompletedLineOnEnter">true</PropertyValue>
6.16 <PropertyValue name="FormatCompletedStatementOnSemicolon">true</PropertyValue>
6.17 <PropertyValue name="FormatOnPaste">true</PropertyValue>
6.18 - <PropertyValue name="ImplicitReferencesString">Implicit (Windows)|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\libhelp.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\sitetypesWindows.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\domWindows.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\underscorefilter.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\showPlainComments.js;Implicit (Web)|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\libhelp.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\sitetypesWeb.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\domWeb.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\underscorefilter.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\showPlainComments.js|~/Scripts/_references.js;Dedicated Worker|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\libhelp.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\dedicatedworker.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\underscorefilter.js|C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\References\showPlainComments.js;</PropertyValue>
6.19 + <PropertyValue name="ImplicitReferencesString">Implicit (Windows 8)|$(VSInstallDir)\JavaScript\References\libhelp.js|$(VSInstallDir)\JavaScript\References\sitetypesWindows.js|$(VSInstallDir)\JavaScript\References\domWindows_8.0.js|$(VSInstallDir)\JavaScript\References\underscorefilter.js|$(VSInstallDir)\JavaScript\References\showPlainComments.js;Implicit (Windows 8.1)|$(VSInstallDir)\JavaScript\References\libhelp.js|$(VSInstallDir)\JavaScript\References\sitetypesWindows.js|$(VSInstallDir)\JavaScript\References\domWindows_8.1.js|$(VSInstallDir)\JavaScript\References\underscorefilter.js|$(VSInstallDir)\JavaScript\References\showPlainComments.js;Implicit (Windows Phone 8.1)|$(VSInstallDir)\JavaScript\References\libhelp.js|$(VSInstallDir)\JavaScript\References\sitetypesWindows.js|$(VSInstallDir)\JavaScript\References\domWindowsPhone_8.1.js|$(VSInstallDir)\JavaScript\References\underscorefilter.js|$(VSInstallDir)\JavaScript\References\showPlainComments.js;Implicit (Web)|$(VSInstallDir)\JavaScript\References\libhelp.js|$(VSInstallDir)\JavaScript\References\sitetypesWeb.js|$(VSInstallDir)\JavaScript\References\domWeb.js|$(VSInstallDir)\JavaScript\References\underscorefilter.js|$(VSInstallDir)\JavaScript\References\showPlainComments.js|~/Scripts/_references.js;Dedicated Worker|$(VSInstallDir)\JavaScript\References\libhelp.js|$(VSInstallDir)\JavaScript\References\dedicatedworker.js|$(VSInstallDir)\JavaScript\References\underscorefilter.js|$(VSInstallDir)\JavaScript\References\showPlainComments.js;Generic|$(VSInstallDir)\JavaScript\References\libhelp.js|$(VSInstallDir)\JavaScript\References\underscorefilter.js|$(VSInstallDir)\JavaScript\References\showPlainComments.js;</PropertyValue>
6.20 <PropertyValue name="InsertSpaceAfterCommaDelimiter">true</PropertyValue>
6.21 <PropertyValue name="InsertSpaceAfterFunctionKeywordForAnonymousFunctions">true</PropertyValue>
6.22 <PropertyValue name="InsertSpaceAfterKeywordsInControlFlowStatements">true</PropertyValue>
7.1 --- a/SharpLibHid.sln Sun Mar 15 21:26:51 2015 +0100
7.2 +++ b/SharpLibHid.sln Tue Mar 17 15:35:58 2015 +0100
7.3 @@ -1,6 +1,6 @@
7.4
7.5 Microsoft Visual Studio Solution File, Format Version 12.00
7.6 -# Visual Studio 2012
7.7 +# Visual Studio 2013
7.8 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E70B5E73-7045-4EA7-968D-06BB68773DAB}"
7.9 ProjectSection(SolutionItems) = preProject
7.10 Rebracer.xml = Rebracer.xml
8.1 --- a/Win32/Win32RawInput.cs Sun Mar 15 21:26:51 2015 +0100
8.2 +++ b/Win32/Win32RawInput.cs Tue Mar 17 15:35:58 2015 +0100
8.3 @@ -110,7 +110,7 @@
8.4
8.5 /// <summary>
8.6 /// If set, the application command keys are handled. RIDEV_APPKEYS can be specified only if RIDEV_NOLEGACY is specified for a keyboard device.
8.7 - /// </summary>
8.8 + /// </summary>
8.9 public const uint RIDEV_APPKEYS = 0x00000400;
8.10
8.11 /// <summary>