sl@0
|
1 |
using Microsoft.Win32.SafeHandles;
|
sl@0
|
2 |
using System;
|
sl@0
|
3 |
using System.Diagnostics;
|
sl@0
|
4 |
using System.Globalization;
|
sl@0
|
5 |
using System.IO;
|
sl@0
|
6 |
using System.Management;
|
sl@0
|
7 |
using System.Runtime.InteropServices;
|
sl@0
|
8 |
using System.Threading;
|
sl@0
|
9 |
using System.Timers;
|
sl@0
|
10 |
using System.Windows.Forms;
|
sl@3
|
11 |
using System.Collections.Generic;
|
sl@3
|
12 |
using System.Drawing;
|
sl@5
|
13 |
using System.Text.RegularExpressions;
|
sl@0
|
14 |
|
sl@0
|
15 |
namespace GenericHid
|
sl@0
|
16 |
{
|
sl@0
|
17 |
///<summary>
|
sl@0
|
18 |
/// Project: GenericHid
|
sl@2
|
19 |
///
|
sl@0
|
20 |
/// ***********************************************************************
|
sl@0
|
21 |
/// Software License Agreement
|
sl@0
|
22 |
///
|
sl@2
|
23 |
/// Licensor grants any person obtaining a copy of this software ("You")
|
sl@2
|
24 |
/// a worldwide, royalty-free, non-exclusive license, for the duration of
|
sl@2
|
25 |
/// the copyright, free of charge, to store and execute the Software in a
|
sl@2
|
26 |
/// computer system and to incorporate the Software or any portion of it
|
sl@2
|
27 |
/// in computer programs You write.
|
sl@2
|
28 |
///
|
sl@0
|
29 |
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
sl@0
|
30 |
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
sl@0
|
31 |
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
sl@0
|
32 |
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
sl@0
|
33 |
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
sl@0
|
34 |
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
sl@0
|
35 |
/// THE SOFTWARE.
|
sl@0
|
36 |
/// ***********************************************************************
|
sl@2
|
37 |
///
|
sl@2
|
38 |
/// Author
|
sl@2
|
39 |
/// Jan Axelson
|
sl@2
|
40 |
///
|
sl@0
|
41 |
/// This software was written using Visual Studio Express 2012 for Windows
|
sl@0
|
42 |
/// Desktop building for the .NET Framework v4.5.
|
sl@2
|
43 |
///
|
sl@2
|
44 |
/// Purpose:
|
sl@0
|
45 |
/// Demonstrates USB communications with a generic HID-class device
|
sl@2
|
46 |
///
|
sl@0
|
47 |
/// Requirements:
|
sl@0
|
48 |
/// Windows Vista or later and an attached USB generic Human Interface Device (HID).
|
sl@2
|
49 |
/// (Does not run on Windows XP or earlier because .NET Framework 4.5 will not install on these OSes.)
|
sl@2
|
50 |
///
|
sl@0
|
51 |
/// Description:
|
sl@2
|
52 |
/// Finds an attached device that matches the vendor and product IDs in the form's
|
sl@0
|
53 |
/// text boxes.
|
sl@2
|
54 |
///
|
sl@0
|
55 |
/// Retrieves the device's capabilities.
|
sl@0
|
56 |
/// Sends and requests HID reports.
|
sl@2
|
57 |
///
|
sl@2
|
58 |
/// Uses the System.Management class and Windows Management Instrumentation (WMI) to detect
|
sl@0
|
59 |
/// when a device is attached or removed.
|
sl@2
|
60 |
///
|
sl@0
|
61 |
/// A list box displays the data sent and received along with error and status messages.
|
sl@0
|
62 |
/// You can select data to send and 1-time or periodic transfers.
|
sl@2
|
63 |
///
|
sl@0
|
64 |
/// You can change the size of the host's Input report buffer and request to use control
|
sl@0
|
65 |
/// transfers only to exchange Input and Output reports.
|
sl@2
|
66 |
///
|
sl@0
|
67 |
/// To view additional debugging messages, in the Visual Studio development environment,
|
sl@2
|
68 |
/// from the main menu, select Build > Configuration Manager > Active Solution Configuration
|
sl@0
|
69 |
/// and select Configuration > Debug and from the main menu, select View > Output.
|
sl@2
|
70 |
///
|
sl@2
|
71 |
/// The application uses asynchronous FileStreams to read Input reports and write Output
|
sl@2
|
72 |
/// reports so the application's main thread doesn't have to wait for the device to retrieve a
|
sl@2
|
73 |
/// report when the HID driver's buffer is empty or send a report when the device's endpoint is busy.
|
sl@2
|
74 |
///
|
sl@0
|
75 |
/// For code that finds a device and opens handles to it, see the FindTheHid routine in frmMain.cs.
|
sl@2
|
76 |
/// For code that reads from the device, see GetInputReportViaInterruptTransfer,
|
sl@0
|
77 |
/// GetInputReportViaControlTransfer, and GetFeatureReport in Hid.cs.
|
sl@2
|
78 |
/// For code that writes to the device, see SendInputReportViaInterruptTransfer,
|
sl@0
|
79 |
/// SendInputReportViaControlTransfer, and SendFeatureReport in Hid.cs.
|
sl@2
|
80 |
///
|
sl@0
|
81 |
/// This project includes the following modules:
|
sl@2
|
82 |
///
|
sl@0
|
83 |
/// GenericHid.cs - runs the application.
|
sl@0
|
84 |
/// FrmMain.cs - routines specific to the form.
|
sl@0
|
85 |
/// Hid.cs - routines specific to HID communications.
|
sl@0
|
86 |
/// DeviceManagement.cs - routine for obtaining a handle to a device from its GUID.
|
sl@0
|
87 |
/// Debugging.cs - contains a routine for displaying API error messages.
|
sl@0
|
88 |
/// HidDeclarations.cs - Declarations for API functions used by Hid.cs.
|
sl@0
|
89 |
/// FileIODeclarations.cs - Declarations for file-related API functions.
|
sl@0
|
90 |
/// DeviceManagementDeclarations.cs - Declarations for API functions used by DeviceManagement.cs.
|
sl@0
|
91 |
/// DebuggingDeclarations.cs - Declarations for API functions used by Debugging.cs.
|
sl@2
|
92 |
///
|
sl@0
|
93 |
/// Companion device firmware for several device CPUs is available from www.Lvr.com/hidpage.htm
|
sl@0
|
94 |
/// You can use any generic HID (not a system mouse or keyboard) that sends and receives reports.
|
sl@0
|
95 |
/// This application will not detect or communicate with non-HID-class devices.
|
sl@2
|
96 |
///
|
sl@0
|
97 |
/// For more information about HIDs and USB, and additional example device firmware to use
|
sl@2
|
98 |
/// with this application, visit Lakeview Research at http://Lvr.com
|
sl@2
|
99 |
/// Send comments, bug reports, etc. to jan@Lvr.com or post on my PORTS forum: http://www.lvr.com/forum
|
sl@2
|
100 |
///
|
sl@0
|
101 |
/// V6.2
|
sl@0
|
102 |
/// 11/12/13
|
sl@0
|
103 |
/// Disabled form buttons when a transfer is in progress.
|
sl@0
|
104 |
/// Other minor edits for clarity and readability.
|
sl@0
|
105 |
/// Will NOT run on Windows XP or earlier, see below.
|
sl@2
|
106 |
///
|
sl@0
|
107 |
/// V6.1
|
sl@0
|
108 |
/// 10/28/13
|
sl@0
|
109 |
/// Uses the .NET System.Management class to detect device arrival and removal with WMI instead of Win32 RegisterDeviceNotification.
|
sl@0
|
110 |
/// Other minor edits.
|
sl@0
|
111 |
/// Will NOT run on Windows XP or earlier, see below.
|
sl@2
|
112 |
///
|
sl@0
|
113 |
/// V6.0
|
sl@0
|
114 |
/// 2/8/13
|
sl@0
|
115 |
/// This version will NOT run on Windows XP or earlier because the code uses .NET Framework 4.5 to support asynchronous FileStreams.
|
sl@2
|
116 |
/// The .NET Framework 4.5 redistributable is compatible with Windows 8, Windows 7 SP1, Windows Server 2008 R2 SP1,
|
sl@0
|
117 |
/// Windows Server 2008 SP2, Windows Vista SP2, and Windows Vista SP3.
|
sl@0
|
118 |
/// For compatibility, replaced ToInt32 with ToInt64 here:
|
sl@0
|
119 |
/// IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4);
|
sl@0
|
120 |
/// and here:
|
sl@0
|
121 |
/// if ((deviceNotificationHandle.ToInt64() == IntPtr.Zero.ToInt64()))
|
sl@0
|
122 |
/// For compatibility if the charset isn't English, added System.Globalization.CultureInfo.InvariantCulture here:
|
sl@0
|
123 |
/// if ((String.Compare(DeviceNameString, mydevicePathName, true, System.Globalization.CultureInfo.InvariantCulture) == 0))
|
sl@0
|
124 |
/// Replaced all Microsoft.VisualBasic namespace code with other .NET equivalents.
|
sl@0
|
125 |
/// Revised user interface for more flexibility.
|
sl@0
|
126 |
/// Moved interrupt-transfer and other HID-specific code to Hid.cs.
|
sl@0
|
127 |
/// Used JetBrains ReSharper to clean up the code: http://www.jetbrains.com/resharper/
|
sl@2
|
128 |
///
|
sl@0
|
129 |
/// V5.0
|
sl@0
|
130 |
/// 3/30/11
|
sl@0
|
131 |
/// Replaced ReadFile and WriteFile with FileStreams. Thanks to Joe Dunne and John on my Ports forum for tips on this.
|
sl@0
|
132 |
/// Simplified Hid.cs.
|
sl@0
|
133 |
/// Replaced the form timer with a system timer.
|
sl@2
|
134 |
///
|
sl@0
|
135 |
/// V4.6
|
sl@0
|
136 |
/// 1/12/10
|
sl@0
|
137 |
/// Supports Vendor IDs and Product IDs up to FFFFh.
|
sl@0
|
138 |
///
|
sl@0
|
139 |
/// V4.52
|
sl@0
|
140 |
/// 11/10/09
|
sl@0
|
141 |
/// Changed HIDD_ATTRIBUTES to use UInt16
|
sl@2
|
142 |
///
|
sl@0
|
143 |
/// V4.51
|
sl@0
|
144 |
/// 2/11/09
|
sl@0
|
145 |
/// Moved Free_ and similar to Finally blocks to ensure they execute.
|
sl@2
|
146 |
///
|
sl@0
|
147 |
/// V4.5
|
sl@0
|
148 |
/// 2/9/09
|
sl@2
|
149 |
/// Changes to support 64-bit systems, memory management, and other corrections.
|
sl@0
|
150 |
/// Big thanks to Peter Nielsen.
|
sl@2
|
151 |
///
|
sl@0
|
152 |
/// </summary>
|
sl@0
|
153 |
|
sl@0
|
154 |
internal class FrmMain
|
sl@0
|
155 |
: Form
|
sl@0
|
156 |
{
|
sl@0
|
157 |
#region '"Windows Form Designer generated code "'
|
sl@0
|
158 |
public FrmMain()
|
sl@0
|
159 |
//: base()
|
sl@0
|
160 |
{
|
sl@0
|
161 |
// This call is required by the Windows Form Designer.
|
sl@0
|
162 |
InitializeComponent();
|
sl@0
|
163 |
}
|
sl@0
|
164 |
// Form overrides dispose to clean up the component list.
|
sl@0
|
165 |
protected override void Dispose(bool Disposing1)
|
sl@0
|
166 |
{
|
sl@0
|
167 |
if (Disposing1)
|
sl@0
|
168 |
{
|
sl@0
|
169 |
if (components != null)
|
sl@0
|
170 |
{
|
sl@0
|
171 |
components.Dispose();
|
sl@0
|
172 |
}
|
sl@0
|
173 |
}
|
sl@0
|
174 |
base.Dispose(Disposing1);
|
sl@0
|
175 |
}
|
sl@0
|
176 |
|
sl@0
|
177 |
// Required by the Windows Form Designer
|
sl@0
|
178 |
private System.ComponentModel.IContainer components;
|
sl@0
|
179 |
public System.Windows.Forms.ToolTip ToolTip1;
|
sl@0
|
180 |
public System.Windows.Forms.TextBox TxtBytesReceived;
|
sl@0
|
181 |
public System.Windows.Forms.GroupBox FraBytesReceived;
|
sl@0
|
182 |
public System.Windows.Forms.CheckBox ChkAutoincrement;
|
sl@0
|
183 |
public System.Windows.Forms.ComboBox CboByte1;
|
sl@0
|
184 |
public System.Windows.Forms.ComboBox CboByte0;
|
sl@0
|
185 |
public System.Windows.Forms.GroupBox FraBytesToSend;
|
sl@0
|
186 |
public System.Windows.Forms.ListBox LstResults;
|
sl@0
|
187 |
// NOTE: The following procedure is required by the Windows Form Designer
|
sl@0
|
188 |
// It can be modified using the Windows Form Designer.
|
sl@2
|
189 |
// Do not modify it using the code editor.
|
sl@0
|
190 |
internal System.Windows.Forms.GroupBox fraInputReportBufferSize;
|
sl@0
|
191 |
internal System.Windows.Forms.TextBox txtInputReportBufferSize;
|
sl@0
|
192 |
internal System.Windows.Forms.Button cmdInputReportBufferSize;
|
sl@0
|
193 |
internal System.Windows.Forms.GroupBox fraDeviceIdentifiers;
|
sl@0
|
194 |
internal System.Windows.Forms.Label lblVendorID;
|
sl@0
|
195 |
internal System.Windows.Forms.TextBox txtVendorID;
|
sl@0
|
196 |
internal System.Windows.Forms.Label lblProductID;
|
sl@0
|
197 |
internal System.Windows.Forms.TextBox txtProductID;
|
sl@0
|
198 |
internal System.Windows.Forms.Button cmdFindDevice;
|
sl@0
|
199 |
private Button cmdGetInputReportInterrupt;
|
sl@0
|
200 |
public GroupBox fraInterruptTransfers;
|
sl@0
|
201 |
private Button cmdSendOutputReportControl;
|
sl@0
|
202 |
private Button cmdGetInputReportControl;
|
sl@0
|
203 |
public GroupBox fraControlTransfers;
|
sl@0
|
204 |
private Button cmdGetFeatureReport;
|
sl@0
|
205 |
private Button cmdSendFeatureReport;
|
sl@0
|
206 |
private Button cmdPeriodicTransfers;
|
sl@0
|
207 |
public GroupBox fraSendAndGetContinuous;
|
sl@0
|
208 |
private RadioButton radFeature;
|
sl@0
|
209 |
private RadioButton radInputOutputControl;
|
sl@0
|
210 |
private RadioButton radInputOutputInterrupt;
|
sl@3
|
211 |
private TreeView treeViewDevices;
|
sl@0
|
212 |
private Button cmdSendOutputReportInterrupt;
|
sl@0
|
213 |
|
sl@0
|
214 |
[System.Diagnostics.DebuggerStepThrough()]
|
sl@0
|
215 |
private void InitializeComponent()
|
sl@0
|
216 |
{
|
sl@3
|
217 |
this.components = new System.ComponentModel.Container();
|
sl@3
|
218 |
this.ToolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
sl@3
|
219 |
this.FraBytesReceived = new System.Windows.Forms.GroupBox();
|
sl@3
|
220 |
this.TxtBytesReceived = new System.Windows.Forms.TextBox();
|
sl@3
|
221 |
this.FraBytesToSend = new System.Windows.Forms.GroupBox();
|
sl@3
|
222 |
this.ChkAutoincrement = new System.Windows.Forms.CheckBox();
|
sl@3
|
223 |
this.CboByte1 = new System.Windows.Forms.ComboBox();
|
sl@3
|
224 |
this.CboByte0 = new System.Windows.Forms.ComboBox();
|
sl@3
|
225 |
this.LstResults = new System.Windows.Forms.ListBox();
|
sl@3
|
226 |
this.fraInputReportBufferSize = new System.Windows.Forms.GroupBox();
|
sl@3
|
227 |
this.cmdInputReportBufferSize = new System.Windows.Forms.Button();
|
sl@3
|
228 |
this.txtInputReportBufferSize = new System.Windows.Forms.TextBox();
|
sl@3
|
229 |
this.fraDeviceIdentifiers = new System.Windows.Forms.GroupBox();
|
sl@3
|
230 |
this.txtProductID = new System.Windows.Forms.TextBox();
|
sl@3
|
231 |
this.lblProductID = new System.Windows.Forms.Label();
|
sl@3
|
232 |
this.txtVendorID = new System.Windows.Forms.TextBox();
|
sl@3
|
233 |
this.lblVendorID = new System.Windows.Forms.Label();
|
sl@3
|
234 |
this.cmdFindDevice = new System.Windows.Forms.Button();
|
sl@3
|
235 |
this.cmdSendOutputReportInterrupt = new System.Windows.Forms.Button();
|
sl@3
|
236 |
this.cmdGetInputReportInterrupt = new System.Windows.Forms.Button();
|
sl@3
|
237 |
this.fraInterruptTransfers = new System.Windows.Forms.GroupBox();
|
sl@3
|
238 |
this.cmdPeriodicTransfers = new System.Windows.Forms.Button();
|
sl@3
|
239 |
this.cmdSendOutputReportControl = new System.Windows.Forms.Button();
|
sl@3
|
240 |
this.cmdGetInputReportControl = new System.Windows.Forms.Button();
|
sl@3
|
241 |
this.fraControlTransfers = new System.Windows.Forms.GroupBox();
|
sl@3
|
242 |
this.cmdGetFeatureReport = new System.Windows.Forms.Button();
|
sl@3
|
243 |
this.cmdSendFeatureReport = new System.Windows.Forms.Button();
|
sl@3
|
244 |
this.fraSendAndGetContinuous = new System.Windows.Forms.GroupBox();
|
sl@3
|
245 |
this.radFeature = new System.Windows.Forms.RadioButton();
|
sl@3
|
246 |
this.radInputOutputControl = new System.Windows.Forms.RadioButton();
|
sl@3
|
247 |
this.radInputOutputInterrupt = new System.Windows.Forms.RadioButton();
|
sl@3
|
248 |
this.treeViewDevices = new System.Windows.Forms.TreeView();
|
sl@3
|
249 |
this.FraBytesReceived.SuspendLayout();
|
sl@3
|
250 |
this.FraBytesToSend.SuspendLayout();
|
sl@3
|
251 |
this.fraInputReportBufferSize.SuspendLayout();
|
sl@3
|
252 |
this.fraDeviceIdentifiers.SuspendLayout();
|
sl@3
|
253 |
this.fraInterruptTransfers.SuspendLayout();
|
sl@3
|
254 |
this.fraControlTransfers.SuspendLayout();
|
sl@3
|
255 |
this.fraSendAndGetContinuous.SuspendLayout();
|
sl@3
|
256 |
this.SuspendLayout();
|
sl@3
|
257 |
//
|
sl@3
|
258 |
// FraBytesReceived
|
sl@3
|
259 |
//
|
sl@3
|
260 |
this.FraBytesReceived.BackColor = System.Drawing.SystemColors.Control;
|
sl@3
|
261 |
this.FraBytesReceived.Controls.Add(this.TxtBytesReceived);
|
sl@3
|
262 |
this.FraBytesReceived.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
263 |
this.FraBytesReceived.ForeColor = System.Drawing.SystemColors.ControlText;
|
sl@3
|
264 |
this.FraBytesReceived.Location = new System.Drawing.Point(495, 353);
|
sl@3
|
265 |
this.FraBytesReceived.Name = "FraBytesReceived";
|
sl@3
|
266 |
this.FraBytesReceived.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
267 |
this.FraBytesReceived.Size = new System.Drawing.Size(112, 136);
|
sl@3
|
268 |
this.FraBytesReceived.TabIndex = 4;
|
sl@3
|
269 |
this.FraBytesReceived.TabStop = false;
|
sl@3
|
270 |
this.FraBytesReceived.Text = "Bytes Received";
|
sl@3
|
271 |
//
|
sl@3
|
272 |
// TxtBytesReceived
|
sl@3
|
273 |
//
|
sl@3
|
274 |
this.TxtBytesReceived.AcceptsReturn = true;
|
sl@3
|
275 |
this.TxtBytesReceived.BackColor = System.Drawing.SystemColors.Window;
|
sl@3
|
276 |
this.TxtBytesReceived.Cursor = System.Windows.Forms.Cursors.IBeam;
|
sl@3
|
277 |
this.TxtBytesReceived.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
278 |
this.TxtBytesReceived.ForeColor = System.Drawing.SystemColors.WindowText;
|
sl@3
|
279 |
this.TxtBytesReceived.Location = new System.Drawing.Point(18, 24);
|
sl@3
|
280 |
this.TxtBytesReceived.MaxLength = 0;
|
sl@3
|
281 |
this.TxtBytesReceived.Multiline = true;
|
sl@3
|
282 |
this.TxtBytesReceived.Name = "TxtBytesReceived";
|
sl@3
|
283 |
this.TxtBytesReceived.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
284 |
this.TxtBytesReceived.Size = new System.Drawing.Size(72, 96);
|
sl@3
|
285 |
this.TxtBytesReceived.TabIndex = 5;
|
sl@3
|
286 |
//
|
sl@3
|
287 |
// FraBytesToSend
|
sl@3
|
288 |
//
|
sl@3
|
289 |
this.FraBytesToSend.BackColor = System.Drawing.SystemColors.Control;
|
sl@3
|
290 |
this.FraBytesToSend.Controls.Add(this.ChkAutoincrement);
|
sl@3
|
291 |
this.FraBytesToSend.Controls.Add(this.CboByte1);
|
sl@3
|
292 |
this.FraBytesToSend.Controls.Add(this.CboByte0);
|
sl@3
|
293 |
this.FraBytesToSend.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
294 |
this.FraBytesToSend.ForeColor = System.Drawing.SystemColors.ControlText;
|
sl@3
|
295 |
this.FraBytesToSend.Location = new System.Drawing.Point(612, 235);
|
sl@3
|
296 |
this.FraBytesToSend.Name = "FraBytesToSend";
|
sl@3
|
297 |
this.FraBytesToSend.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
298 |
this.FraBytesToSend.Size = new System.Drawing.Size(160, 136);
|
sl@3
|
299 |
this.FraBytesToSend.TabIndex = 1;
|
sl@3
|
300 |
this.FraBytesToSend.TabStop = false;
|
sl@3
|
301 |
this.FraBytesToSend.Text = "Bytes to Send";
|
sl@3
|
302 |
//
|
sl@3
|
303 |
// ChkAutoincrement
|
sl@3
|
304 |
//
|
sl@3
|
305 |
this.ChkAutoincrement.BackColor = System.Drawing.SystemColors.Control;
|
sl@3
|
306 |
this.ChkAutoincrement.Cursor = System.Windows.Forms.Cursors.Default;
|
sl@3
|
307 |
this.ChkAutoincrement.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
308 |
this.ChkAutoincrement.ForeColor = System.Drawing.SystemColors.ControlText;
|
sl@3
|
309 |
this.ChkAutoincrement.Location = new System.Drawing.Point(8, 96);
|
sl@3
|
310 |
this.ChkAutoincrement.Name = "ChkAutoincrement";
|
sl@3
|
311 |
this.ChkAutoincrement.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
312 |
this.ChkAutoincrement.Size = new System.Drawing.Size(201, 35);
|
sl@3
|
313 |
this.ChkAutoincrement.TabIndex = 6;
|
sl@3
|
314 |
this.ChkAutoincrement.Text = "Autoincrement values";
|
sl@3
|
315 |
this.ChkAutoincrement.UseVisualStyleBackColor = false;
|
sl@3
|
316 |
//
|
sl@3
|
317 |
// CboByte1
|
sl@3
|
318 |
//
|
sl@3
|
319 |
this.CboByte1.BackColor = System.Drawing.SystemColors.Window;
|
sl@3
|
320 |
this.CboByte1.Cursor = System.Windows.Forms.Cursors.Default;
|
sl@3
|
321 |
this.CboByte1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
sl@3
|
322 |
this.CboByte1.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
323 |
this.CboByte1.ForeColor = System.Drawing.SystemColors.WindowText;
|
sl@3
|
324 |
this.CboByte1.Location = new System.Drawing.Point(8, 64);
|
sl@3
|
325 |
this.CboByte1.Name = "CboByte1";
|
sl@3
|
326 |
this.CboByte1.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
327 |
this.CboByte1.Size = new System.Drawing.Size(101, 22);
|
sl@3
|
328 |
this.CboByte1.TabIndex = 3;
|
sl@3
|
329 |
//
|
sl@3
|
330 |
// CboByte0
|
sl@3
|
331 |
//
|
sl@3
|
332 |
this.CboByte0.BackColor = System.Drawing.SystemColors.Window;
|
sl@3
|
333 |
this.CboByte0.Cursor = System.Windows.Forms.Cursors.Default;
|
sl@3
|
334 |
this.CboByte0.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
sl@3
|
335 |
this.CboByte0.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
336 |
this.CboByte0.ForeColor = System.Drawing.SystemColors.WindowText;
|
sl@3
|
337 |
this.CboByte0.Location = new System.Drawing.Point(8, 24);
|
sl@3
|
338 |
this.CboByte0.Name = "CboByte0";
|
sl@3
|
339 |
this.CboByte0.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
340 |
this.CboByte0.Size = new System.Drawing.Size(101, 22);
|
sl@3
|
341 |
this.CboByte0.TabIndex = 2;
|
sl@3
|
342 |
//
|
sl@3
|
343 |
// LstResults
|
sl@3
|
344 |
//
|
sl@3
|
345 |
this.LstResults.BackColor = System.Drawing.SystemColors.Window;
|
sl@3
|
346 |
this.LstResults.Cursor = System.Windows.Forms.Cursors.Default;
|
sl@3
|
347 |
this.LstResults.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
348 |
this.LstResults.ForeColor = System.Drawing.SystemColors.WindowText;
|
sl@3
|
349 |
this.LstResults.HorizontalScrollbar = true;
|
sl@3
|
350 |
this.LstResults.ItemHeight = 14;
|
sl@3
|
351 |
this.LstResults.Location = new System.Drawing.Point(12, 494);
|
sl@3
|
352 |
this.LstResults.Name = "LstResults";
|
sl@3
|
353 |
this.LstResults.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
354 |
this.LstResults.Size = new System.Drawing.Size(760, 256);
|
sl@3
|
355 |
this.LstResults.TabIndex = 0;
|
sl@3
|
356 |
//
|
sl@3
|
357 |
// fraInputReportBufferSize
|
sl@3
|
358 |
//
|
sl@3
|
359 |
this.fraInputReportBufferSize.Controls.Add(this.cmdInputReportBufferSize);
|
sl@3
|
360 |
this.fraInputReportBufferSize.Controls.Add(this.txtInputReportBufferSize);
|
sl@3
|
361 |
this.fraInputReportBufferSize.Location = new System.Drawing.Point(623, 44);
|
sl@3
|
362 |
this.fraInputReportBufferSize.Name = "fraInputReportBufferSize";
|
sl@3
|
363 |
this.fraInputReportBufferSize.Size = new System.Drawing.Size(149, 79);
|
sl@3
|
364 |
this.fraInputReportBufferSize.TabIndex = 9;
|
sl@3
|
365 |
this.fraInputReportBufferSize.TabStop = false;
|
sl@3
|
366 |
this.fraInputReportBufferSize.Text = "Input Report Buffer Size";
|
sl@3
|
367 |
//
|
sl@3
|
368 |
// cmdInputReportBufferSize
|
sl@3
|
369 |
//
|
sl@3
|
370 |
this.cmdInputReportBufferSize.Location = new System.Drawing.Point(6, 47);
|
sl@3
|
371 |
this.cmdInputReportBufferSize.Name = "cmdInputReportBufferSize";
|
sl@3
|
372 |
this.cmdInputReportBufferSize.Size = new System.Drawing.Size(136, 26);
|
sl@3
|
373 |
this.cmdInputReportBufferSize.TabIndex = 1;
|
sl@3
|
374 |
this.cmdInputReportBufferSize.Text = "Change Buffer Size";
|
sl@3
|
375 |
this.cmdInputReportBufferSize.Click += new System.EventHandler(this.cmdInputReportBufferSize_Click);
|
sl@3
|
376 |
//
|
sl@3
|
377 |
// txtInputReportBufferSize
|
sl@3
|
378 |
//
|
sl@3
|
379 |
this.txtInputReportBufferSize.Location = new System.Drawing.Point(6, 21);
|
sl@3
|
380 |
this.txtInputReportBufferSize.Name = "txtInputReportBufferSize";
|
sl@3
|
381 |
this.txtInputReportBufferSize.Size = new System.Drawing.Size(56, 20);
|
sl@3
|
382 |
this.txtInputReportBufferSize.TabIndex = 0;
|
sl@3
|
383 |
//
|
sl@3
|
384 |
// fraDeviceIdentifiers
|
sl@3
|
385 |
//
|
sl@3
|
386 |
this.fraDeviceIdentifiers.Controls.Add(this.txtProductID);
|
sl@3
|
387 |
this.fraDeviceIdentifiers.Controls.Add(this.lblProductID);
|
sl@3
|
388 |
this.fraDeviceIdentifiers.Controls.Add(this.txtVendorID);
|
sl@3
|
389 |
this.fraDeviceIdentifiers.Controls.Add(this.lblVendorID);
|
sl@3
|
390 |
this.fraDeviceIdentifiers.Location = new System.Drawing.Point(409, 12);
|
sl@3
|
391 |
this.fraDeviceIdentifiers.Name = "fraDeviceIdentifiers";
|
sl@3
|
392 |
this.fraDeviceIdentifiers.Size = new System.Drawing.Size(208, 96);
|
sl@3
|
393 |
this.fraDeviceIdentifiers.TabIndex = 10;
|
sl@3
|
394 |
this.fraDeviceIdentifiers.TabStop = false;
|
sl@3
|
395 |
this.fraDeviceIdentifiers.Text = "Device Identifiers";
|
sl@3
|
396 |
//
|
sl@3
|
397 |
// txtProductID
|
sl@3
|
398 |
//
|
sl@3
|
399 |
this.txtProductID.Location = new System.Drawing.Point(120, 56);
|
sl@3
|
400 |
this.txtProductID.Name = "txtProductID";
|
sl@3
|
401 |
this.txtProductID.Size = new System.Drawing.Size(72, 20);
|
sl@3
|
402 |
this.txtProductID.TabIndex = 3;
|
sl@3
|
403 |
this.txtProductID.Text = "1299";
|
sl@3
|
404 |
this.txtProductID.TextChanged += new System.EventHandler(this.txtProductID_TextChanged);
|
sl@3
|
405 |
//
|
sl@3
|
406 |
// lblProductID
|
sl@3
|
407 |
//
|
sl@3
|
408 |
this.lblProductID.Location = new System.Drawing.Point(16, 56);
|
sl@3
|
409 |
this.lblProductID.Name = "lblProductID";
|
sl@3
|
410 |
this.lblProductID.Size = new System.Drawing.Size(112, 23);
|
sl@3
|
411 |
this.lblProductID.TabIndex = 2;
|
sl@3
|
412 |
this.lblProductID.Text = "Product ID (hex):";
|
sl@3
|
413 |
//
|
sl@3
|
414 |
// txtVendorID
|
sl@3
|
415 |
//
|
sl@3
|
416 |
this.txtVendorID.Location = new System.Drawing.Point(120, 24);
|
sl@3
|
417 |
this.txtVendorID.Name = "txtVendorID";
|
sl@3
|
418 |
this.txtVendorID.Size = new System.Drawing.Size(72, 20);
|
sl@3
|
419 |
this.txtVendorID.TabIndex = 1;
|
sl@3
|
420 |
this.txtVendorID.Text = "0925";
|
sl@3
|
421 |
this.txtVendorID.TextChanged += new System.EventHandler(this.txtVendorID_TextChanged);
|
sl@3
|
422 |
//
|
sl@3
|
423 |
// lblVendorID
|
sl@3
|
424 |
//
|
sl@3
|
425 |
this.lblVendorID.Location = new System.Drawing.Point(16, 24);
|
sl@3
|
426 |
this.lblVendorID.Name = "lblVendorID";
|
sl@3
|
427 |
this.lblVendorID.Size = new System.Drawing.Size(112, 23);
|
sl@3
|
428 |
this.lblVendorID.TabIndex = 0;
|
sl@3
|
429 |
this.lblVendorID.Text = "Vendor ID (hex):";
|
sl@3
|
430 |
//
|
sl@3
|
431 |
// cmdFindDevice
|
sl@3
|
432 |
//
|
sl@3
|
433 |
this.cmdFindDevice.Location = new System.Drawing.Point(636, 12);
|
sl@3
|
434 |
this.cmdFindDevice.Name = "cmdFindDevice";
|
sl@3
|
435 |
this.cmdFindDevice.Size = new System.Drawing.Size(136, 26);
|
sl@3
|
436 |
this.cmdFindDevice.TabIndex = 11;
|
sl@3
|
437 |
this.cmdFindDevice.Text = "Find My Device";
|
sl@3
|
438 |
this.cmdFindDevice.Click += new System.EventHandler(this.cmdFindDevice_Click);
|
sl@3
|
439 |
//
|
sl@3
|
440 |
// cmdSendOutputReportInterrupt
|
sl@3
|
441 |
//
|
sl@3
|
442 |
this.cmdSendOutputReportInterrupt.Location = new System.Drawing.Point(21, 27);
|
sl@3
|
443 |
this.cmdSendOutputReportInterrupt.Name = "cmdSendOutputReportInterrupt";
|
sl@3
|
444 |
this.cmdSendOutputReportInterrupt.Size = new System.Drawing.Size(118, 26);
|
sl@3
|
445 |
this.cmdSendOutputReportInterrupt.TabIndex = 12;
|
sl@3
|
446 |
this.cmdSendOutputReportInterrupt.Text = "Send Output Report";
|
sl@3
|
447 |
this.cmdSendOutputReportInterrupt.UseVisualStyleBackColor = true;
|
sl@3
|
448 |
this.cmdSendOutputReportInterrupt.Click += new System.EventHandler(this.cmdSendOutputReportInterrupt_Click);
|
sl@3
|
449 |
//
|
sl@3
|
450 |
// cmdGetInputReportInterrupt
|
sl@3
|
451 |
//
|
sl@3
|
452 |
this.cmdGetInputReportInterrupt.Location = new System.Drawing.Point(21, 60);
|
sl@3
|
453 |
this.cmdGetInputReportInterrupt.Name = "cmdGetInputReportInterrupt";
|
sl@3
|
454 |
this.cmdGetInputReportInterrupt.Size = new System.Drawing.Size(118, 26);
|
sl@3
|
455 |
this.cmdGetInputReportInterrupt.TabIndex = 13;
|
sl@3
|
456 |
this.cmdGetInputReportInterrupt.Text = "Get Input Report";
|
sl@3
|
457 |
this.cmdGetInputReportInterrupt.UseVisualStyleBackColor = true;
|
sl@3
|
458 |
this.cmdGetInputReportInterrupt.Click += new System.EventHandler(this.cmdGetInputReportInterrupt_Click);
|
sl@3
|
459 |
//
|
sl@3
|
460 |
// fraInterruptTransfers
|
sl@3
|
461 |
//
|
sl@3
|
462 |
this.fraInterruptTransfers.BackColor = System.Drawing.SystemColors.Control;
|
sl@3
|
463 |
this.fraInterruptTransfers.Controls.Add(this.cmdSendOutputReportInterrupt);
|
sl@3
|
464 |
this.fraInterruptTransfers.Controls.Add(this.cmdGetInputReportInterrupt);
|
sl@3
|
465 |
this.fraInterruptTransfers.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
466 |
this.fraInterruptTransfers.ForeColor = System.Drawing.SystemColors.ControlText;
|
sl@3
|
467 |
this.fraInterruptTransfers.Location = new System.Drawing.Point(338, 129);
|
sl@3
|
468 |
this.fraInterruptTransfers.Name = "fraInterruptTransfers";
|
sl@3
|
469 |
this.fraInterruptTransfers.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
470 |
this.fraInterruptTransfers.Size = new System.Drawing.Size(151, 100);
|
sl@3
|
471 |
this.fraInterruptTransfers.TabIndex = 14;
|
sl@3
|
472 |
this.fraInterruptTransfers.TabStop = false;
|
sl@3
|
473 |
this.fraInterruptTransfers.Text = "Interrupt Transfers";
|
sl@3
|
474 |
//
|
sl@3
|
475 |
// cmdPeriodicTransfers
|
sl@3
|
476 |
//
|
sl@3
|
477 |
this.cmdPeriodicTransfers.Location = new System.Drawing.Point(153, 36);
|
sl@3
|
478 |
this.cmdPeriodicTransfers.Name = "cmdPeriodicTransfers";
|
sl@3
|
479 |
this.cmdPeriodicTransfers.Size = new System.Drawing.Size(118, 26);
|
sl@3
|
480 |
this.cmdPeriodicTransfers.TabIndex = 16;
|
sl@3
|
481 |
this.cmdPeriodicTransfers.Text = "Start";
|
sl@3
|
482 |
this.cmdPeriodicTransfers.UseVisualStyleBackColor = true;
|
sl@3
|
483 |
this.cmdPeriodicTransfers.Click += new System.EventHandler(this.cmdPeriodicTransfers_Click);
|
sl@3
|
484 |
//
|
sl@3
|
485 |
// cmdSendOutputReportControl
|
sl@3
|
486 |
//
|
sl@3
|
487 |
this.cmdSendOutputReportControl.Location = new System.Drawing.Point(10, 27);
|
sl@3
|
488 |
this.cmdSendOutputReportControl.Name = "cmdSendOutputReportControl";
|
sl@3
|
489 |
this.cmdSendOutputReportControl.Size = new System.Drawing.Size(118, 26);
|
sl@3
|
490 |
this.cmdSendOutputReportControl.TabIndex = 12;
|
sl@3
|
491 |
this.cmdSendOutputReportControl.Text = "Send Output Report";
|
sl@3
|
492 |
this.cmdSendOutputReportControl.UseVisualStyleBackColor = true;
|
sl@3
|
493 |
this.cmdSendOutputReportControl.Click += new System.EventHandler(this.cmdSendOutputReportControl_Click);
|
sl@3
|
494 |
//
|
sl@3
|
495 |
// cmdGetInputReportControl
|
sl@3
|
496 |
//
|
sl@3
|
497 |
this.cmdGetInputReportControl.Location = new System.Drawing.Point(10, 60);
|
sl@3
|
498 |
this.cmdGetInputReportControl.Name = "cmdGetInputReportControl";
|
sl@3
|
499 |
this.cmdGetInputReportControl.Size = new System.Drawing.Size(118, 26);
|
sl@3
|
500 |
this.cmdGetInputReportControl.TabIndex = 13;
|
sl@3
|
501 |
this.cmdGetInputReportControl.Text = "Get Input Report";
|
sl@3
|
502 |
this.cmdGetInputReportControl.UseVisualStyleBackColor = true;
|
sl@3
|
503 |
this.cmdGetInputReportControl.Click += new System.EventHandler(this.cmdGetInputReportControl_Click);
|
sl@3
|
504 |
//
|
sl@3
|
505 |
// fraControlTransfers
|
sl@3
|
506 |
//
|
sl@3
|
507 |
this.fraControlTransfers.BackColor = System.Drawing.SystemColors.Control;
|
sl@3
|
508 |
this.fraControlTransfers.Controls.Add(this.cmdGetFeatureReport);
|
sl@3
|
509 |
this.fraControlTransfers.Controls.Add(this.cmdSendFeatureReport);
|
sl@3
|
510 |
this.fraControlTransfers.Controls.Add(this.cmdSendOutputReportControl);
|
sl@3
|
511 |
this.fraControlTransfers.Controls.Add(this.cmdGetInputReportControl);
|
sl@3
|
512 |
this.fraControlTransfers.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
513 |
this.fraControlTransfers.ForeColor = System.Drawing.SystemColors.ControlText;
|
sl@3
|
514 |
this.fraControlTransfers.Location = new System.Drawing.Point(495, 129);
|
sl@3
|
515 |
this.fraControlTransfers.Name = "fraControlTransfers";
|
sl@3
|
516 |
this.fraControlTransfers.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
517 |
this.fraControlTransfers.Size = new System.Drawing.Size(277, 100);
|
sl@3
|
518 |
this.fraControlTransfers.TabIndex = 15;
|
sl@3
|
519 |
this.fraControlTransfers.TabStop = false;
|
sl@3
|
520 |
this.fraControlTransfers.Text = "Control Transfers";
|
sl@3
|
521 |
//
|
sl@3
|
522 |
// cmdGetFeatureReport
|
sl@3
|
523 |
//
|
sl@3
|
524 |
this.cmdGetFeatureReport.Location = new System.Drawing.Point(141, 60);
|
sl@3
|
525 |
this.cmdGetFeatureReport.Name = "cmdGetFeatureReport";
|
sl@3
|
526 |
this.cmdGetFeatureReport.Size = new System.Drawing.Size(118, 26);
|
sl@3
|
527 |
this.cmdGetFeatureReport.TabIndex = 15;
|
sl@3
|
528 |
this.cmdGetFeatureReport.Text = "Get Feature Report";
|
sl@3
|
529 |
this.cmdGetFeatureReport.UseVisualStyleBackColor = true;
|
sl@3
|
530 |
this.cmdGetFeatureReport.Click += new System.EventHandler(this.cmdGetFeatureReport_Click);
|
sl@3
|
531 |
//
|
sl@3
|
532 |
// cmdSendFeatureReport
|
sl@3
|
533 |
//
|
sl@3
|
534 |
this.cmdSendFeatureReport.Location = new System.Drawing.Point(141, 27);
|
sl@3
|
535 |
this.cmdSendFeatureReport.Name = "cmdSendFeatureReport";
|
sl@3
|
536 |
this.cmdSendFeatureReport.Size = new System.Drawing.Size(118, 26);
|
sl@3
|
537 |
this.cmdSendFeatureReport.TabIndex = 14;
|
sl@3
|
538 |
this.cmdSendFeatureReport.Text = "Send Feature Report";
|
sl@3
|
539 |
this.cmdSendFeatureReport.UseVisualStyleBackColor = true;
|
sl@3
|
540 |
this.cmdSendFeatureReport.Click += new System.EventHandler(this.cmdSendFeatureReport_Click);
|
sl@3
|
541 |
//
|
sl@3
|
542 |
// fraSendAndGetContinuous
|
sl@3
|
543 |
//
|
sl@3
|
544 |
this.fraSendAndGetContinuous.BackColor = System.Drawing.SystemColors.Control;
|
sl@3
|
545 |
this.fraSendAndGetContinuous.Controls.Add(this.radFeature);
|
sl@3
|
546 |
this.fraSendAndGetContinuous.Controls.Add(this.radInputOutputControl);
|
sl@3
|
547 |
this.fraSendAndGetContinuous.Controls.Add(this.radInputOutputInterrupt);
|
sl@3
|
548 |
this.fraSendAndGetContinuous.Controls.Add(this.cmdPeriodicTransfers);
|
sl@3
|
549 |
this.fraSendAndGetContinuous.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
550 |
this.fraSendAndGetContinuous.ForeColor = System.Drawing.SystemColors.ControlText;
|
sl@3
|
551 |
this.fraSendAndGetContinuous.Location = new System.Drawing.Point(311, 235);
|
sl@3
|
552 |
this.fraSendAndGetContinuous.Name = "fraSendAndGetContinuous";
|
sl@3
|
553 |
this.fraSendAndGetContinuous.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
sl@3
|
554 |
this.fraSendAndGetContinuous.Size = new System.Drawing.Size(295, 112);
|
sl@3
|
555 |
this.fraSendAndGetContinuous.TabIndex = 17;
|
sl@3
|
556 |
this.fraSendAndGetContinuous.TabStop = false;
|
sl@3
|
557 |
this.fraSendAndGetContinuous.Text = "Send and Get Continuous";
|
sl@3
|
558 |
//
|
sl@3
|
559 |
// radFeature
|
sl@3
|
560 |
//
|
sl@3
|
561 |
this.radFeature.AutoSize = true;
|
sl@3
|
562 |
this.radFeature.Location = new System.Drawing.Point(17, 76);
|
sl@3
|
563 |
this.radFeature.Name = "radFeature";
|
sl@3
|
564 |
this.radFeature.Size = new System.Drawing.Size(62, 18);
|
sl@3
|
565 |
this.radFeature.TabIndex = 19;
|
sl@3
|
566 |
this.radFeature.TabStop = true;
|
sl@3
|
567 |
this.radFeature.Text = "Feature";
|
sl@3
|
568 |
this.radFeature.UseVisualStyleBackColor = true;
|
sl@3
|
569 |
this.radFeature.CheckedChanged += new System.EventHandler(this.radFeature_CheckedChanged);
|
sl@3
|
570 |
//
|
sl@3
|
571 |
// radInputOutputControl
|
sl@3
|
572 |
//
|
sl@3
|
573 |
this.radInputOutputControl.AutoSize = true;
|
sl@3
|
574 |
this.radInputOutputControl.Location = new System.Drawing.Point(17, 52);
|
sl@3
|
575 |
this.radInputOutputControl.Name = "radInputOutputControl";
|
sl@3
|
576 |
this.radInputOutputControl.Size = new System.Drawing.Size(120, 18);
|
sl@3
|
577 |
this.radInputOutputControl.TabIndex = 18;
|
sl@3
|
578 |
this.radInputOutputControl.TabStop = true;
|
sl@3
|
579 |
this.radInputOutputControl.Text = "Input Output Control";
|
sl@3
|
580 |
this.radInputOutputControl.UseVisualStyleBackColor = true;
|
sl@3
|
581 |
this.radInputOutputControl.CheckedChanged += new System.EventHandler(this.radInputOutputControl_CheckedChanged);
|
sl@3
|
582 |
//
|
sl@3
|
583 |
// radInputOutputInterrupt
|
sl@3
|
584 |
//
|
sl@3
|
585 |
this.radInputOutputInterrupt.AutoSize = true;
|
sl@3
|
586 |
this.radInputOutputInterrupt.Location = new System.Drawing.Point(17, 28);
|
sl@3
|
587 |
this.radInputOutputInterrupt.Name = "radInputOutputInterrupt";
|
sl@3
|
588 |
this.radInputOutputInterrupt.Size = new System.Drawing.Size(126, 18);
|
sl@3
|
589 |
this.radInputOutputInterrupt.TabIndex = 17;
|
sl@3
|
590 |
this.radInputOutputInterrupt.TabStop = true;
|
sl@3
|
591 |
this.radInputOutputInterrupt.Text = "Input Output Interrupt";
|
sl@3
|
592 |
this.radInputOutputInterrupt.UseVisualStyleBackColor = true;
|
sl@3
|
593 |
this.radInputOutputInterrupt.CheckedChanged += new System.EventHandler(this.radInputOutputInterrupt_CheckedChanged);
|
sl@3
|
594 |
//
|
sl@3
|
595 |
// treeViewDevices
|
sl@3
|
596 |
//
|
sl@3
|
597 |
this.treeViewDevices.Location = new System.Drawing.Point(12, 12);
|
sl@3
|
598 |
this.treeViewDevices.Name = "treeViewDevices";
|
sl@3
|
599 |
this.treeViewDevices.Size = new System.Drawing.Size(284, 461);
|
sl@3
|
600 |
this.treeViewDevices.TabIndex = 18;
|
sl@5
|
601 |
this.treeViewDevices.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViewDevices_AfterSelect);
|
sl@3
|
602 |
//
|
sl@3
|
603 |
// FrmMain
|
sl@3
|
604 |
//
|
sl@3
|
605 |
this.ClientSize = new System.Drawing.Size(784, 756);
|
sl@3
|
606 |
this.Controls.Add(this.treeViewDevices);
|
sl@3
|
607 |
this.Controls.Add(this.fraSendAndGetContinuous);
|
sl@3
|
608 |
this.Controls.Add(this.fraControlTransfers);
|
sl@3
|
609 |
this.Controls.Add(this.fraInterruptTransfers);
|
sl@3
|
610 |
this.Controls.Add(this.cmdFindDevice);
|
sl@3
|
611 |
this.Controls.Add(this.fraDeviceIdentifiers);
|
sl@3
|
612 |
this.Controls.Add(this.fraInputReportBufferSize);
|
sl@3
|
613 |
this.Controls.Add(this.FraBytesReceived);
|
sl@3
|
614 |
this.Controls.Add(this.FraBytesToSend);
|
sl@3
|
615 |
this.Controls.Add(this.LstResults);
|
sl@3
|
616 |
this.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
sl@3
|
617 |
this.Location = new System.Drawing.Point(21, 28);
|
sl@3
|
618 |
this.Name = "FrmMain";
|
sl@3
|
619 |
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
sl@3
|
620 |
this.Text = "Generic HID Tester";
|
sl@3
|
621 |
this.Closed += new System.EventHandler(this.frmMain_Closed);
|
sl@3
|
622 |
this.Load += new System.EventHandler(this.frmMain_Load);
|
sl@3
|
623 |
this.FraBytesReceived.ResumeLayout(false);
|
sl@3
|
624 |
this.FraBytesReceived.PerformLayout();
|
sl@3
|
625 |
this.FraBytesToSend.ResumeLayout(false);
|
sl@3
|
626 |
this.fraInputReportBufferSize.ResumeLayout(false);
|
sl@3
|
627 |
this.fraInputReportBufferSize.PerformLayout();
|
sl@3
|
628 |
this.fraDeviceIdentifiers.ResumeLayout(false);
|
sl@3
|
629 |
this.fraDeviceIdentifiers.PerformLayout();
|
sl@3
|
630 |
this.fraInterruptTransfers.ResumeLayout(false);
|
sl@3
|
631 |
this.fraControlTransfers.ResumeLayout(false);
|
sl@3
|
632 |
this.fraSendAndGetContinuous.ResumeLayout(false);
|
sl@3
|
633 |
this.fraSendAndGetContinuous.PerformLayout();
|
sl@3
|
634 |
this.ResumeLayout(false);
|
sl@0
|
635 |
|
sl@0
|
636 |
}
|
sl@2
|
637 |
#endregion '"Windows Form Designer generated code "'
|
sl@0
|
638 |
|
sl@0
|
639 |
private Boolean _deviceDetected;
|
sl@0
|
640 |
private IntPtr _deviceNotificationHandle;
|
sl@0
|
641 |
private FileStream _deviceData;
|
sl@0
|
642 |
private FormActions _formActions;
|
sl@0
|
643 |
private SafeFileHandle _hidHandle;
|
sl@0
|
644 |
private String _hidUsage;
|
sl@0
|
645 |
private ManagementEventWatcher _deviceArrivedWatcher;
|
sl@0
|
646 |
private Boolean _deviceHandleObtained;
|
sl@0
|
647 |
private ManagementEventWatcher _deviceRemovedWatcher;
|
sl@0
|
648 |
private Int32 _myProductId;
|
sl@0
|
649 |
private Int32 _myVendorId;
|
sl@0
|
650 |
private Boolean _periodicTransfersRequested;
|
sl@0
|
651 |
private ReportReadOrWritten _readOrWritten;
|
sl@0
|
652 |
private ReportTypes _reportType;
|
sl@0
|
653 |
private SendOrGet _sendOrGet;
|
sl@0
|
654 |
private Boolean _transferInProgress;
|
sl@0
|
655 |
private TransferTypes _transferType;
|
sl@0
|
656 |
|
sl@0
|
657 |
private static System.Timers.Timer _periodicTransfers;
|
sl@0
|
658 |
|
sl@0
|
659 |
private readonly Debugging _myDebugging = new Debugging(); // For viewing results of API calls via Debug.Write.
|
sl@0
|
660 |
private readonly DeviceManagement _myDeviceManagement = new DeviceManagement();
|
sl@0
|
661 |
private Hid _myHid = new Hid();
|
sl@0
|
662 |
|
sl@0
|
663 |
private enum FormActions
|
sl@0
|
664 |
{
|
sl@0
|
665 |
AddItemToListBox,
|
sl@0
|
666 |
DisableInputReportBufferSize,
|
sl@0
|
667 |
EnableGetInputReportInterruptTransfer,
|
sl@0
|
668 |
EnableInputReportBufferSize,
|
sl@0
|
669 |
EnableSendOutputReportInterrupt,
|
sl@0
|
670 |
ScrollToBottomOfListBox,
|
sl@3
|
671 |
SetInputReportBufferSize,
|
sl@3
|
672 |
AddDeviceToTreeView,
|
sl@3
|
673 |
ResetDeviceTreeView,
|
sl@4
|
674 |
SelectDeviceInTreeView,
|
sl@4
|
675 |
CompleteDeviceTreeView
|
sl@0
|
676 |
}
|
sl@0
|
677 |
|
sl@0
|
678 |
private enum ReportReadOrWritten
|
sl@0
|
679 |
{
|
sl@0
|
680 |
Read,
|
sl@0
|
681 |
Written
|
sl@0
|
682 |
}
|
sl@0
|
683 |
|
sl@0
|
684 |
private enum ReportTypes
|
sl@0
|
685 |
{
|
sl@0
|
686 |
Input,
|
sl@0
|
687 |
Output,
|
sl@0
|
688 |
Feature
|
sl@0
|
689 |
}
|
sl@0
|
690 |
|
sl@0
|
691 |
private enum SendOrGet
|
sl@0
|
692 |
{
|
sl@0
|
693 |
Send,
|
sl@0
|
694 |
Get
|
sl@0
|
695 |
}
|
sl@0
|
696 |
|
sl@0
|
697 |
private enum TransferTypes
|
sl@0
|
698 |
{
|
sl@0
|
699 |
Control,
|
sl@0
|
700 |
Interrupt
|
sl@0
|
701 |
}
|
sl@0
|
702 |
|
sl@0
|
703 |
private enum WmiDeviceProperties
|
sl@0
|
704 |
{
|
sl@0
|
705 |
Name,
|
sl@0
|
706 |
Caption,
|
sl@0
|
707 |
Description,
|
sl@0
|
708 |
Manufacturer,
|
sl@0
|
709 |
PNPDeviceID,
|
sl@0
|
710 |
DeviceID,
|
sl@0
|
711 |
ClassGUID
|
sl@0
|
712 |
}
|
sl@0
|
713 |
|
sl@0
|
714 |
internal FrmMain FrmMy;
|
sl@0
|
715 |
|
sl@0
|
716 |
// This delegate has the same parameters as AccessForm.
|
sl@0
|
717 |
// Used in accessing the application's form from a different thread.
|
sl@0
|
718 |
|
sl@3
|
719 |
private delegate void MarshalDataToForm(FormActions action, params string[] strings);
|
sl@0
|
720 |
|
sl@0
|
721 |
/// <summary>
|
sl@0
|
722 |
/// Performs various application-specific functions that
|
sl@0
|
723 |
/// involve accessing the application's form.
|
sl@0
|
724 |
/// </summary>
|
sl@2
|
725 |
///
|
sl@0
|
726 |
/// <param name="action"> a FormActions member that names the action to perform on the form</param>
|
sl@2
|
727 |
/// <param name="formText"> text that the form displays or the code uses for
|
sl@0
|
728 |
/// another purpose. Actions that don't use text ignore this parameter. </param>
|
sl@0
|
729 |
|
sl@3
|
730 |
private void AccessForm(FormActions action, params string[] strings)
|
sl@0
|
731 |
{
|
sl@0
|
732 |
try
|
sl@0
|
733 |
{
|
sl@0
|
734 |
// Select an action to perform on the form:
|
sl@0
|
735 |
|
sl@0
|
736 |
switch (action)
|
sl@0
|
737 |
{
|
sl@0
|
738 |
case FormActions.AddItemToListBox:
|
sl@0
|
739 |
|
sl@3
|
740 |
LstResults.Items.Add(strings[0]);
|
sl@0
|
741 |
break;
|
sl@0
|
742 |
|
sl@0
|
743 |
case FormActions.DisableInputReportBufferSize:
|
sl@0
|
744 |
|
sl@0
|
745 |
cmdInputReportBufferSize.Enabled = false;
|
sl@0
|
746 |
break;
|
sl@0
|
747 |
|
sl@0
|
748 |
case FormActions.EnableGetInputReportInterruptTransfer:
|
sl@0
|
749 |
|
sl@0
|
750 |
cmdGetInputReportInterrupt.Enabled = true;
|
sl@0
|
751 |
break;
|
sl@0
|
752 |
|
sl@0
|
753 |
case FormActions.EnableInputReportBufferSize:
|
sl@0
|
754 |
|
sl@0
|
755 |
cmdInputReportBufferSize.Enabled = true;
|
sl@0
|
756 |
break;
|
sl@0
|
757 |
|
sl@0
|
758 |
case FormActions.EnableSendOutputReportInterrupt:
|
sl@0
|
759 |
|
sl@0
|
760 |
cmdSendOutputReportInterrupt.Enabled = true;
|
sl@0
|
761 |
break;
|
sl@0
|
762 |
|
sl@0
|
763 |
case FormActions.ScrollToBottomOfListBox:
|
sl@0
|
764 |
|
sl@0
|
765 |
LstResults.SelectedIndex = LstResults.Items.Count - 1;
|
sl@0
|
766 |
break;
|
sl@0
|
767 |
|
sl@0
|
768 |
case FormActions.SetInputReportBufferSize:
|
sl@0
|
769 |
|
sl@3
|
770 |
txtInputReportBufferSize.Text = strings[0];
|
sl@0
|
771 |
break;
|
sl@3
|
772 |
|
sl@3
|
773 |
case FormActions.AddDeviceToTreeView:
|
sl@3
|
774 |
{
|
sl@4
|
775 |
//Try and see if our device is already present
|
sl@4
|
776 |
TreeNode[] res = treeViewDevices.Nodes.Find(strings[0], false);
|
sl@4
|
777 |
foreach (TreeNode device in res)
|
sl@3
|
778 |
{
|
sl@4
|
779 |
if (device.ForeColor == Color.Red)
|
sl@4
|
780 |
{
|
sl@4
|
781 |
//Device was removed and has now been added back
|
sl@4
|
782 |
device.ForeColor = Color.Green;
|
sl@4
|
783 |
}
|
sl@4
|
784 |
else
|
sl@4
|
785 |
{
|
sl@4
|
786 |
//Device was already there set back our device color to black
|
sl@4
|
787 |
device.ForeColor = Color.Black;
|
sl@4
|
788 |
}
|
sl@3
|
789 |
}
|
sl@4
|
790 |
|
sl@4
|
791 |
if (res.Length > 0)
|
sl@4
|
792 |
{
|
sl@4
|
793 |
//Our device is already there
|
sl@4
|
794 |
break;
|
sl@4
|
795 |
}
|
sl@4
|
796 |
|
sl@4
|
797 |
//Build our node from our string array
|
sl@4
|
798 |
TreeNode newNode = new TreeNode(strings[0]);
|
sl@4
|
799 |
for (int i = 1; i < strings.Length; i++)
|
sl@4
|
800 |
{
|
sl@4
|
801 |
newNode.Nodes.Add(strings[i]);
|
sl@4
|
802 |
if (strings[i].StartsWith("Name: "))
|
sl@4
|
803 |
{
|
sl@4
|
804 |
//Found our name property, update our node text
|
sl@4
|
805 |
newNode.Text = strings[i].Substring(6, strings[i].Length - 6);
|
sl@4
|
806 |
}
|
sl@4
|
807 |
}
|
sl@4
|
808 |
|
sl@4
|
809 |
//New device color is green
|
sl@4
|
810 |
newNode.ForeColor = Color.Green;
|
sl@4
|
811 |
newNode.Name = strings[0]; //Set ID as name to make sure we can find it
|
sl@4
|
812 |
treeViewDevices.Nodes.Add(newNode);
|
sl@3
|
813 |
}
|
sl@3
|
814 |
break;
|
sl@3
|
815 |
|
sl@3
|
816 |
case FormActions.ResetDeviceTreeView:
|
sl@4
|
817 |
{
|
sl@4
|
818 |
//Mark all non removed/red device as purple/unknown
|
sl@4
|
819 |
foreach (TreeNode device in treeViewDevices.Nodes)
|
sl@4
|
820 |
{
|
sl@4
|
821 |
if (device.ForeColor != Color.Red)
|
sl@4
|
822 |
{
|
sl@4
|
823 |
device.ForeColor = Color.Purple;
|
sl@4
|
824 |
}
|
sl@4
|
825 |
}
|
sl@4
|
826 |
//treeViewDevices.Nodes.Clear();
|
sl@4
|
827 |
}
|
sl@4
|
828 |
break;
|
sl@4
|
829 |
|
sl@4
|
830 |
case FormActions.CompleteDeviceTreeView:
|
sl@4
|
831 |
{
|
sl@4
|
832 |
//Our device list is now complete
|
sl@4
|
833 |
foreach (TreeNode device in treeViewDevices.Nodes)
|
sl@4
|
834 |
{
|
sl@4
|
835 |
//Purple devices need to be marked as red for removed
|
sl@4
|
836 |
if (device.ForeColor == Color.Purple)
|
sl@4
|
837 |
{
|
sl@4
|
838 |
device.ForeColor = Color.Red;
|
sl@4
|
839 |
}
|
sl@4
|
840 |
}
|
sl@4
|
841 |
}
|
sl@3
|
842 |
break;
|
sl@3
|
843 |
|
sl@3
|
844 |
case FormActions.SelectDeviceInTreeView:
|
sl@3
|
845 |
{
|
sl@4
|
846 |
//treeViewDevices.SelectedNode = null;
|
sl@4
|
847 |
TreeNode[] res = treeViewDevices.Nodes.Find(strings[0], false);
|
sl@4
|
848 |
foreach (TreeNode device in res)
|
sl@4
|
849 |
{
|
sl@4
|
850 |
device.ForeColor = Color.Blue;
|
sl@4
|
851 |
//treeViewDevices.SelectedNode = res[0];
|
sl@4
|
852 |
//treeViewDevices.SelectedNode.ForeColor = Color.Blue;
|
sl@4
|
853 |
}
|
sl@3
|
854 |
}
|
sl@3
|
855 |
|
sl@3
|
856 |
|
sl@3
|
857 |
break;
|
sl@0
|
858 |
}
|
sl@0
|
859 |
}
|
sl@0
|
860 |
catch (Exception ex)
|
sl@0
|
861 |
{
|
sl@0
|
862 |
DisplayException(Name, ex);
|
sl@0
|
863 |
throw;
|
sl@0
|
864 |
}
|
sl@0
|
865 |
}
|
sl@0
|
866 |
|
sl@0
|
867 |
/// <summary>
|
sl@0
|
868 |
/// Add a handler to detect arrival of devices using WMI.
|
sl@0
|
869 |
/// </summary>
|
sl@0
|
870 |
|
sl@0
|
871 |
private void AddDeviceArrivedHandler()
|
sl@0
|
872 |
{
|
sl@0
|
873 |
const Int32 pollingIntervalSeconds = 3;
|
sl@0
|
874 |
var scope = new ManagementScope("root\\CIMV2");
|
sl@0
|
875 |
scope.Options.EnablePrivileges = true;
|
sl@0
|
876 |
|
sl@0
|
877 |
try
|
sl@0
|
878 |
{
|
sl@0
|
879 |
var q = new WqlEventQuery();
|
sl@0
|
880 |
q.EventClassName = "__InstanceCreationEvent";
|
sl@0
|
881 |
q.WithinInterval = new TimeSpan(0, 0, pollingIntervalSeconds);
|
sl@0
|
882 |
q.Condition = @"TargetInstance ISA 'Win32_USBControllerdevice'";
|
sl@0
|
883 |
_deviceArrivedWatcher = new ManagementEventWatcher(scope, q);
|
sl@0
|
884 |
_deviceArrivedWatcher.EventArrived += DeviceAdded;
|
sl@0
|
885 |
|
sl@0
|
886 |
_deviceArrivedWatcher.Start();
|
sl@0
|
887 |
}
|
sl@0
|
888 |
catch (Exception e)
|
sl@0
|
889 |
{
|
sl@0
|
890 |
Debug.WriteLine(e.Message);
|
sl@0
|
891 |
if (_deviceArrivedWatcher != null)
|
sl@0
|
892 |
_deviceArrivedWatcher.Stop();
|
sl@0
|
893 |
}
|
sl@0
|
894 |
}
|
sl@0
|
895 |
|
sl@0
|
896 |
/// <summary>
|
sl@0
|
897 |
/// Add a handler to detect removal of devices using WMI.
|
sl@0
|
898 |
/// </summary>
|
sl@0
|
899 |
|
sl@0
|
900 |
private void AddDeviceRemovedHandler()
|
sl@0
|
901 |
{
|
sl@0
|
902 |
const Int32 pollingIntervalSeconds = 3;
|
sl@0
|
903 |
var scope = new ManagementScope("root\\CIMV2");
|
sl@0
|
904 |
scope.Options.EnablePrivileges = true;
|
sl@0
|
905 |
|
sl@0
|
906 |
try
|
sl@0
|
907 |
{
|
sl@0
|
908 |
var q = new WqlEventQuery();
|
sl@0
|
909 |
q.EventClassName = "__InstanceDeletionEvent";
|
sl@0
|
910 |
q.WithinInterval = new TimeSpan(0, 0, pollingIntervalSeconds);
|
sl@0
|
911 |
q.Condition = @"TargetInstance ISA 'Win32_USBControllerdevice'";
|
sl@0
|
912 |
_deviceRemovedWatcher = new ManagementEventWatcher(scope, q);
|
sl@0
|
913 |
_deviceRemovedWatcher.EventArrived += DeviceRemoved;
|
sl@0
|
914 |
_deviceRemovedWatcher.Start();
|
sl@0
|
915 |
}
|
sl@0
|
916 |
catch (Exception e)
|
sl@0
|
917 |
{
|
sl@0
|
918 |
Debug.WriteLine(e.Message);
|
sl@0
|
919 |
if (_deviceRemovedWatcher != null)
|
sl@0
|
920 |
_deviceRemovedWatcher.Stop();
|
sl@0
|
921 |
}
|
sl@0
|
922 |
}
|
sl@0
|
923 |
|
sl@0
|
924 |
/// <summary>
|
sl@0
|
925 |
/// Close the handle and FileStreams for a device.
|
sl@0
|
926 |
/// </summary>
|
sl@2
|
927 |
///
|
sl@0
|
928 |
private void CloseCommunications()
|
sl@0
|
929 |
{
|
sl@0
|
930 |
if (_deviceData != null)
|
sl@0
|
931 |
{
|
sl@0
|
932 |
_deviceData.Close();
|
sl@0
|
933 |
}
|
sl@0
|
934 |
|
sl@0
|
935 |
if ((_hidHandle != null) && (!(_hidHandle.IsInvalid)))
|
sl@0
|
936 |
{
|
sl@0
|
937 |
_hidHandle.Close();
|
sl@0
|
938 |
}
|
sl@0
|
939 |
|
sl@0
|
940 |
// The next attempt to communicate will get a new handle and FileStreams.
|
sl@0
|
941 |
|
sl@0
|
942 |
_deviceHandleObtained = false;
|
sl@0
|
943 |
}
|
sl@0
|
944 |
|
sl@0
|
945 |
/// <summary>
|
sl@0
|
946 |
/// Search for a specific device.
|
sl@0
|
947 |
/// </summary>
|
sl@0
|
948 |
|
sl@0
|
949 |
private void cmdFindDevice_Click(Object sender, EventArgs e)
|
sl@0
|
950 |
{
|
sl@0
|
951 |
try
|
sl@0
|
952 |
{
|
sl@0
|
953 |
if (_transferInProgress)
|
sl@0
|
954 |
{
|
sl@0
|
955 |
DisplayTransferInProgressMessage();
|
sl@0
|
956 |
}
|
sl@0
|
957 |
else
|
sl@0
|
958 |
{
|
sl@0
|
959 |
_deviceDetected = FindDeviceUsingWmi();
|
sl@0
|
960 |
if (_deviceDetected)
|
sl@0
|
961 |
{
|
sl@0
|
962 |
FindTheHid();
|
sl@0
|
963 |
}
|
sl@0
|
964 |
}
|
sl@0
|
965 |
}
|
sl@0
|
966 |
catch (Exception ex)
|
sl@0
|
967 |
{
|
sl@0
|
968 |
DisplayException(Name, ex);
|
sl@0
|
969 |
throw;
|
sl@0
|
970 |
}
|
sl@0
|
971 |
}
|
sl@0
|
972 |
|
sl@0
|
973 |
/// <summary>
|
sl@0
|
974 |
/// Request to get a Feature report from the device.
|
sl@0
|
975 |
/// </summary>
|
sl@0
|
976 |
/// <param name="sender"></param>
|
sl@0
|
977 |
/// <param name="e"></param>
|
sl@0
|
978 |
|
sl@0
|
979 |
private void cmdGetFeatureReport_Click(object sender, EventArgs e)
|
sl@0
|
980 |
{
|
sl@0
|
981 |
try
|
sl@0
|
982 |
{
|
sl@0
|
983 |
if (_transferInProgress)
|
sl@0
|
984 |
{
|
sl@0
|
985 |
DisplayTransferInProgressMessage();
|
sl@0
|
986 |
}
|
sl@0
|
987 |
else
|
sl@0
|
988 |
{
|
sl@0
|
989 |
// Don't allow another transfer request until this one completes.
|
sl@2
|
990 |
// Move the focus away from the button to prevent the focus from
|
sl@0
|
991 |
// switching to the next control in the tab order on disabling the button.
|
sl@0
|
992 |
|
sl@0
|
993 |
fraControlTransfers.Focus();
|
sl@0
|
994 |
cmdGetFeatureReport.Enabled = false;
|
sl@0
|
995 |
_transferType = TransferTypes.Control;
|
sl@0
|
996 |
RequestToGetFeatureReport();
|
sl@0
|
997 |
}
|
sl@0
|
998 |
}
|
sl@0
|
999 |
catch (Exception ex)
|
sl@0
|
1000 |
{
|
sl@0
|
1001 |
DisplayException(Name, ex);
|
sl@0
|
1002 |
throw;
|
sl@0
|
1003 |
}
|
sl@0
|
1004 |
}
|
sl@0
|
1005 |
|
sl@0
|
1006 |
/// <summary>
|
sl@0
|
1007 |
/// Request to get an Input report from the device using a control transfer.
|
sl@0
|
1008 |
/// </summary>
|
sl@0
|
1009 |
/// <param name="sender"></param>
|
sl@0
|
1010 |
/// <param name="e"></param>
|
sl@0
|
1011 |
|
sl@0
|
1012 |
private void cmdGetInputReportControl_Click(object sender, EventArgs e)
|
sl@0
|
1013 |
{
|
sl@0
|
1014 |
try
|
sl@0
|
1015 |
{
|
sl@0
|
1016 |
// Don't allow another transfer request until this one completes.
|
sl@2
|
1017 |
// Move the focus away from the button to prevent the focus from
|
sl@0
|
1018 |
// switching to the next control in the tab order on disabling the button.
|
sl@0
|
1019 |
|
sl@0
|
1020 |
if (_transferInProgress)
|
sl@0
|
1021 |
{
|
sl@0
|
1022 |
DisplayTransferInProgressMessage();
|
sl@0
|
1023 |
}
|
sl@0
|
1024 |
else
|
sl@0
|
1025 |
{
|
sl@0
|
1026 |
fraControlTransfers.Focus();
|
sl@0
|
1027 |
cmdGetInputReportControl.Enabled = false;
|
sl@0
|
1028 |
_transferType = TransferTypes.Control;
|
sl@0
|
1029 |
RequestToGetInputReport();
|
sl@0
|
1030 |
}
|
sl@0
|
1031 |
}
|
sl@0
|
1032 |
catch (Exception ex)
|
sl@0
|
1033 |
{
|
sl@0
|
1034 |
DisplayException(Name, ex);
|
sl@0
|
1035 |
throw;
|
sl@0
|
1036 |
}
|
sl@0
|
1037 |
}
|
sl@0
|
1038 |
|
sl@0
|
1039 |
/// <summary>
|
sl@0
|
1040 |
/// Request to get an Input report retrieved using interrupt transfers.
|
sl@0
|
1041 |
/// </summary>
|
sl@0
|
1042 |
/// <param name="sender"></param>
|
sl@0
|
1043 |
/// <param name="e"></param>
|
sl@2
|
1044 |
///
|
sl@0
|
1045 |
private void cmdGetInputReportInterrupt_Click(object sender, EventArgs e)
|
sl@0
|
1046 |
{
|
sl@0
|
1047 |
try
|
sl@0
|
1048 |
{
|
sl@0
|
1049 |
if (_transferInProgress)
|
sl@0
|
1050 |
{
|
sl@0
|
1051 |
DisplayTransferInProgressMessage();
|
sl@0
|
1052 |
}
|
sl@0
|
1053 |
else
|
sl@0
|
1054 |
{
|
sl@0
|
1055 |
// Don't allow another transfer request until this one completes.
|
sl@2
|
1056 |
// Move the focus away from the button to prevent the focus from
|
sl@0
|
1057 |
// switching to the next control in the tab order on disabling the button.
|
sl@0
|
1058 |
|
sl@0
|
1059 |
fraInterruptTransfers.Focus();
|
sl@0
|
1060 |
cmdGetInputReportInterrupt.Enabled = false;
|
sl@0
|
1061 |
_transferType = TransferTypes.Interrupt;
|
sl@0
|
1062 |
RequestToGetInputReport();
|
sl@0
|
1063 |
}
|
sl@0
|
1064 |
}
|
sl@0
|
1065 |
catch (Exception ex)
|
sl@0
|
1066 |
{
|
sl@0
|
1067 |
DisplayException(Name, ex);
|
sl@0
|
1068 |
throw;
|
sl@0
|
1069 |
}
|
sl@0
|
1070 |
}
|
sl@0
|
1071 |
|
sl@0
|
1072 |
/// <summary>
|
sl@0
|
1073 |
/// Set the number of Input reports the HID driver will store.
|
sl@0
|
1074 |
/// </summary>
|
sl@0
|
1075 |
|
sl@0
|
1076 |
private void cmdInputReportBufferSize_Click(Object sender, EventArgs e)
|
sl@0
|
1077 |
{
|
sl@0
|
1078 |
try
|
sl@0
|
1079 |
{
|
sl@0
|
1080 |
if (_transferInProgress)
|
sl@0
|
1081 |
{
|
sl@0
|
1082 |
DisplayTransferInProgressMessage();
|
sl@0
|
1083 |
}
|
sl@0
|
1084 |
else
|
sl@0
|
1085 |
{
|
sl@0
|
1086 |
SetInputReportBufferSize();
|
sl@0
|
1087 |
}
|
sl@0
|
1088 |
}
|
sl@0
|
1089 |
catch
|
sl@0
|
1090 |
(Exception ex)
|
sl@0
|
1091 |
{
|
sl@0
|
1092 |
DisplayException(Name, ex);
|
sl@0
|
1093 |
throw;
|
sl@0
|
1094 |
}
|
sl@0
|
1095 |
}
|
sl@0
|
1096 |
|
sl@0
|
1097 |
/// <summary>
|
sl@0
|
1098 |
/// Alternate sending and getting a report.
|
sl@0
|
1099 |
/// </summary>
|
sl@0
|
1100 |
/// <param name="sender"></param>
|
sl@0
|
1101 |
/// <param name="e"></param>
|
sl@0
|
1102 |
|
sl@0
|
1103 |
private void cmdPeriodicTransfers_Click(object sender, EventArgs e)
|
sl@0
|
1104 |
{
|
sl@0
|
1105 |
try
|
sl@0
|
1106 |
{
|
sl@0
|
1107 |
if (cmdPeriodicTransfers.Text == "Start")
|
sl@0
|
1108 |
{
|
sl@0
|
1109 |
if (_transferInProgress)
|
sl@0
|
1110 |
{
|
sl@0
|
1111 |
DisplayTransferInProgressMessage();
|
sl@0
|
1112 |
}
|
sl@0
|
1113 |
else
|
sl@0
|
1114 |
{
|
sl@0
|
1115 |
_sendOrGet = SendOrGet.Send;
|
sl@0
|
1116 |
PeriodicTransfersStart();
|
sl@0
|
1117 |
}
|
sl@0
|
1118 |
}
|
sl@0
|
1119 |
else
|
sl@0
|
1120 |
{
|
sl@0
|
1121 |
PeriodicTransfersStop();
|
sl@0
|
1122 |
}
|
sl@0
|
1123 |
}
|
sl@0
|
1124 |
catch (Exception ex)
|
sl@0
|
1125 |
{
|
sl@0
|
1126 |
DisplayException(Name, ex);
|
sl@0
|
1127 |
throw;
|
sl@0
|
1128 |
}
|
sl@0
|
1129 |
}
|
sl@0
|
1130 |
|
sl@0
|
1131 |
/// <summary>
|
sl@0
|
1132 |
/// Request to send a Feature report using a control transfer.
|
sl@0
|
1133 |
/// </summary>
|
sl@0
|
1134 |
/// <param name="sender"></param>
|
sl@0
|
1135 |
/// <param name="e"></param>
|
sl@0
|
1136 |
|
sl@0
|
1137 |
private void cmdSendFeatureReport_Click(object sender, EventArgs e)
|
sl@0
|
1138 |
{
|
sl@0
|
1139 |
try
|
sl@0
|
1140 |
{
|
sl@0
|
1141 |
if (_transferInProgress)
|
sl@0
|
1142 |
{
|
sl@0
|
1143 |
DisplayTransferInProgressMessage();
|
sl@0
|
1144 |
}
|
sl@0
|
1145 |
else
|
sl@0
|
1146 |
{
|
sl@0
|
1147 |
// Don't allow another transfer request until this one completes.
|
sl@2
|
1148 |
// Move the focus away from the button to prevent the focus from
|
sl@0
|
1149 |
// switching to the next control in the tab order on disabling the button.
|
sl@0
|
1150 |
|
sl@0
|
1151 |
fraControlTransfers.Focus();
|
sl@0
|
1152 |
cmdSendFeatureReport.Enabled = false;
|
sl@0
|
1153 |
_transferType = TransferTypes.Control;
|
sl@0
|
1154 |
RequestToSendFeatureReport();
|
sl@0
|
1155 |
}
|
sl@0
|
1156 |
}
|
sl@0
|
1157 |
catch (Exception ex)
|
sl@0
|
1158 |
{
|
sl@0
|
1159 |
DisplayException(Name, ex);
|
sl@0
|
1160 |
throw;
|
sl@0
|
1161 |
}
|
sl@0
|
1162 |
}
|
sl@0
|
1163 |
|
sl@0
|
1164 |
/// <summary>
|
sl@0
|
1165 |
/// Request to send an Output report using a control transfer.
|
sl@0
|
1166 |
/// </summary>
|
sl@0
|
1167 |
/// <param name="sender"></param>
|
sl@0
|
1168 |
/// <param name="e"></param>
|
sl@2
|
1169 |
///
|
sl@0
|
1170 |
private void cmdSendOutputReportControl_Click(object sender, EventArgs e)
|
sl@0
|
1171 |
{
|
sl@0
|
1172 |
try
|
sl@0
|
1173 |
{
|
sl@0
|
1174 |
if (_transferInProgress)
|
sl@0
|
1175 |
{
|
sl@0
|
1176 |
DisplayTransferInProgressMessage();
|
sl@0
|
1177 |
}
|
sl@0
|
1178 |
else
|
sl@0
|
1179 |
{
|
sl@0
|
1180 |
// Don't allow another transfer request until this one completes.
|
sl@2
|
1181 |
// Move the focus away from the button to prevent the focus from
|
sl@0
|
1182 |
// switching to the next control in the tab order on disabling the button.
|
sl@0
|
1183 |
|
sl@0
|
1184 |
fraControlTransfers.Focus();
|
sl@0
|
1185 |
cmdSendOutputReportControl.Enabled = false;
|
sl@0
|
1186 |
_transferType = TransferTypes.Control;
|
sl@0
|
1187 |
RequestToSendOutputReport();
|
sl@0
|
1188 |
}
|
sl@0
|
1189 |
}
|
sl@0
|
1190 |
catch (Exception ex)
|
sl@0
|
1191 |
{
|
sl@0
|
1192 |
DisplayException(Name, ex);
|
sl@0
|
1193 |
throw;
|
sl@0
|
1194 |
}
|
sl@0
|
1195 |
}
|
sl@0
|
1196 |
|
sl@0
|
1197 |
/// <summary>
|
sl@2
|
1198 |
/// Request to send an Output report using an interrupt transfer.
|
sl@0
|
1199 |
/// </summary>
|
sl@0
|
1200 |
/// <param name="sender"></param>
|
sl@0
|
1201 |
/// <param name="e"></param>
|
sl@0
|
1202 |
|
sl@0
|
1203 |
private void cmdSendOutputReportInterrupt_Click(object sender, EventArgs e)
|
sl@0
|
1204 |
{
|
sl@0
|
1205 |
try
|
sl@0
|
1206 |
{
|
sl@0
|
1207 |
if (_transferInProgress)
|
sl@0
|
1208 |
{
|
sl@0
|
1209 |
DisplayTransferInProgressMessage();
|
sl@0
|
1210 |
}
|
sl@0
|
1211 |
else
|
sl@0
|
1212 |
{
|
sl@0
|
1213 |
// Don't allow another transfer request until this one completes.
|
sl@2
|
1214 |
// Move the focus away from the button to prevent the focus from
|
sl@0
|
1215 |
// switching to the next control in the tab order on disabling the button.
|
sl@0
|
1216 |
|
sl@0
|
1217 |
fraInterruptTransfers.Focus();
|
sl@0
|
1218 |
cmdSendOutputReportInterrupt.Enabled = false;
|
sl@0
|
1219 |
_transferType = TransferTypes.Interrupt;
|
sl@0
|
1220 |
RequestToSendOutputReport();
|
sl@0
|
1221 |
}
|
sl@0
|
1222 |
}
|
sl@0
|
1223 |
catch (Exception ex)
|
sl@0
|
1224 |
{
|
sl@0
|
1225 |
DisplayException(Name, ex);
|
sl@0
|
1226 |
throw;
|
sl@0
|
1227 |
}
|
sl@0
|
1228 |
}
|
sl@0
|
1229 |
|
sl@0
|
1230 |
/// <summary>
|
sl@0
|
1231 |
/// Called on arrival of any device.
|
sl@0
|
1232 |
/// Calls a routine that searches to see if the desired device is present.
|
sl@0
|
1233 |
/// </summary>
|
sl@0
|
1234 |
|
sl@0
|
1235 |
private void DeviceAdded(object sender, EventArrivedEventArgs e)
|
sl@0
|
1236 |
{
|
sl@0
|
1237 |
try
|
sl@0
|
1238 |
{
|
sl@0
|
1239 |
Debug.WriteLine("A USB device has been inserted");
|
sl@0
|
1240 |
|
sl@0
|
1241 |
_deviceDetected = FindDeviceUsingWmi();
|
sl@0
|
1242 |
}
|
sl@0
|
1243 |
catch (Exception ex)
|
sl@0
|
1244 |
{
|
sl@0
|
1245 |
DisplayException(Name, ex);
|
sl@0
|
1246 |
throw;
|
sl@0
|
1247 |
}
|
sl@0
|
1248 |
}
|
sl@0
|
1249 |
|
sl@0
|
1250 |
/// <summary>
|
sl@0
|
1251 |
/// Called if the user changes the Vendor ID or Product ID in the text box.
|
sl@0
|
1252 |
/// </summary>
|
sl@0
|
1253 |
|
sl@0
|
1254 |
private void DeviceHasChanged()
|
sl@0
|
1255 |
{
|
sl@0
|
1256 |
try
|
sl@0
|
1257 |
{
|
sl@0
|
1258 |
// If a device was previously detected, stop receiving notifications about it.
|
sl@0
|
1259 |
|
sl@0
|
1260 |
if (_deviceHandleObtained)
|
sl@0
|
1261 |
{
|
sl@0
|
1262 |
DeviceNotificationsStop();
|
sl@0
|
1263 |
|
sl@0
|
1264 |
CloseCommunications();
|
sl@0
|
1265 |
}
|
sl@0
|
1266 |
// Look for a device that matches the Vendor ID and Product ID in the text boxes.
|
sl@0
|
1267 |
|
sl@0
|
1268 |
FindTheHid();
|
sl@0
|
1269 |
}
|
sl@0
|
1270 |
catch (Exception ex)
|
sl@0
|
1271 |
{
|
sl@0
|
1272 |
DisplayException(Name, ex);
|
sl@0
|
1273 |
throw;
|
sl@0
|
1274 |
}
|
sl@0
|
1275 |
}
|
sl@0
|
1276 |
|
sl@0
|
1277 |
/// <summary>
|
sl@0
|
1278 |
/// Add handlers to detect device arrival and removal.
|
sl@0
|
1279 |
/// </summary>
|
sl@0
|
1280 |
|
sl@0
|
1281 |
private void DeviceNotificationsStart()
|
sl@0
|
1282 |
{
|
sl@0
|
1283 |
AddDeviceArrivedHandler();
|
sl@0
|
1284 |
AddDeviceRemovedHandler();
|
sl@0
|
1285 |
}
|
sl@0
|
1286 |
|
sl@0
|
1287 |
/// <summary>
|
sl@0
|
1288 |
/// Stop receiving notifications about device arrival and removal
|
sl@0
|
1289 |
/// </summary>
|
sl@0
|
1290 |
|
sl@0
|
1291 |
private void DeviceNotificationsStop()
|
sl@0
|
1292 |
{
|
sl@0
|
1293 |
try
|
sl@0
|
1294 |
{
|
sl@0
|
1295 |
if (_deviceArrivedWatcher != null)
|
sl@0
|
1296 |
_deviceArrivedWatcher.Stop();
|
sl@0
|
1297 |
if (_deviceRemovedWatcher != null)
|
sl@0
|
1298 |
_deviceRemovedWatcher.Stop();
|
sl@0
|
1299 |
}
|
sl@0
|
1300 |
catch (Exception ex)
|
sl@0
|
1301 |
{
|
sl@0
|
1302 |
DisplayException(Name, ex);
|
sl@0
|
1303 |
throw;
|
sl@0
|
1304 |
}
|
sl@0
|
1305 |
}
|
sl@0
|
1306 |
|
sl@0
|
1307 |
/// <summary>
|
sl@0
|
1308 |
/// Called on removal of any device.
|
sl@0
|
1309 |
/// Calls a routine that searches to see if the desired device is still present.
|
sl@0
|
1310 |
/// </summary>
|
sl@2
|
1311 |
///
|
sl@0
|
1312 |
private void DeviceRemoved(object sender, EventArgs e)
|
sl@0
|
1313 |
{
|
sl@0
|
1314 |
try
|
sl@0
|
1315 |
{
|
sl@0
|
1316 |
Debug.WriteLine("A USB device has been removed");
|
sl@0
|
1317 |
|
sl@0
|
1318 |
_deviceDetected = FindDeviceUsingWmi();
|
sl@0
|
1319 |
|
sl@0
|
1320 |
if (!_deviceDetected)
|
sl@0
|
1321 |
{
|
sl@0
|
1322 |
_deviceHandleObtained = false;
|
sl@0
|
1323 |
CloseCommunications();
|
sl@0
|
1324 |
}
|
sl@0
|
1325 |
}
|
sl@0
|
1326 |
catch (Exception ex)
|
sl@0
|
1327 |
{
|
sl@0
|
1328 |
DisplayException(Name, ex);
|
sl@0
|
1329 |
throw;
|
sl@0
|
1330 |
}
|
sl@0
|
1331 |
}
|
sl@0
|
1332 |
|
sl@0
|
1333 |
/// <summary>
|
sl@0
|
1334 |
/// Displays received or written report data.
|
sl@0
|
1335 |
/// </summary>
|
sl@2
|
1336 |
///
|
sl@2
|
1337 |
/// <param name="buffer"> contains the report data. </param>
|
sl@0
|
1338 |
/// <param name="currentReportType" > "Input", "Output", or "Feature"</param>
|
sl@0
|
1339 |
/// <param name="currentReadOrWritten" > "read" for Input and IN Feature reports, "written" for Output and OUT Feature reports.</param>
|
sl@0
|
1340 |
|
sl@0
|
1341 |
private void DisplayReportData(Byte[] buffer, ReportTypes currentReportType, ReportReadOrWritten currentReadOrWritten)
|
sl@0
|
1342 |
{
|
sl@0
|
1343 |
try
|
sl@0
|
1344 |
{
|
sl@0
|
1345 |
Int32 count;
|
sl@0
|
1346 |
|
sl@0
|
1347 |
LstResults.Items.Add(currentReportType.ToString() + " report has been " + currentReadOrWritten.ToString().ToLower() + ".");
|
sl@0
|
1348 |
|
sl@0
|
1349 |
// Display the report data received in the form's list box.
|
sl@0
|
1350 |
|
sl@0
|
1351 |
LstResults.Items.Add(" Report ID: " + String.Format("{0:X2} ", buffer[0]));
|
sl@0
|
1352 |
LstResults.Items.Add(" Report Data:");
|
sl@0
|
1353 |
|
sl@0
|
1354 |
TxtBytesReceived.Text = "";
|
sl@0
|
1355 |
|
sl@0
|
1356 |
for (count = 1; count <= buffer.Length - 1; count++)
|
sl@0
|
1357 |
{
|
sl@0
|
1358 |
// Display bytes as 2-character Hex strings.
|
sl@0
|
1359 |
|
sl@0
|
1360 |
String byteValue = String.Format("{0:X2} ", buffer[count]);
|
sl@0
|
1361 |
|
sl@0
|
1362 |
LstResults.Items.Add(" " + byteValue);
|
sl@0
|
1363 |
|
sl@0
|
1364 |
// Display the received bytes in the text box.
|
sl@0
|
1365 |
|
sl@0
|
1366 |
TxtBytesReceived.SelectionStart = TxtBytesReceived.Text.Length;
|
sl@0
|
1367 |
TxtBytesReceived.SelectedText = byteValue + Environment.NewLine;
|
sl@0
|
1368 |
}
|
sl@0
|
1369 |
ScrollToBottomOfListBox();
|
sl@0
|
1370 |
}
|
sl@0
|
1371 |
catch (Exception ex)
|
sl@0
|
1372 |
{
|
sl@0
|
1373 |
DisplayException(Name, ex);
|
sl@0
|
1374 |
throw;
|
sl@0
|
1375 |
}
|
sl@0
|
1376 |
}
|
sl@0
|
1377 |
|
sl@0
|
1378 |
/// <summary>
|
sl@0
|
1379 |
/// Display a message if the user clicks a button when a transfer is in progress.
|
sl@0
|
1380 |
/// </summary>
|
sl@2
|
1381 |
///
|
sl@0
|
1382 |
private void DisplayTransferInProgressMessage()
|
sl@0
|
1383 |
{
|
sl@0
|
1384 |
AccessForm(FormActions.AddItemToListBox, "Command not executed because a transfer is in progress.");
|
sl@0
|
1385 |
ScrollToBottomOfListBox();
|
sl@0
|
1386 |
}
|
sl@0
|
1387 |
|
sl@0
|
1388 |
/// <summary>
|
sl@0
|
1389 |
/// Do periodic transfers.
|
sl@0
|
1390 |
/// </summary>
|
sl@0
|
1391 |
/// <param name="source"></param>
|
sl@0
|
1392 |
/// <param name="e"></param>
|
sl@0
|
1393 |
/// <remarks>
|
sl@0
|
1394 |
/// The timer is enabled only if continuous (periodic) transfers have been requested.
|
sl@2
|
1395 |
/// </remarks>
|
sl@0
|
1396 |
|
sl@0
|
1397 |
private void DoPeriodicTransfers(object source, ElapsedEventArgs e)
|
sl@0
|
1398 |
{
|
sl@0
|
1399 |
try
|
sl@0
|
1400 |
{
|
sl@0
|
1401 |
PeriodicTransfers();
|
sl@0
|
1402 |
}
|
sl@0
|
1403 |
catch (Exception ex)
|
sl@0
|
1404 |
{
|
sl@0
|
1405 |
DisplayException(Name, ex);
|
sl@0
|
1406 |
throw;
|
sl@0
|
1407 |
}
|
sl@0
|
1408 |
}
|
sl@0
|
1409 |
|
sl@0
|
1410 |
/// <summary>
|
sl@0
|
1411 |
/// Enable the command buttons on the form.
|
sl@0
|
1412 |
/// Needed after attempting a transfer and device not found.
|
sl@0
|
1413 |
/// </summary>
|
sl@2
|
1414 |
///
|
sl@0
|
1415 |
private void EnableFormControls()
|
sl@0
|
1416 |
{
|
sl@0
|
1417 |
cmdGetInputReportInterrupt.Enabled = true;
|
sl@0
|
1418 |
cmdSendOutputReportControl.Enabled = true;
|
sl@0
|
1419 |
cmdGetInputReportControl.Enabled = true;
|
sl@0
|
1420 |
cmdGetFeatureReport.Enabled = true;
|
sl@0
|
1421 |
cmdSendFeatureReport.Enabled = true;
|
sl@0
|
1422 |
cmdPeriodicTransfers.Enabled = true;
|
sl@0
|
1423 |
cmdSendOutputReportInterrupt.Enabled = true;
|
sl@0
|
1424 |
}
|
sl@0
|
1425 |
|
sl@0
|
1426 |
/// <summary>
|
sl@0
|
1427 |
/// Use the System.Management class to find a device by Vendor ID and Product ID using WMI. If found, display device properties.
|
sl@0
|
1428 |
/// </summary>
|
sl@2
|
1429 |
/// <remarks>
|
sl@0
|
1430 |
/// During debugging, if you stop the firmware but leave the device attached, the device may still be detected as present
|
sl@2
|
1431 |
/// but will be unable to communicate. The device will show up in Windows Device Manager as well.
|
sl@0
|
1432 |
/// This situation is unlikely to occur with a final product.
|
sl@0
|
1433 |
/// </remarks>
|
sl@0
|
1434 |
|
sl@0
|
1435 |
private Boolean FindDeviceUsingWmi()
|
sl@0
|
1436 |
{
|
sl@0
|
1437 |
try
|
sl@0
|
1438 |
{
|
sl@3
|
1439 |
MyMarshalDataToForm(FormActions.ResetDeviceTreeView);
|
sl@0
|
1440 |
// Prepend "@" to string below to treat backslash as a normal character (not escape character):
|
sl@0
|
1441 |
|
sl@0
|
1442 |
String deviceIdString = @"USB\VID_" + _myVendorId.ToString("X4") + "&PID_" + _myProductId.ToString("X4");
|
sl@0
|
1443 |
|
sl@0
|
1444 |
_deviceDetected = false;
|
sl@0
|
1445 |
var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity");
|
sl@2
|
1446 |
int usbDeviceCounter = 0;
|
sl@0
|
1447 |
|
sl@0
|
1448 |
foreach (ManagementObject queryObj in searcher.Get())
|
sl@0
|
1449 |
{
|
sl@2
|
1450 |
string deviceId = queryObj["PNPDeviceID"].ToString();
|
sl@2
|
1451 |
if (deviceId.Contains(deviceIdString))
|
sl@2
|
1452 |
{
|
sl@2
|
1453 |
_deviceDetected = true;
|
sl@2
|
1454 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "My device found (WMI):");
|
sl@0
|
1455 |
|
sl@3
|
1456 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "--------");
|
sl@3
|
1457 |
List<string> device = new List<string>();
|
sl@3
|
1458 |
device.Add(deviceId);
|
sl@3
|
1459 |
usbDeviceCounter++;
|
sl@2
|
1460 |
// Display device properties.
|
sl@2
|
1461 |
foreach (WmiDeviceProperties wmiDeviceProperty in Enum.GetValues(typeof(WmiDeviceProperties)))
|
sl@2
|
1462 |
{
|
sl@2
|
1463 |
MyMarshalDataToForm(FormActions.AddItemToListBox, (wmiDeviceProperty.ToString() + ": " + queryObj[wmiDeviceProperty.ToString()]));
|
sl@3
|
1464 |
device.Add((wmiDeviceProperty.ToString() + ": " + queryObj[wmiDeviceProperty.ToString()]));
|
sl@2
|
1465 |
Debug.WriteLine(wmiDeviceProperty.ToString() + ": {0}", queryObj[wmiDeviceProperty.ToString()]);
|
sl@2
|
1466 |
}
|
sl@2
|
1467 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "--------");
|
sl@2
|
1468 |
MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
|
sl@3
|
1469 |
|
sl@3
|
1470 |
MyMarshalDataToForm(FormActions.AddDeviceToTreeView, device.ToArray());
|
sl@3
|
1471 |
MyMarshalDataToForm(FormActions.SelectDeviceInTreeView, deviceId);
|
sl@3
|
1472 |
|
sl@2
|
1473 |
}
|
sl@3
|
1474 |
else if (deviceId.StartsWith("USB\\VID"))
|
sl@2
|
1475 |
{
|
sl@3
|
1476 |
List<string> device = new List<string>();
|
sl@3
|
1477 |
device.Add(deviceId);
|
sl@2
|
1478 |
usbDeviceCounter++;
|
sl@3
|
1479 |
// Add device properties.
|
sl@2
|
1480 |
foreach (WmiDeviceProperties wmiDeviceProperty in Enum.GetValues(typeof(WmiDeviceProperties)))
|
sl@2
|
1481 |
{
|
sl@3
|
1482 |
device.Add((wmiDeviceProperty.ToString() + ": " + queryObj[wmiDeviceProperty.ToString()]));
|
sl@2
|
1483 |
Debug.WriteLine(wmiDeviceProperty.ToString() + ": {0}", queryObj[wmiDeviceProperty.ToString()]);
|
sl@2
|
1484 |
}
|
sl@3
|
1485 |
|
sl@3
|
1486 |
MyMarshalDataToForm(FormActions.AddDeviceToTreeView, device.ToArray());
|
sl@2
|
1487 |
}
|
sl@0
|
1488 |
}
|
sl@2
|
1489 |
|
sl@4
|
1490 |
//Complete our device TreeView
|
sl@4
|
1491 |
MyMarshalDataToForm(FormActions.CompleteDeviceTreeView);
|
sl@4
|
1492 |
|
sl@4
|
1493 |
|
sl@2
|
1494 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "Found " + usbDeviceCounter /*searcher.Get().Count*/ + " USB HID devices");
|
sl@2
|
1495 |
|
sl@0
|
1496 |
if (!_deviceDetected)
|
sl@0
|
1497 |
{
|
sl@0
|
1498 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "My device not found (WMI)");
|
sl@0
|
1499 |
MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
|
sl@0
|
1500 |
}
|
sl@0
|
1501 |
return _deviceDetected;
|
sl@0
|
1502 |
}
|
sl@0
|
1503 |
catch (Exception ex)
|
sl@0
|
1504 |
{
|
sl@0
|
1505 |
DisplayException(Name, ex);
|
sl@0
|
1506 |
throw;
|
sl@0
|
1507 |
}
|
sl@0
|
1508 |
}
|
sl@0
|
1509 |
|
sl@0
|
1510 |
/// <summary>
|
sl@0
|
1511 |
/// Call HID functions that use Win32 API functions to locate a HID-class device
|
sl@0
|
1512 |
/// by its Vendor ID and Product ID. Open a handle to the device.
|
sl@0
|
1513 |
/// </summary>
|
sl@2
|
1514 |
///
|
sl@0
|
1515 |
/// <returns>
|
sl@0
|
1516 |
/// True if the device is detected, False if not detected.
|
sl@0
|
1517 |
/// </returns>
|
sl@0
|
1518 |
|
sl@0
|
1519 |
private Boolean FindTheHid()
|
sl@0
|
1520 |
{
|
sl@0
|
1521 |
var devicePathName = new String[128];
|
sl@0
|
1522 |
String myDevicePathName = "";
|
sl@0
|
1523 |
|
sl@0
|
1524 |
try
|
sl@0
|
1525 |
{
|
sl@0
|
1526 |
_deviceHandleObtained = false;
|
sl@0
|
1527 |
CloseCommunications();
|
sl@0
|
1528 |
|
sl@0
|
1529 |
// Get the device's Vendor ID and Product ID from the form's text boxes.
|
sl@0
|
1530 |
|
sl@0
|
1531 |
GetVendorAndProductIDsFromTextBoxes(ref _myVendorId, ref _myProductId);
|
sl@0
|
1532 |
|
sl@0
|
1533 |
// Get the HID-class GUID.
|
sl@0
|
1534 |
|
sl@0
|
1535 |
Guid hidGuid = _myHid.GetHidGuid();
|
sl@0
|
1536 |
|
sl@0
|
1537 |
String functionName = "GetHidGuid";
|
sl@0
|
1538 |
Debug.WriteLine(_myDebugging.ResultOfApiCall(functionName));
|
sl@0
|
1539 |
Debug.WriteLine(" GUID for system HIDs: " + hidGuid.ToString());
|
sl@0
|
1540 |
|
sl@0
|
1541 |
// Fill an array with the device path names of all attached HIDs.
|
sl@0
|
1542 |
|
sl@0
|
1543 |
Boolean availableHids = _myDeviceManagement.FindDeviceFromGuid(hidGuid, ref devicePathName);
|
sl@0
|
1544 |
|
sl@0
|
1545 |
// If there is at least one HID, attempt to read the Vendor ID and Product ID
|
sl@0
|
1546 |
// of each device until there is a match or all devices have been examined.
|
sl@0
|
1547 |
|
sl@0
|
1548 |
if (availableHids)
|
sl@0
|
1549 |
{
|
sl@0
|
1550 |
Int32 memberIndex = 0;
|
sl@0
|
1551 |
|
sl@0
|
1552 |
do
|
sl@0
|
1553 |
{
|
sl@0
|
1554 |
// Open the handle without read/write access to enable getting information about any HID, even system keyboards and mice.
|
sl@0
|
1555 |
|
sl@0
|
1556 |
_hidHandle = _myHid.OpenHandle(devicePathName[memberIndex], false);
|
sl@0
|
1557 |
|
sl@0
|
1558 |
functionName = "CreateFile";
|
sl@0
|
1559 |
Debug.WriteLine(_myDebugging.ResultOfApiCall(functionName));
|
sl@0
|
1560 |
Debug.WriteLine(" Returned handle: " + _hidHandle);
|
sl@0
|
1561 |
|
sl@0
|
1562 |
if (!_hidHandle.IsInvalid)
|
sl@0
|
1563 |
{
|
sl@2
|
1564 |
// The returned handle is valid,
|
sl@0
|
1565 |
// so find out if this is the device we're looking for.
|
sl@0
|
1566 |
|
sl@0
|
1567 |
_myHid.DeviceAttributes.Size = Marshal.SizeOf(_myHid.DeviceAttributes);
|
sl@0
|
1568 |
|
sl@0
|
1569 |
Boolean success = _myHid.GetAttributes(_hidHandle, ref _myHid.DeviceAttributes);
|
sl@0
|
1570 |
|
sl@0
|
1571 |
if (success)
|
sl@0
|
1572 |
{
|
sl@0
|
1573 |
Debug.WriteLine(" HIDD_ATTRIBUTES structure filled without error.");
|
sl@0
|
1574 |
Debug.WriteLine(" Structure size: " + _myHid.DeviceAttributes.Size);
|
sl@0
|
1575 |
Debug.WriteLine(" Vendor ID: " + Convert.ToString(_myHid.DeviceAttributes.VendorID, 16));
|
sl@0
|
1576 |
Debug.WriteLine(" Product ID: " + Convert.ToString(_myHid.DeviceAttributes.ProductID, 16));
|
sl@0
|
1577 |
Debug.WriteLine(" Version Number: " + Convert.ToString(_myHid.DeviceAttributes.VersionNumber, 16));
|
sl@0
|
1578 |
|
sl@0
|
1579 |
if ((_myHid.DeviceAttributes.VendorID == _myVendorId) && (_myHid.DeviceAttributes.ProductID == _myProductId))
|
sl@0
|
1580 |
{
|
sl@0
|
1581 |
Debug.WriteLine(" Handle obtained to my device");
|
sl@0
|
1582 |
|
sl@0
|
1583 |
// Display the information in form's list box.
|
sl@0
|
1584 |
|
sl@0
|
1585 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "Handle obtained to my device:");
|
sl@0
|
1586 |
MyMarshalDataToForm(FormActions.AddItemToListBox, " Vendor ID= " + Convert.ToString(_myHid.DeviceAttributes.VendorID, 16));
|
sl@0
|
1587 |
MyMarshalDataToForm(FormActions.AddItemToListBox, " Product ID = " + Convert.ToString(_myHid.DeviceAttributes.ProductID, 16));
|
sl@0
|
1588 |
MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
|
sl@0
|
1589 |
|
sl@0
|
1590 |
_deviceHandleObtained = true;
|
sl@0
|
1591 |
|
sl@0
|
1592 |
myDevicePathName = devicePathName[memberIndex];
|
sl@0
|
1593 |
}
|
sl@0
|
1594 |
else
|
sl@0
|
1595 |
{
|
sl@0
|
1596 |
// It's not a match, so close the handle.
|
sl@0
|
1597 |
|
sl@0
|
1598 |
_deviceHandleObtained = false;
|
sl@0
|
1599 |
_hidHandle.Close();
|
sl@0
|
1600 |
}
|
sl@0
|
1601 |
}
|
sl@0
|
1602 |
else
|
sl@0
|
1603 |
{
|
sl@0
|
1604 |
// There was a problem retrieving the information.
|
sl@0
|
1605 |
|
sl@0
|
1606 |
Debug.WriteLine(" Error in filling HIDD_ATTRIBUTES structure.");
|
sl@0
|
1607 |
_deviceHandleObtained = false;
|
sl@0
|
1608 |
_hidHandle.Close();
|
sl@0
|
1609 |
}
|
sl@0
|
1610 |
}
|
sl@0
|
1611 |
|
sl@0
|
1612 |
// Keep looking until we find the device or there are no devices left to examine.
|
sl@0
|
1613 |
|
sl@0
|
1614 |
memberIndex = memberIndex + 1;
|
sl@0
|
1615 |
}
|
sl@0
|
1616 |
while (!((_deviceHandleObtained || (memberIndex == devicePathName.Length))));
|
sl@0
|
1617 |
}
|
sl@0
|
1618 |
|
sl@0
|
1619 |
if (_deviceHandleObtained)
|
sl@0
|
1620 |
{
|
sl@0
|
1621 |
// The device was detected.
|
sl@0
|
1622 |
// Learn the capabilities of the device.
|
sl@0
|
1623 |
|
sl@0
|
1624 |
_myHid.Capabilities = _myHid.GetDeviceCapabilities(_hidHandle);
|
sl@0
|
1625 |
|
sl@0
|
1626 |
// Find out if the device is a system mouse or keyboard.
|
sl@0
|
1627 |
|
sl@0
|
1628 |
_hidUsage = _myHid.GetHidUsage(_myHid.Capabilities);
|
sl@0
|
1629 |
|
sl@0
|
1630 |
// Get the Input report buffer size.
|
sl@0
|
1631 |
|
sl@0
|
1632 |
GetInputReportBufferSize();
|
sl@0
|
1633 |
MyMarshalDataToForm(FormActions.EnableInputReportBufferSize, "");
|
sl@0
|
1634 |
|
sl@0
|
1635 |
//Close the handle and reopen it with read/write access.
|
sl@0
|
1636 |
|
sl@0
|
1637 |
_hidHandle.Close();
|
sl@0
|
1638 |
|
sl@0
|
1639 |
_hidHandle = _myHid.OpenHandle(myDevicePathName, true);
|
sl@0
|
1640 |
|
sl@0
|
1641 |
if (_hidHandle.IsInvalid)
|
sl@0
|
1642 |
{
|
sl@0
|
1643 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "The device is a system " + _hidUsage + ".");
|
sl@0
|
1644 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "Windows 2000 and later obtain exclusive access to Input and Output reports for this devices.");
|
sl@0
|
1645 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "Windows 8 also obtains exclusive access to Feature reports.");
|
sl@0
|
1646 |
MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
|
sl@0
|
1647 |
}
|
sl@0
|
1648 |
else
|
sl@0
|
1649 |
{
|
sl@0
|
1650 |
if (_myHid.Capabilities.InputReportByteLength > 0)
|
sl@0
|
1651 |
{
|
sl@2
|
1652 |
// Set the size of the Input report buffer.
|
sl@0
|
1653 |
|
sl@0
|
1654 |
var inputReportBuffer = new Byte[_myHid.Capabilities.InputReportByteLength];
|
sl@0
|
1655 |
|
sl@0
|
1656 |
_deviceData = new FileStream(_hidHandle, FileAccess.Read | FileAccess.Write, inputReportBuffer.Length, false);
|
sl@0
|
1657 |
}
|
sl@0
|
1658 |
|
sl@0
|
1659 |
if (_myHid.Capabilities.OutputReportByteLength > 0)
|
sl@0
|
1660 |
{
|
sl@0
|
1661 |
Byte[] outputReportBuffer = null;
|
sl@0
|
1662 |
}
|
sl@0
|
1663 |
// Flush any waiting reports in the input buffer. (optional)
|
sl@0
|
1664 |
|
sl@0
|
1665 |
_myHid.FlushQueue(_hidHandle);
|
sl@0
|
1666 |
}
|
sl@0
|
1667 |
}
|
sl@0
|
1668 |
else
|
sl@0
|
1669 |
{
|
sl@0
|
1670 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "Device not found.");
|
sl@0
|
1671 |
MyMarshalDataToForm(FormActions.DisableInputReportBufferSize, "");
|
sl@0
|
1672 |
EnableFormControls();
|
sl@0
|
1673 |
MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
|
sl@0
|
1674 |
}
|
sl@0
|
1675 |
return _deviceHandleObtained;
|
sl@0
|
1676 |
}
|
sl@0
|
1677 |
catch (Exception ex)
|
sl@0
|
1678 |
{
|
sl@0
|
1679 |
DisplayException(Name, ex);
|
sl@0
|
1680 |
throw;
|
sl@0
|
1681 |
}
|
sl@0
|
1682 |
}
|
sl@0
|
1683 |
|
sl@0
|
1684 |
/// <summary>
|
sl@0
|
1685 |
/// Perform shutdown operations.
|
sl@0
|
1686 |
/// </summary>
|
sl@0
|
1687 |
|
sl@0
|
1688 |
private void frmMain_Closed(Object eventSender, EventArgs eventArgs)
|
sl@0
|
1689 |
{
|
sl@0
|
1690 |
try
|
sl@0
|
1691 |
{
|
sl@0
|
1692 |
Shutdown();
|
sl@0
|
1693 |
}
|
sl@0
|
1694 |
catch (Exception ex)
|
sl@0
|
1695 |
{
|
sl@0
|
1696 |
DisplayException(Name, ex);
|
sl@0
|
1697 |
throw;
|
sl@0
|
1698 |
}
|
sl@0
|
1699 |
}
|
sl@0
|
1700 |
|
sl@0
|
1701 |
/// <summary>
|
sl@0
|
1702 |
/// Perform startup operations.
|
sl@0
|
1703 |
/// </summary>
|
sl@0
|
1704 |
|
sl@0
|
1705 |
private void frmMain_Load(Object eventSender, EventArgs eventArgs)
|
sl@0
|
1706 |
{
|
sl@0
|
1707 |
try
|
sl@0
|
1708 |
{
|
sl@0
|
1709 |
FrmMy = this;
|
sl@0
|
1710 |
Startup();
|
sl@0
|
1711 |
}
|
sl@0
|
1712 |
catch (Exception ex)
|
sl@0
|
1713 |
{
|
sl@0
|
1714 |
DisplayException(Name, ex);
|
sl@0
|
1715 |
throw;
|
sl@0
|
1716 |
}
|
sl@0
|
1717 |
}
|
sl@0
|
1718 |
|
sl@0
|
1719 |
private void GetBytesToSend()
|
sl@0
|
1720 |
{
|
sl@0
|
1721 |
try
|
sl@0
|
1722 |
{
|
sl@0
|
1723 |
// Get the bytes to send in a report from the combo boxes.
|
sl@0
|
1724 |
// Increment the values if the autoincrement check box is selected.
|
sl@0
|
1725 |
|
sl@0
|
1726 |
if (ChkAutoincrement.Checked)
|
sl@0
|
1727 |
{
|
sl@0
|
1728 |
if (CboByte0.SelectedIndex < 255)
|
sl@0
|
1729 |
{
|
sl@0
|
1730 |
CboByte0.SelectedIndex = CboByte0.SelectedIndex + 1;
|
sl@0
|
1731 |
}
|
sl@0
|
1732 |
else
|
sl@0
|
1733 |
{
|
sl@0
|
1734 |
CboByte0.SelectedIndex = 0;
|
sl@0
|
1735 |
}
|
sl@0
|
1736 |
if (CboByte1.SelectedIndex < 255)
|
sl@0
|
1737 |
{
|
sl@0
|
1738 |
CboByte1.SelectedIndex = CboByte1.SelectedIndex + 1;
|
sl@0
|
1739 |
}
|
sl@0
|
1740 |
else
|
sl@0
|
1741 |
{
|
sl@0
|
1742 |
CboByte1.SelectedIndex = 0;
|
sl@0
|
1743 |
}
|
sl@0
|
1744 |
}
|
sl@0
|
1745 |
}
|
sl@0
|
1746 |
catch (Exception ex)
|
sl@0
|
1747 |
{
|
sl@0
|
1748 |
DisplayException(Name, ex);
|
sl@0
|
1749 |
throw;
|
sl@0
|
1750 |
}
|
sl@0
|
1751 |
}
|
sl@0
|
1752 |
|
sl@0
|
1753 |
/// <summary>
|
sl@0
|
1754 |
/// Find and display the number of Input buffers
|
sl@2
|
1755 |
/// (the number of Input reports the HID driver will store).
|
sl@0
|
1756 |
/// </summary>
|
sl@0
|
1757 |
|
sl@0
|
1758 |
private void GetInputReportBufferSize()
|
sl@0
|
1759 |
{
|
sl@0
|
1760 |
Int32 numberOfInputBuffers = 0;
|
sl@0
|
1761 |
Boolean success;
|
sl@0
|
1762 |
|
sl@0
|
1763 |
try
|
sl@0
|
1764 |
{
|
sl@0
|
1765 |
// Get the number of input buffers.
|
sl@0
|
1766 |
|
sl@0
|
1767 |
_myHid.GetNumberOfInputBuffers(_hidHandle, ref numberOfInputBuffers);
|
sl@0
|
1768 |
|
sl@0
|
1769 |
// Display the result in the text box.
|
sl@0
|
1770 |
|
sl@0
|
1771 |
MyMarshalDataToForm(FormActions.SetInputReportBufferSize, Convert.ToString(numberOfInputBuffers));
|
sl@0
|
1772 |
}
|
sl@0
|
1773 |
catch (Exception ex)
|
sl@0
|
1774 |
{
|
sl@0
|
1775 |
DisplayException(Name, ex);
|
sl@0
|
1776 |
throw;
|
sl@0
|
1777 |
}
|
sl@0
|
1778 |
}
|
sl@0
|
1779 |
|
sl@0
|
1780 |
/// <summary>
|
sl@2
|
1781 |
/// Retrieve a Vendor ID and Product ID in hexadecimal
|
sl@0
|
1782 |
/// from the form's text boxes and convert the text to Int32s.
|
sl@0
|
1783 |
/// </summary>
|
sl@2
|
1784 |
///
|
sl@0
|
1785 |
/// <param name="myVendorId"> the Vendor ID</param>
|
sl@0
|
1786 |
/// <param name="myProductId"> the Product ID</param>
|
sl@0
|
1787 |
|
sl@0
|
1788 |
private void GetVendorAndProductIDsFromTextBoxes(ref Int32 myVendorId, ref Int32 myProductId)
|
sl@0
|
1789 |
{
|
sl@0
|
1790 |
try
|
sl@0
|
1791 |
{
|
sl@0
|
1792 |
myVendorId = Int32.Parse(txtVendorID.Text, NumberStyles.AllowHexSpecifier);
|
sl@0
|
1793 |
myProductId = Int32.Parse(txtProductID.Text, NumberStyles.AllowHexSpecifier);
|
sl@0
|
1794 |
}
|
sl@0
|
1795 |
catch (Exception ex)
|
sl@0
|
1796 |
{
|
sl@0
|
1797 |
DisplayException(Name, ex);
|
sl@0
|
1798 |
throw;
|
sl@0
|
1799 |
}
|
sl@0
|
1800 |
}
|
sl@0
|
1801 |
|
sl@0
|
1802 |
/// <summary>
|
sl@0
|
1803 |
/// Initialize the elements on the form.
|
sl@0
|
1804 |
/// </summary>
|
sl@0
|
1805 |
|
sl@0
|
1806 |
private void InitializeDisplay()
|
sl@0
|
1807 |
{
|
sl@0
|
1808 |
try
|
sl@0
|
1809 |
{
|
sl@0
|
1810 |
// Create a dropdown list box for each byte to send in a report.
|
sl@0
|
1811 |
// Display the values as 2-character hex strings.
|
sl@0
|
1812 |
|
sl@0
|
1813 |
Int16 count;
|
sl@0
|
1814 |
for (count = 0; count <= 255; count++)
|
sl@0
|
1815 |
{
|
sl@0
|
1816 |
String byteValue = String.Format("{0:X2} ", count);
|
sl@0
|
1817 |
FrmMy.CboByte0.Items.Insert(count, byteValue);
|
sl@0
|
1818 |
FrmMy.CboByte1.Items.Insert(count, byteValue);
|
sl@0
|
1819 |
}
|
sl@0
|
1820 |
|
sl@0
|
1821 |
// Select a default value for each box
|
sl@0
|
1822 |
|
sl@0
|
1823 |
FrmMy.CboByte0.SelectedIndex = 0;
|
sl@0
|
1824 |
FrmMy.CboByte1.SelectedIndex = 128;
|
sl@0
|
1825 |
FrmMy.radInputOutputInterrupt.Checked = true;
|
sl@0
|
1826 |
|
sl@0
|
1827 |
// Check the autoincrement box to increment the values each time a report is sent.
|
sl@0
|
1828 |
|
sl@0
|
1829 |
ChkAutoincrement.CheckState = CheckState.Checked;
|
sl@0
|
1830 |
|
sl@0
|
1831 |
// Don't allow the user to select an input report buffer size until there is
|
sl@0
|
1832 |
// a handle to a HID.
|
sl@0
|
1833 |
|
sl@0
|
1834 |
cmdInputReportBufferSize.Focus();
|
sl@0
|
1835 |
cmdInputReportBufferSize.Enabled = false;
|
sl@0
|
1836 |
|
sl@0
|
1837 |
LstResults.Items.Add("For a more detailed event log, view debug statements in Visual Studio's Output window:");
|
sl@0
|
1838 |
LstResults.Items.Add("Click Build > Configuration Manager > Active Solution Configuration > Debug > Close.");
|
sl@0
|
1839 |
LstResults.Items.Add("Then click View > Output.");
|
sl@0
|
1840 |
LstResults.Items.Add("");
|
sl@0
|
1841 |
}
|
sl@0
|
1842 |
catch (Exception ex)
|
sl@0
|
1843 |
{
|
sl@0
|
1844 |
DisplayException(Name, ex);
|
sl@0
|
1845 |
throw;
|
sl@0
|
1846 |
}
|
sl@0
|
1847 |
}
|
sl@0
|
1848 |
|
sl@0
|
1849 |
/// <summary>
|
sl@2
|
1850 |
/// Enables accessing a form's controls from another thread
|
sl@0
|
1851 |
/// </summary>
|
sl@2
|
1852 |
///
|
sl@0
|
1853 |
/// <param name="action"> a FormActions member that names the action to perform on the form </param>
|
sl@2
|
1854 |
/// <param name="textToDisplay"> text that the form displays or the code uses for
|
sl@0
|
1855 |
/// another purpose. Actions that don't use text ignore this parameter. </param>
|
sl@0
|
1856 |
|
sl@3
|
1857 |
private void MyMarshalDataToForm(FormActions action, params string[] strings)
|
sl@0
|
1858 |
{
|
sl@0
|
1859 |
try
|
sl@0
|
1860 |
{
|
sl@3
|
1861 |
object[] args = { action, strings };
|
sl@0
|
1862 |
|
sl@0
|
1863 |
// The AccessForm routine contains the code that accesses the form.
|
sl@0
|
1864 |
|
sl@0
|
1865 |
MarshalDataToForm marshalDataToFormDelegate = AccessForm;
|
sl@0
|
1866 |
|
sl@0
|
1867 |
// Execute AccessForm, passing the parameters in args.
|
sl@0
|
1868 |
|
sl@0
|
1869 |
Invoke(marshalDataToFormDelegate, args);
|
sl@0
|
1870 |
}
|
sl@0
|
1871 |
catch (Exception ex)
|
sl@0
|
1872 |
{
|
sl@0
|
1873 |
DisplayException(Name, ex);
|
sl@0
|
1874 |
throw;
|
sl@0
|
1875 |
}
|
sl@0
|
1876 |
}
|
sl@0
|
1877 |
|
sl@0
|
1878 |
/// <summary>
|
sl@0
|
1879 |
/// Timeout if read via interrupt transfer doesn't return.
|
sl@0
|
1880 |
/// </summary>
|
sl@0
|
1881 |
|
sl@0
|
1882 |
private void OnReadTimeout()
|
sl@0
|
1883 |
{
|
sl@0
|
1884 |
try
|
sl@0
|
1885 |
{
|
sl@0
|
1886 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "The attempt to read a report timed out.");
|
sl@0
|
1887 |
MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
|
sl@0
|
1888 |
CloseCommunications();
|
sl@0
|
1889 |
MyMarshalDataToForm(FormActions.EnableGetInputReportInterruptTransfer, "");
|
sl@0
|
1890 |
_transferInProgress = false;
|
sl@0
|
1891 |
_sendOrGet = SendOrGet.Send;
|
sl@0
|
1892 |
}
|
sl@0
|
1893 |
catch (Exception ex)
|
sl@0
|
1894 |
{
|
sl@0
|
1895 |
DisplayException(Name, ex);
|
sl@0
|
1896 |
throw;
|
sl@0
|
1897 |
}
|
sl@0
|
1898 |
}
|
sl@0
|
1899 |
|
sl@0
|
1900 |
/// <summary>
|
sl@0
|
1901 |
/// Timeout if write via interrupt transfer doesn't return.
|
sl@0
|
1902 |
/// </summary>
|
sl@0
|
1903 |
|
sl@0
|
1904 |
private void OnWriteTimeout()
|
sl@0
|
1905 |
{
|
sl@0
|
1906 |
try
|
sl@0
|
1907 |
{
|
sl@0
|
1908 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "The attempt to write a report timed out.");
|
sl@0
|
1909 |
MyMarshalDataToForm(FormActions.ScrollToBottomOfListBox, "");
|
sl@0
|
1910 |
CloseCommunications();
|
sl@0
|
1911 |
MyMarshalDataToForm(FormActions.EnableSendOutputReportInterrupt, "");
|
sl@0
|
1912 |
_transferInProgress = false;
|
sl@0
|
1913 |
_sendOrGet = SendOrGet.Get;
|
sl@0
|
1914 |
}
|
sl@0
|
1915 |
catch (Exception ex)
|
sl@0
|
1916 |
{
|
sl@0
|
1917 |
DisplayException(Name, ex);
|
sl@0
|
1918 |
throw;
|
sl@0
|
1919 |
}
|
sl@0
|
1920 |
}
|
sl@0
|
1921 |
|
sl@0
|
1922 |
/// <summary>
|
sl@0
|
1923 |
/// Alternat sending and getting a report.
|
sl@0
|
1924 |
/// </summary>
|
sl@0
|
1925 |
|
sl@0
|
1926 |
private void PeriodicTransfers()
|
sl@0
|
1927 |
{
|
sl@0
|
1928 |
try
|
sl@0
|
1929 |
{
|
sl@0
|
1930 |
if (!_transferInProgress)
|
sl@0
|
1931 |
{
|
sl@0
|
1932 |
if (_reportType == ReportTypes.Feature)
|
sl@0
|
1933 |
{
|
sl@0
|
1934 |
SendOrGetFeatureReport();
|
sl@0
|
1935 |
}
|
sl@0
|
1936 |
else
|
sl@0
|
1937 |
{
|
sl@0
|
1938 |
// Output and Input reports
|
sl@0
|
1939 |
|
sl@0
|
1940 |
SendOutputReportOrGetInputReport();
|
sl@0
|
1941 |
}
|
sl@0
|
1942 |
}
|
sl@0
|
1943 |
}
|
sl@0
|
1944 |
catch (Exception ex)
|
sl@0
|
1945 |
{
|
sl@0
|
1946 |
DisplayException(Name, ex);
|
sl@0
|
1947 |
throw;
|
sl@0
|
1948 |
}
|
sl@0
|
1949 |
}
|
sl@0
|
1950 |
|
sl@0
|
1951 |
/// <summary>
|
sl@0
|
1952 |
/// Start doing periodic transfers.
|
sl@0
|
1953 |
/// </summary>
|
sl@0
|
1954 |
|
sl@0
|
1955 |
private void PeriodicTransfersStart()
|
sl@0
|
1956 |
{
|
sl@0
|
1957 |
// Don't allow changing the transfer type while transfers are in progress.
|
sl@0
|
1958 |
|
sl@0
|
1959 |
if (radFeature.Checked)
|
sl@0
|
1960 |
{
|
sl@0
|
1961 |
radInputOutputControl.Enabled = false;
|
sl@0
|
1962 |
radInputOutputInterrupt.Enabled = false;
|
sl@0
|
1963 |
}
|
sl@0
|
1964 |
else if (radInputOutputControl.Checked)
|
sl@0
|
1965 |
{
|
sl@0
|
1966 |
radFeature.Enabled = false;
|
sl@0
|
1967 |
radInputOutputInterrupt.Enabled = false;
|
sl@0
|
1968 |
}
|
sl@0
|
1969 |
else if (radInputOutputInterrupt.Checked)
|
sl@0
|
1970 |
{
|
sl@0
|
1971 |
radFeature.Enabled = false;
|
sl@0
|
1972 |
radInputOutputControl.Enabled = false;
|
sl@0
|
1973 |
}
|
sl@0
|
1974 |
|
sl@0
|
1975 |
// Change the command button's text.
|
sl@0
|
1976 |
|
sl@0
|
1977 |
cmdPeriodicTransfers.Text = "Stop";
|
sl@0
|
1978 |
|
sl@0
|
1979 |
// Enable the timer event to trigger a set of transfers.
|
sl@0
|
1980 |
|
sl@0
|
1981 |
_periodicTransfers.Start();
|
sl@0
|
1982 |
|
sl@0
|
1983 |
cmdPeriodicTransfers.Enabled = true;
|
sl@0
|
1984 |
|
sl@0
|
1985 |
if (radInputOutputInterrupt.Checked)
|
sl@0
|
1986 |
{
|
sl@0
|
1987 |
_transferType = TransferTypes.Interrupt;
|
sl@0
|
1988 |
_reportType = ReportTypes.Output;
|
sl@0
|
1989 |
}
|
sl@0
|
1990 |
else if (radInputOutputControl.Checked)
|
sl@0
|
1991 |
{
|
sl@0
|
1992 |
_transferType = TransferTypes.Control;
|
sl@0
|
1993 |
_reportType = ReportTypes.Output;
|
sl@0
|
1994 |
}
|
sl@0
|
1995 |
else if (radFeature.Checked)
|
sl@0
|
1996 |
{
|
sl@0
|
1997 |
_transferType = TransferTypes.Control;
|
sl@0
|
1998 |
_reportType = ReportTypes.Feature;
|
sl@0
|
1999 |
}
|
sl@0
|
2000 |
_periodicTransfersRequested = true;
|
sl@0
|
2001 |
PeriodicTransfers();
|
sl@0
|
2002 |
}
|
sl@0
|
2003 |
|
sl@0
|
2004 |
/// <summary>
|
sl@0
|
2005 |
/// Stop doing periodic transfers.
|
sl@0
|
2006 |
/// </summary>
|
sl@0
|
2007 |
|
sl@0
|
2008 |
private void PeriodicTransfersStop()
|
sl@0
|
2009 |
{
|
sl@0
|
2010 |
// Stop doing continuous transfers.
|
sl@0
|
2011 |
|
sl@0
|
2012 |
_periodicTransfersRequested = false;
|
sl@0
|
2013 |
|
sl@2
|
2014 |
// Disable the timer that triggers the transfers.
|
sl@0
|
2015 |
|
sl@0
|
2016 |
_periodicTransfers.Stop();
|
sl@0
|
2017 |
cmdPeriodicTransfers.Enabled = true;
|
sl@0
|
2018 |
|
sl@0
|
2019 |
// Change the command button's text.
|
sl@0
|
2020 |
|
sl@0
|
2021 |
cmdPeriodicTransfers.Text = "Start";
|
sl@0
|
2022 |
|
sl@0
|
2023 |
// Re-allow changing the transfer type.
|
sl@0
|
2024 |
|
sl@0
|
2025 |
radFeature.Enabled = true;
|
sl@0
|
2026 |
radInputOutputControl.Enabled = true;
|
sl@0
|
2027 |
radInputOutputInterrupt.Enabled = true;
|
sl@0
|
2028 |
}
|
sl@0
|
2029 |
|
sl@0
|
2030 |
private void radInputOutputControl_CheckedChanged(object sender, EventArgs e)
|
sl@0
|
2031 |
{
|
sl@0
|
2032 |
}
|
sl@0
|
2033 |
|
sl@0
|
2034 |
private void radInputOutputInterrupt_CheckedChanged(object sender, EventArgs e)
|
sl@0
|
2035 |
{
|
sl@0
|
2036 |
}
|
sl@0
|
2037 |
|
sl@0
|
2038 |
private void radFeature_CheckedChanged(object sender, EventArgs e)
|
sl@0
|
2039 |
{
|
sl@0
|
2040 |
}
|
sl@0
|
2041 |
|
sl@0
|
2042 |
/// <summary>
|
sl@0
|
2043 |
/// Request a Feature report.
|
sl@0
|
2044 |
/// Assumes report ID = 0.
|
sl@0
|
2045 |
/// </summary>
|
sl@0
|
2046 |
|
sl@0
|
2047 |
private void RequestToGetFeatureReport()
|
sl@0
|
2048 |
{
|
sl@0
|
2049 |
String byteValue = null;
|
sl@0
|
2050 |
|
sl@0
|
2051 |
try
|
sl@0
|
2052 |
{
|
sl@0
|
2053 |
// If the device hasn't been detected, was removed, or timed out on a previous attempt
|
sl@0
|
2054 |
// to access it, look for the device.
|
sl@0
|
2055 |
|
sl@0
|
2056 |
if (!_deviceHandleObtained)
|
sl@0
|
2057 |
{
|
sl@0
|
2058 |
_deviceHandleObtained = FindTheHid();
|
sl@0
|
2059 |
}
|
sl@0
|
2060 |
|
sl@0
|
2061 |
if (_deviceHandleObtained)
|
sl@0
|
2062 |
{
|
sl@0
|
2063 |
Byte[] inFeatureReportBuffer = null;
|
sl@0
|
2064 |
|
sl@0
|
2065 |
if ((_myHid.Capabilities.FeatureReportByteLength > 0))
|
sl@0
|
2066 |
{
|
sl@2
|
2067 |
// The HID has a Feature report.
|
sl@0
|
2068 |
// Read a report from the device.
|
sl@0
|
2069 |
|
sl@2
|
2070 |
// Set the size of the Feature report buffer.
|
sl@0
|
2071 |
|
sl@0
|
2072 |
if ((_myHid.Capabilities.FeatureReportByteLength > 0))
|
sl@0
|
2073 |
{
|
sl@0
|
2074 |
inFeatureReportBuffer = new Byte[_myHid.Capabilities.FeatureReportByteLength];
|
sl@0
|
2075 |
}
|
sl@0
|
2076 |
|
sl@0
|
2077 |
// Read a report.
|
sl@0
|
2078 |
|
sl@0
|
2079 |
Boolean success = _myHid.GetFeatureReport(_hidHandle, ref inFeatureReportBuffer);
|
sl@0
|
2080 |
|
sl@0
|
2081 |
if (success)
|
sl@0
|
2082 |
{
|
sl@0
|
2083 |
DisplayReportData(inFeatureReportBuffer, ReportTypes.Feature, ReportReadOrWritten.Read);
|
sl@0
|
2084 |
}
|
sl@0
|
2085 |
else
|
sl@0
|
2086 |
{
|
sl@0
|
2087 |
CloseCommunications();
|
sl@0
|
2088 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "The attempt to read a Feature report failed.");
|
sl@0
|
2089 |
ScrollToBottomOfListBox();
|
sl@0
|
2090 |
}
|
sl@0
|
2091 |
}
|
sl@0
|
2092 |
else
|
sl@0
|
2093 |
{
|
sl@0
|
2094 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "The HID doesn't have a Feature report.");
|
sl@0
|
2095 |
ScrollToBottomOfListBox();
|
sl@0
|
2096 |
}
|
sl@0
|
2097 |
}
|
sl@0
|
2098 |
_transferInProgress = false;
|
sl@0
|
2099 |
cmdGetFeatureReport.Enabled = true;
|
sl@0
|
2100 |
}
|
sl@0
|
2101 |
catch (Exception ex)
|
sl@0
|
2102 |
{
|
sl@0
|
2103 |
DisplayException(Name, ex);
|
sl@0
|
2104 |
throw;
|
sl@0
|
2105 |
}
|
sl@0
|
2106 |
}
|
sl@0
|
2107 |
|
sl@0
|
2108 |
/// <summary>
|
sl@0
|
2109 |
/// Request an Input report.
|
sl@0
|
2110 |
/// Assumes report ID = 0.
|
sl@0
|
2111 |
/// </summary>
|
sl@0
|
2112 |
|
sl@0
|
2113 |
private async void RequestToGetInputReport()
|
sl@0
|
2114 |
{
|
sl@0
|
2115 |
const Int32 readTimeout = 5000;
|
sl@0
|
2116 |
|
sl@0
|
2117 |
String byteValue = null;
|
sl@0
|
2118 |
Byte[] inputReportBuffer = null;
|
sl@0
|
2119 |
|
sl@0
|
2120 |
try
|
sl@0
|
2121 |
{
|
sl@0
|
2122 |
Boolean success = false;
|
sl@0
|
2123 |
|
sl@0
|
2124 |
// If the device hasn't been detected, was removed, or timed out on a previous attempt
|
sl@0
|
2125 |
// to access it, look for the device.
|
sl@0
|
2126 |
|
sl@0
|
2127 |
if (!_deviceHandleObtained)
|
sl@0
|
2128 |
{
|
sl@0
|
2129 |
_deviceHandleObtained = FindTheHid();
|
sl@0
|
2130 |
}
|
sl@0
|
2131 |
|
sl@0
|
2132 |
if (_deviceHandleObtained)
|
sl@0
|
2133 |
{
|
sl@0
|
2134 |
// Don't attempt to exchange reports if valid handles aren't available
|
sl@0
|
2135 |
// (as for a mouse or keyboard under Windows 2000 and later.)
|
sl@0
|
2136 |
|
sl@0
|
2137 |
if (!_hidHandle.IsInvalid)
|
sl@0
|
2138 |
{
|
sl@0
|
2139 |
// Read an Input report.
|
sl@0
|
2140 |
|
sl@0
|
2141 |
// Don't attempt to send an Input report if the HID has no Input report.
|
sl@0
|
2142 |
// (The HID spec requires all HIDs to have an interrupt IN endpoint,
|
sl@0
|
2143 |
// which suggests that all HIDs must support Input reports.)
|
sl@0
|
2144 |
|
sl@0
|
2145 |
if (_myHid.Capabilities.InputReportByteLength > 0)
|
sl@0
|
2146 |
{
|
sl@2
|
2147 |
// Set the size of the Input report buffer.
|
sl@0
|
2148 |
|
sl@0
|
2149 |
inputReportBuffer = new Byte[_myHid.Capabilities.InputReportByteLength];
|
sl@0
|
2150 |
|
sl@0
|
2151 |
if (_transferType.Equals(TransferTypes.Control))
|
sl@0
|
2152 |
{
|
sl@0
|
2153 |
{
|
sl@0
|
2154 |
_transferInProgress = true;
|
sl@0
|
2155 |
|
sl@0
|
2156 |
// Read a report using a control transfer.
|
sl@0
|
2157 |
|
sl@0
|
2158 |
success = _myHid.GetInputReportViaControlTransfer(_hidHandle, ref inputReportBuffer);
|
sl@0
|
2159 |
cmdGetInputReportControl.Enabled = true;
|
sl@0
|
2160 |
_transferInProgress = false;
|
sl@0
|
2161 |
}
|
sl@0
|
2162 |
}
|
sl@0
|
2163 |
else
|
sl@0
|
2164 |
{
|
sl@0
|
2165 |
{
|
sl@0
|
2166 |
_transferInProgress = true;
|
sl@0
|
2167 |
|
sl@2
|
2168 |
// Read a report using interrupt transfers.
|
sl@0
|
2169 |
// Timeout if no report available.
|
sl@2
|
2170 |
// To enable reading a report without blocking the calling thread, uses Filestream's ReadAsync method.
|
sl@0
|
2171 |
|
sl@0
|
2172 |
// Create a delegate to execute on a timeout.
|
sl@0
|
2173 |
|
sl@0
|
2174 |
Action onReadTimeoutAction = OnReadTimeout;
|
sl@0
|
2175 |
|
sl@0
|
2176 |
// The CancellationTokenSource specifies the timeout value and the action to take on a timeout.
|
sl@0
|
2177 |
|
sl@0
|
2178 |
var cts = new CancellationTokenSource();
|
sl@0
|
2179 |
|
sl@0
|
2180 |
// Cancel the read if it hasn't completed after a timeout.
|
sl@0
|
2181 |
|
sl@0
|
2182 |
cts.CancelAfter(readTimeout);
|
sl@0
|
2183 |
|
sl@0
|
2184 |
// Specify the function to call on a timeout.
|
sl@0
|
2185 |
|
sl@0
|
2186 |
cts.Token.Register(onReadTimeoutAction);
|
sl@0
|
2187 |
|
sl@0
|
2188 |
// Stops waiting when data is available or on timeout:
|
sl@0
|
2189 |
|
sl@0
|
2190 |
Int32 bytesRead = await _myHid.GetInputReportViaInterruptTransfer(_deviceData, inputReportBuffer, cts);
|
sl@0
|
2191 |
|
sl@0
|
2192 |
// Arrive here only if the operation completed.
|
sl@0
|
2193 |
|
sl@2
|
2194 |
// Dispose to stop the timeout timer.
|
sl@0
|
2195 |
|
sl@0
|
2196 |
cts.Dispose();
|
sl@0
|
2197 |
|
sl@0
|
2198 |
_transferInProgress = false;
|
sl@0
|
2199 |
cmdGetInputReportInterrupt.Enabled = true;
|
sl@0
|
2200 |
|
sl@0
|
2201 |
if (bytesRead > 0)
|
sl@0
|
2202 |
{
|
sl@0
|
2203 |
success = true;
|
sl@0
|
2204 |
Debug.Print("bytes read (includes report ID) = " + Convert.ToString(bytesRead));
|
sl@0
|
2205 |
}
|
sl@0
|
2206 |
}
|
sl@0
|
2207 |
}
|
sl@0
|
2208 |
}
|
sl@0
|
2209 |
else
|
sl@0
|
2210 |
{
|
sl@0
|
2211 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "No attempt to read an Input report was made.");
|
sl@0
|
2212 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "The HID doesn't have an Input report.");
|
sl@0
|
2213 |
}
|
sl@0
|
2214 |
}
|
sl@0
|
2215 |
else
|
sl@0
|
2216 |
{
|
sl@0
|
2217 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "Invalid handle.");
|
sl@0
|
2218 |
MyMarshalDataToForm(FormActions.AddItemToListBox,
|
sl@0
|
2219 |
"No attempt to write an Output report or read an Input report was made.");
|
sl@0
|
2220 |
}
|
sl@0
|
2221 |
|
sl@0
|
2222 |
if (success)
|
sl@0
|
2223 |
{
|
sl@0
|
2224 |
DisplayReportData(inputReportBuffer, ReportTypes.Input, ReportReadOrWritten.Read);
|
sl@0
|
2225 |
}
|
sl@0
|
2226 |
else
|
sl@0
|
2227 |
{
|
sl@0
|
2228 |
CloseCommunications();
|
sl@0
|
2229 |
MyMarshalDataToForm(FormActions.AddItemToListBox, "The attempt to read an Input report has failed.");
|
sl@0
|
2230 |
ScrollToBottomOfListBox();
|
sl@0
|
2231 |
}
|
sl@0
|
2232 |
}
|
sl@0
|
2233 |
}
|
sl@0
|
2234 |
catch (Exception ex)
|
sl@0
|
2235 |
{
|
sl@0
|
2236 |
DisplayException(Name, ex);
|
sl@0
|
2237 |
throw;
|
sl@0
|
2238 |
}
|
sl@0
|
2239 |
}
|
sl@0
|
2240 |
|
sl@0
|
2241 |
/// <summary>
|
sl@0
|
2242 |
/// Sends a Feature report.
|
sl@0
|
2243 |
/// Assumes report ID = 0.
|
sl@0
|
2244 |
/// </summary>
|
sl@0
|
2245 |
|
sl@0
|
2246 |
private void RequestToSendFeatureReport()
|
sl@0
|
2247 |
{
|
sl@0
|
2248 |
String byteValue = null;
|
sl@0
|
2249 |
|
sl@0
|
2250 |
try
|
sl@0
|
2251 |
{
|
sl@0
|
2252 |
_transferInProgress = true;
|
sl@0
|
2253 |
|
sl@0
|
2254 |
// If the device hasn't been detected, was removed, or timed out on a previous attempt
|
sl@0
|
2255 |
// to access it, look for the device.
|
sl@0
|
2256 |
|
sl@0
|
2257 |
if (!_deviceHandleObtained)
|
sl@0
|
2258 |
{
|
sl@0
|
2259 |
_deviceHandleObtained = FindTheHid();
|
sl@0
|
2260 |
}
|
sl@0
|
2261 |
|
sl@0
|
2262 |
if (_deviceHandleObtained)
|
sl@0
|
2263 |
{
|
sl@0
|
2264 |
GetBytesToSend();
|
sl@0
|
2265 |
|
sl@0
|
2266 |
if ((_myHid.Capabilities.FeatureReportByteLength > 0))
|
sl@0
|
2267 |
{
|
sl@0
|
2268 |
// The HID has a Feature report.
|
sl@2
|
2269 |
// Set the size of the Feature report buffer.
|
sl@0
|
2270 |
|
sl@0
|
2271 |
var outFeatureReportBuffer = new Byte[_myHid.Capabilities.FeatureReportByteLength];
|
sl@0
|
2272 |
|
sl@0
|
2273 |
// Store the report ID in the buffer.
|
sl@0
|
2274 |
|
sl@0
|
2275 |
outFeatureReportBuffer[0] = 0;
|
sl@0
|
2276 |
|
sl@0
|
2277 |
// Store the report data following the report ID.
|
sl@0
|
2278 |
// Use the data in the combo boxes on the form.
|
sl@0
|
2279 |
|
sl@0
|
2280 |
outFeatureReportBuffer[1] = Convert.ToByte(CboByte0.SelectedIndex);
|
sl@0
|
2281 |
|
sl@0
|
2282 |
if (outFeatureReportBuffer.GetUpperBound(0) > 1)
|
sl@0
|
2283 |
{
|
sl@0
|
2284 |
outFeatureReportBuffer[2] = Convert.ToByte(CboByte1.SelectedIndex);
|
sl@0
|
2285 |
}
|
sl@0
|
2286 |
|
sl@0
|
2287 |
// Write a report to the device
|
sl@0
|
2288 |
|
sl@0
|
2289 |
Boolean success = _myHid.SendFeatureReport(_hidHandle, outFeatureReportBuffer);
|
sl@0
|
2290 |
|
sl@0
|
2291 |
if (success)
|
sl@0
|
2292 |
{
|
sl@0
|
2293 |
DisplayReportData(outFeatureReportBuffer, ReportTypes.Feature, ReportReadOrWritten.Written);
|
sl@0
|
2294 |
}
|
sl@0
|
2295 |
else
|
sl@0
|
2296 |
{
|
sl@0
|
2297 |
CloseCommunications();
|
sl@0
|
2298 |
AccessForm(FormActions.AddItemToListBox, "The attempt to send a Feature report failed.");
|
sl@0
|
2299 |
ScrollToBottomOfListBox();
|
sl@0
|
2300 |
}
|
sl@0
|
2301 |
}
|
sl@0
|
2302 |
else
|
sl@0
|
2303 |
{
|
sl@0
|
2304 |
AccessForm(FormActions.AddItemToListBox, "The HID doesn't have a Feature report.");
|
sl@0
|
2305 |
ScrollToBottomOfListBox();
|
sl@0
|
2306 |
}
|
sl@0
|
2307 |
|
sl@0
|
2308 |
}
|
sl@0
|
2309 |
_transferInProgress = false;
|
sl@0
|
2310 |
cmdSendFeatureReport.Enabled = true;
|
sl@0
|
2311 |
ScrollToBottomOfListBox();
|
sl@0
|
2312 |
|
sl@0
|
2313 |
}
|
sl@0
|
2314 |
catch (Exception ex)
|
sl@0
|
2315 |
{
|
sl@0
|
2316 |
DisplayException(Name, ex);
|
sl@0
|
2317 |
throw;
|
sl@0
|
2318 |
}
|
sl@0
|
2319 |
}
|
sl@0
|
2320 |
|
sl@0
|
2321 |
/// <summary>
|
sl@0
|
2322 |
/// Sends an Output report.
|
sl@0
|
2323 |
/// Assumes report ID = 0.
|
sl@0
|
2324 |
/// </summary>
|
sl@0
|
2325 |
|
sl@0
|
2326 |
private async void RequestToSendOutputReport()
|
sl@0
|
2327 |
{
|
sl@0
|
2328 |
const Int32 writeTimeout = 5000;
|
sl@0
|
2329 |
String byteValue = null;
|
sl@0
|
2330 |
|
sl@0
|
2331 |
try
|
sl@0
|
2332 |
{
|
sl@0
|
2333 |
// If the device hasn't been detected, was removed, or timed out on a previous attempt
|
sl@0
|
2334 |
// to access it, look for the device.
|
sl@0
|
2335 |
|
sl@0
|
2336 |
if (!_deviceHandleObtained)
|
sl@0
|
2337 |
{
|
sl@0
|
2338 |
_deviceHandleObtained = FindTheHid();
|
sl@0
|
2339 |
}
|
sl@0
|
2340 |
|
sl@0
|
2341 |
if (_deviceHandleObtained)
|
sl@0
|
2342 |
{
|
sl@0
|
2343 |
GetBytesToSend();
|
sl@0
|
2344 |
}
|
sl@0
|
2345 |
// Don't attempt to exchange reports if valid handles aren't available
|
sl@0
|
2346 |
// (as for a mouse or keyboard.)
|
sl@0
|
2347 |
|
sl@0
|
2348 |
if (!_hidHandle.IsInvalid)
|
sl@0
|
2349 |
{
|
sl@0
|
2350 |
// Don't attempt to send an Output report if the HID has no Output report.
|
sl@0
|
2351 |
|
sl@0
|
2352 |
if (_myHid.Capabilities.OutputReportByteLength > 0)
|
sl@0
|
2353 |
{
|
sl@2
|
2354 |
// Set the size of the Output report buffer.
|
sl@0
|
2355 |
|
sl@0
|
2356 |
var outputReportBuffer = new Byte[_myHid.Capabilities.OutputReportByteLength];
|
sl@0
|
2357 |
|
sl@0
|
2358 |
// Store the report ID in the first byte of the buffer:
|
sl@0
|
2359 |
|
sl@0
|
2360 |
outputReportBuffer[0] = 0;
|
sl@0
|
2361 |
|
sl@0
|
2362 |
// Store the report data following the report ID.
|
sl@0
|
2363 |
// Use the data in the combo boxes on the form.
|
sl@0
|
2364 |
|
sl@0
|
2365 |
outputReportBuffer[1] = Convert.ToByte(CboByte0.SelectedIndex);
|
sl@0
|
2366 |
|
sl@0
|
2367 |
if (outputReportBuffer.GetUpperBound(0) > 1)
|
sl@0
|
2368 |
{
|
sl@0
|
2369 |
outputReportBuffer[2] = Convert.ToByte(CboByte1.SelectedIndex);
|
sl@0
|
2370 |
}
|
sl@0
|
2371 |
|
sl@0
|
2372 |
// Write a report.
|
sl@0
|
2373 |
|
sl@0
|
2374 |
Boolean success;
|
sl@0
|
2375 |
|
sl@0
|
2376 |
if (_transferType.Equals(TransferTypes.Control))
|
sl@0
|
2377 |
{
|
sl@0
|
2378 |
{
|
sl@0
|
2379 |
_transferInProgress = true;
|
sl@0
|
2380 |
|
sl@0
|
2381 |
// Use a control transfer to send the report,
|
sl@0
|
2382 |
// even if the HID has an interrupt OUT endpoint.
|
sl@0
|
2383 |
|
sl@0
|
2384 |
success = _myHid.SendOutputReportViaControlTransfer(_hidHandle, outputReportBuffer);
|
sl@0
|
2385 |
|
sl@0
|
2386 |
_transferInProgress = false;
|
sl@0
|
2387 |
cmdSendOutputReportControl.Enabled = true;
|
sl@0
|
2388 |
}
|
sl@0
|
2389 |
}
|
sl@0
|
2390 |
else
|
sl@0
|
2391 |
{
|
sl@0
|
2392 |
Debug.Print("interrupt");
|
sl@0
|
2393 |
_transferInProgress = true;
|
sl@0
|
2394 |
|
sl@0
|
2395 |
// The CancellationTokenSource specifies the timeout value and the action to take on a timeout.
|
sl@0
|
2396 |
|
sl@0
|
2397 |
var cts = new CancellationTokenSource();
|
sl@0
|
2398 |
|
sl@0
|
2399 |
// Create a delegate to execute on a timeout.
|
sl@0
|
2400 |
|
sl@0
|
2401 |
Action onWriteTimeoutAction = OnWriteTimeout;
|
sl@0
|
2402 |
|
sl@0
|
2403 |
// Cancel the read if it hasn't completed after a timeout.
|
sl@0
|
2404 |
|
sl@0
|
2405 |
cts.CancelAfter(writeTimeout);
|
sl@0
|
2406 |
|
sl@0
|
2407 |
// Specify the function to call on a timeout.
|
sl@0
|
2408 |
|
sl@0
|
2409 |
cts.Token.Register(onWriteTimeoutAction);
|
sl@0
|
2410 |
|
sl@0
|
2411 |
// Send an Output report and wait for completion or timeout.
|
sl@0
|
2412 |
|
sl@0
|
2413 |
success = await _myHid.SendOutputReportViaInterruptTransfer(_deviceData, _hidHandle, outputReportBuffer, cts);
|
sl@0
|
2414 |
|
sl@0
|
2415 |
// Get here only if the operation completes without a timeout.
|
sl@0
|
2416 |
|
sl@0
|
2417 |
_transferInProgress = false;
|
sl@0
|
2418 |
cmdSendOutputReportInterrupt.Enabled = true;
|
sl@0
|
2419 |
|
sl@0
|
2420 |
// Dispose to stop the timeout timer.
|
sl@0
|
2421 |
|
sl@0
|
2422 |
cts.Dispose();
|
sl@0
|
2423 |
}
|
sl@0
|
2424 |
if (success)
|
sl@0
|
2425 |
{
|
sl@0
|
2426 |
DisplayReportData(outputReportBuffer, ReportTypes.Output, ReportReadOrWritten.Written);
|
sl@0
|
2427 |
}
|
sl@0
|
2428 |
else
|
sl@0
|
2429 |
{
|
sl@0
|
2430 |
CloseCommunications();
|
sl@0
|
2431 |
AccessForm(FormActions.AddItemToListBox, "The attempt to write an Output report failed.");
|
sl@0
|
2432 |
ScrollToBottomOfListBox();
|
sl@0
|
2433 |
}
|
sl@0
|
2434 |
}
|
sl@0
|
2435 |
}
|
sl@0
|
2436 |
else
|
sl@0
|
2437 |
{
|
sl@0
|
2438 |
AccessForm(FormActions.AddItemToListBox, "The HID doesn't have an Output report.");
|
sl@0
|
2439 |
}
|
sl@0
|
2440 |
}
|
sl@0
|
2441 |
catch (Exception ex)
|
sl@0
|
2442 |
{
|
sl@0
|
2443 |
DisplayException(Name, ex);
|
sl@0
|
2444 |
throw;
|
sl@0
|
2445 |
}
|
sl@0
|
2446 |
}
|
sl@0
|
2447 |
|
sl@0
|
2448 |
/// <summary>
|
sl@0
|
2449 |
/// Scroll to the bottom of the list box and trim as needed.
|
sl@0
|
2450 |
/// </summary>
|
sl@0
|
2451 |
|
sl@0
|
2452 |
private void ScrollToBottomOfListBox()
|
sl@0
|
2453 |
{
|
sl@0
|
2454 |
try
|
sl@0
|
2455 |
{
|
sl@0
|
2456 |
LstResults.SelectedIndex = LstResults.Items.Count - 1;
|
sl@0
|
2457 |
|
sl@0
|
2458 |
// If the list box is getting too large, trim its contents by removing the earliest data.
|
sl@0
|
2459 |
|
sl@0
|
2460 |
if (LstResults.Items.Count > 1000)
|
sl@0
|
2461 |
{
|
sl@0
|
2462 |
Int32 count;
|
sl@0
|
2463 |
for (count = 1; count <= 500; count++)
|
sl@0
|
2464 |
{
|
sl@0
|
2465 |
LstResults.Items.RemoveAt(4);
|
sl@0
|
2466 |
}
|
sl@0
|
2467 |
}
|
sl@0
|
2468 |
}
|
sl@0
|
2469 |
catch (Exception ex)
|
sl@0
|
2470 |
{
|
sl@0
|
2471 |
DisplayException(Name, ex);
|
sl@0
|
2472 |
throw;
|
sl@0
|
2473 |
}
|
sl@0
|
2474 |
}
|
sl@0
|
2475 |
|
sl@0
|
2476 |
/// <summary>
|
sl@0
|
2477 |
/// Request to send or get a Feature report.
|
sl@0
|
2478 |
/// </summary>
|
sl@0
|
2479 |
|
sl@0
|
2480 |
private void SendOrGetFeatureReport()
|
sl@0
|
2481 |
{
|
sl@0
|
2482 |
try
|
sl@0
|
2483 |
{
|
sl@0
|
2484 |
// If the device hasn't been detected, was removed, or timed out on a previous attempt
|
sl@0
|
2485 |
// to access it, look for the device.
|
sl@0
|
2486 |
|
sl@0
|
2487 |
if (!_deviceHandleObtained)
|
sl@0
|
2488 |
{
|
sl@0
|
2489 |
_deviceHandleObtained = FindTheHid();
|
sl@0
|
2490 |
}
|
sl@0
|
2491 |
|
sl@0
|
2492 |
if (_deviceHandleObtained)
|
sl@0
|
2493 |
{
|
sl@0
|
2494 |
switch (_sendOrGet)
|
sl@0
|
2495 |
{
|
sl@0
|
2496 |
case SendOrGet.Send:
|
sl@0
|
2497 |
RequestToSendFeatureReport();
|
sl@0
|
2498 |
_sendOrGet = SendOrGet.Get;
|
sl@0
|
2499 |
break;
|
sl@0
|
2500 |
case SendOrGet.Get:
|
sl@0
|
2501 |
RequestToGetFeatureReport();
|
sl@0
|
2502 |
_sendOrGet = SendOrGet.Send;
|
sl@0
|
2503 |
break;
|
sl@0
|
2504 |
}
|
sl@0
|
2505 |
}
|
sl@0
|
2506 |
}
|
sl@0
|
2507 |
catch (Exception ex)
|
sl@0
|
2508 |
{
|
sl@0
|
2509 |
DisplayException(Name, ex);
|
sl@0
|
2510 |
throw;
|
sl@0
|
2511 |
}
|
sl@0
|
2512 |
}
|
sl@0
|
2513 |
|
sl@0
|
2514 |
/// <summary>
|
sl@0
|
2515 |
/// Request to send an Output report or get an Input report.
|
sl@0
|
2516 |
/// </summary>
|
sl@0
|
2517 |
|
sl@0
|
2518 |
private void SendOutputReportOrGetInputReport()
|
sl@0
|
2519 |
{
|
sl@0
|
2520 |
try
|
sl@0
|
2521 |
{
|
sl@0
|
2522 |
// If the device hasn't been detected, was removed, or timed out on a previous attempt
|
sl@0
|
2523 |
// to access it, look for the device.
|
sl@0
|
2524 |
|
sl@0
|
2525 |
if (!_deviceHandleObtained)
|
sl@0
|
2526 |
{
|
sl@0
|
2527 |
_deviceHandleObtained = FindTheHid();
|
sl@0
|
2528 |
}
|
sl@0
|
2529 |
|
sl@0
|
2530 |
if (_deviceHandleObtained)
|
sl@0
|
2531 |
{
|
sl@0
|
2532 |
if (_sendOrGet == SendOrGet.Send)
|
sl@0
|
2533 |
{
|
sl@0
|
2534 |
RequestToSendOutputReport();
|
sl@0
|
2535 |
_sendOrGet = SendOrGet.Get;
|
sl@0
|
2536 |
}
|
sl@0
|
2537 |
else
|
sl@0
|
2538 |
{
|
sl@0
|
2539 |
RequestToGetInputReport();
|
sl@0
|
2540 |
_sendOrGet = SendOrGet.Send;
|
sl@0
|
2541 |
}
|
sl@0
|
2542 |
}
|
sl@0
|
2543 |
}
|
sl@0
|
2544 |
catch (Exception ex)
|
sl@0
|
2545 |
{
|
sl@0
|
2546 |
DisplayException(Name, ex);
|
sl@0
|
2547 |
throw;
|
sl@0
|
2548 |
}
|
sl@0
|
2549 |
}
|
sl@0
|
2550 |
|
sl@0
|
2551 |
/// <summary>
|
sl@2
|
2552 |
/// Set the number of Input buffers (the number of Input reports
|
sl@0
|
2553 |
/// the host will store) from the value in the text box.
|
sl@0
|
2554 |
/// </summary>
|
sl@0
|
2555 |
|
sl@0
|
2556 |
private void SetInputReportBufferSize()
|
sl@0
|
2557 |
{
|
sl@0
|
2558 |
try
|
sl@0
|
2559 |
{
|
sl@0
|
2560 |
if (!_transferInProgress)
|
sl@0
|
2561 |
{
|
sl@0
|
2562 |
// Get the number of buffers from the text box.
|
sl@0
|
2563 |
|
sl@0
|
2564 |
Int32 numberOfInputBuffers = Convert.ToInt32(txtInputReportBufferSize.Text);
|
sl@0
|
2565 |
|
sl@0
|
2566 |
// Set the number of buffers.
|
sl@0
|
2567 |
|
sl@0
|
2568 |
_myHid.SetNumberOfInputBuffers(_hidHandle, numberOfInputBuffers);
|
sl@0
|
2569 |
|
sl@0
|
2570 |
// Verify and display the result.
|
sl@0
|
2571 |
|
sl@0
|
2572 |
GetInputReportBufferSize();
|
sl@0
|
2573 |
}
|
sl@0
|
2574 |
else
|
sl@0
|
2575 |
{
|
sl@0
|
2576 |
DisplayTransferInProgressMessage();
|
sl@0
|
2577 |
}
|
sl@0
|
2578 |
}
|
sl@0
|
2579 |
catch (Exception ex)
|
sl@0
|
2580 |
{
|
sl@0
|
2581 |
DisplayException(Name, ex);
|
sl@0
|
2582 |
throw;
|
sl@0
|
2583 |
}
|
sl@0
|
2584 |
}
|
sl@0
|
2585 |
|
sl@0
|
2586 |
/// <summary>
|
sl@0
|
2587 |
/// Perform actions that must execute when the program ends.
|
sl@0
|
2588 |
/// </summary>
|
sl@0
|
2589 |
|
sl@0
|
2590 |
private void Shutdown()
|
sl@0
|
2591 |
{
|
sl@0
|
2592 |
try
|
sl@0
|
2593 |
{
|
sl@0
|
2594 |
CloseCommunications();
|
sl@0
|
2595 |
DeviceNotificationsStop();
|
sl@0
|
2596 |
}
|
sl@0
|
2597 |
catch (Exception ex)
|
sl@0
|
2598 |
{
|
sl@0
|
2599 |
DisplayException(Name, ex);
|
sl@0
|
2600 |
throw;
|
sl@0
|
2601 |
}
|
sl@0
|
2602 |
}
|
sl@0
|
2603 |
|
sl@0
|
2604 |
/// <summary>
|
sl@0
|
2605 |
/// Perform actions that must execute when the program starts.
|
sl@0
|
2606 |
/// </summary>
|
sl@0
|
2607 |
|
sl@0
|
2608 |
private void Startup()
|
sl@0
|
2609 |
{
|
sl@0
|
2610 |
const Int32 periodicTransferInterval = 1000;
|
sl@0
|
2611 |
try
|
sl@0
|
2612 |
{
|
sl@0
|
2613 |
_myHid = new Hid();
|
sl@0
|
2614 |
InitializeDisplay();
|
sl@0
|
2615 |
|
sl@0
|
2616 |
_periodicTransfers = new System.Timers.Timer(periodicTransferInterval);
|
sl@0
|
2617 |
_periodicTransfers.Elapsed += DoPeriodicTransfers;
|
sl@0
|
2618 |
_periodicTransfers.Stop();
|
sl@0
|
2619 |
_periodicTransfers.SynchronizingObject = this;
|
sl@0
|
2620 |
|
sl@0
|
2621 |
// Default USB Vendor ID and Product ID:
|
sl@0
|
2622 |
|
sl@0
|
2623 |
txtVendorID.Text = "0925";
|
sl@0
|
2624 |
txtProductID.Text = "7001";
|
sl@0
|
2625 |
|
sl@0
|
2626 |
GetVendorAndProductIDsFromTextBoxes(ref _myVendorId, ref _myProductId);
|
sl@0
|
2627 |
|
sl@0
|
2628 |
DeviceNotificationsStart();
|
sl@0
|
2629 |
FindDeviceUsingWmi();
|
sl@0
|
2630 |
FindTheHid();
|
sl@0
|
2631 |
}
|
sl@0
|
2632 |
catch (Exception ex)
|
sl@0
|
2633 |
{
|
sl@0
|
2634 |
DisplayException(Name, ex);
|
sl@0
|
2635 |
throw;
|
sl@0
|
2636 |
}
|
sl@0
|
2637 |
}
|
sl@0
|
2638 |
|
sl@0
|
2639 |
/// <summary>
|
sl@0
|
2640 |
/// The Product ID has changed in the text box. Call a routine to handle it.
|
sl@0
|
2641 |
/// </summary>
|
sl@0
|
2642 |
|
sl@0
|
2643 |
private void txtProductID_TextChanged(Object sender, EventArgs e)
|
sl@0
|
2644 |
{
|
sl@0
|
2645 |
try
|
sl@0
|
2646 |
{
|
sl@0
|
2647 |
DeviceHasChanged();
|
sl@0
|
2648 |
}
|
sl@0
|
2649 |
catch (Exception ex)
|
sl@0
|
2650 |
{
|
sl@0
|
2651 |
DisplayException(Name, ex);
|
sl@0
|
2652 |
throw;
|
sl@0
|
2653 |
}
|
sl@0
|
2654 |
}
|
sl@0
|
2655 |
|
sl@0
|
2656 |
/// <summary>
|
sl@0
|
2657 |
/// The Vendor ID has changed in the text box. Call a routine to handle it.
|
sl@0
|
2658 |
/// </summary>
|
sl@0
|
2659 |
|
sl@0
|
2660 |
private void txtVendorID_TextChanged(Object sender, EventArgs e)
|
sl@0
|
2661 |
{
|
sl@0
|
2662 |
try
|
sl@0
|
2663 |
{
|
sl@0
|
2664 |
DeviceHasChanged();
|
sl@0
|
2665 |
}
|
sl@0
|
2666 |
catch (Exception ex)
|
sl@0
|
2667 |
{
|
sl@0
|
2668 |
DisplayException(Name, ex);
|
sl@0
|
2669 |
throw;
|
sl@0
|
2670 |
}
|
sl@0
|
2671 |
}
|
sl@0
|
2672 |
|
sl@0
|
2673 |
/// <summary>
|
sl@0
|
2674 |
/// Provides a central mechanism for exception handling.
|
sl@0
|
2675 |
/// Displays a message box that describes the exception.
|
sl@0
|
2676 |
/// </summary>
|
sl@2
|
2677 |
///
|
sl@0
|
2678 |
/// <param name="moduleName"> the module where the exception occurred. </param>
|
sl@0
|
2679 |
/// <param name="e"> the exception </param>
|
sl@0
|
2680 |
|
sl@0
|
2681 |
internal static void DisplayException(String moduleName, Exception e)
|
sl@0
|
2682 |
{
|
sl@0
|
2683 |
// Create an error message.
|
sl@0
|
2684 |
|
sl@0
|
2685 |
String message = "Exception: " + e.Message + Environment.NewLine + "Module: " + moduleName + Environment.NewLine + "Method: " + e.TargetSite.Name;
|
sl@0
|
2686 |
|
sl@0
|
2687 |
const String caption = "Unexpected Exception";
|
sl@0
|
2688 |
|
sl@0
|
2689 |
MessageBox.Show(message, caption, MessageBoxButtons.OK);
|
sl@0
|
2690 |
Debug.Write(message);
|
sl@0
|
2691 |
|
sl@2
|
2692 |
// Get the last error and display it.
|
sl@0
|
2693 |
|
sl@0
|
2694 |
Int32 error = Marshal.GetLastWin32Error();
|
sl@0
|
2695 |
|
sl@0
|
2696 |
Debug.WriteLine("The last Win32 Error was: " + error);
|
sl@0
|
2697 |
}
|
sl@0
|
2698 |
|
sl@0
|
2699 |
[STAThread]
|
sl@0
|
2700 |
internal static void Main() { Application.Run(new FrmMain()); }
|
sl@0
|
2701 |
private static FrmMain _transDefaultFormFrmMain;
|
sl@0
|
2702 |
internal static FrmMain TransDefaultFormFrmMain
|
sl@0
|
2703 |
{
|
sl@0
|
2704 |
get
|
sl@0
|
2705 |
{
|
sl@0
|
2706 |
if (_transDefaultFormFrmMain == null)
|
sl@0
|
2707 |
{
|
sl@0
|
2708 |
_transDefaultFormFrmMain = new FrmMain();
|
sl@0
|
2709 |
}
|
sl@0
|
2710 |
return _transDefaultFormFrmMain;
|
sl@0
|
2711 |
}
|
sl@0
|
2712 |
}
|
sl@5
|
2713 |
|
sl@5
|
2714 |
private void treeViewDevices_AfterSelect(object sender, TreeViewEventArgs e)
|
sl@5
|
2715 |
{
|
sl@5
|
2716 |
//Node selected in our TreeView
|
sl@5
|
2717 |
//Extract vendor and product IDs
|
sl@5
|
2718 |
string deviceId = treeViewDevices.SelectedNode.Name;
|
sl@5
|
2719 |
Regex regex = new Regex(@"VID_(....)&PID_(....).*");
|
sl@5
|
2720 |
Match match = regex.Match(deviceId);
|
sl@5
|
2721 |
if (match.Success)
|
sl@5
|
2722 |
{
|
sl@5
|
2723 |
//Take matches from each capturing group here. match.Groups[n].Value;
|
sl@5
|
2724 |
//Put vendor and product ID in our text fields.
|
sl@5
|
2725 |
txtVendorID.Text = match.Groups[1].Value;
|
sl@5
|
2726 |
txtProductID.Text = match.Groups[2].Value;
|
sl@5
|
2727 |
}
|
sl@5
|
2728 |
}
|
sl@0
|
2729 |
}
|
sl@0
|
2730 |
}
|