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