📄 frmmain.cs
字号:
this.ResumeLayout(false);
}
#endregion
// Project: usbhidio_vbdotnet
// Version: 2.0
// Date: 6/24/04
//
// Purpose:
// Demonstrates USB communications with a HID-class device
// Description:
// Finds an attached device that matches the vendor and product IDs in the form's
// text boxes.
// Retrieves the device's capabilities.
// Sends and requests HID reports.
// Uses RegisterDeviceNotification() and WM_DEVICE_CHANGE messages
// to detect when a device is attached or removed.
// RegisterDeviceNotification doesn't work under Windows 98 (not sure why).
// A list box displays the data sent and received,
// along with error and status messages.
// Combo boxes select data to send, and 1-time or timed, periodic transfers.
// You can change the size of the host's Input report buffer and request to use control
// transfers only to exchange Input and Output reports.
// To view additional debugging messages, in the Visual Studio development environment,
// select the Debug build (Build > Configuration Manager > Active Solution Configuration)
// and view the Output window (View > Other Windows > Output)
// The application uses a Delegate and the BeginInvoke and EndInvoke methods to read
// from the device asynchronously.
// If you want to only receive data or only send data, comment out the unwanted code
// (the "Success = " line and the "If Success" block that follows it).
// This project includes the following modules:
// frmMain.vb - routines specific to the form.
// Hid.vb - routines specific to HID communications.
// DeviceManagement.vb - routines for obtaining a handle to a device from its GUID
// and receiving device notifications. This routines are not specific to HIDs.
// Debugging.vb - contains a routine for displaying API error messages.
// HidDeclarations.vb - Declarations for API functions used by Hid.vb.
// FileIODeclarations.vb - Declarations for file-related API functions.
// DeviceManagementDeclarations.vb - Declarations for API functions used by DeviceManagement.vb.
// DebuggingDeclarations.vb - Declarations for API functions used by Debugging.vb.
// Companion device firmware for several device CPUs is available from www.Lvr.com/hidpage.htm.
// You can use any generic HID (not a system mouse or keyboard) that sends and receives reports.
// For more information about HIDs and USB, and additional example device firmware to use
// with this application, visit Lakeview Research at http:// www.Lvr.com .
// Send comments, bug reports, etc. to jan@Lvr.com .
// This application has been tested under Windows 98SE, Windows 2000, and Windows XP.
IntPtr _DeviceNotificationHandle;
int _HIDHandle;
bool _MyDeviceDetected;
string _MyDevicePathName;
Hid _MyHID = new Hid();
int _ReadHandle;
// Used only in viewing results of API calls in debug.write statements:
Debugging _MyDebugging = new Debugging();
DeviceManagement _MyDeviceManagement = new DeviceManagement();
// Define a class of delegates that point to the Hid.DeviceReport.Read function.
// The delegate has the same parameters as Hid.DeviceReport.Read.
// Used for asynchronous reads from the device.
private delegate void ReadInputReportDelegate (int readHandle, int hidHandle, ref bool myDeviceDetected, ref byte[] readBuffer, ref bool success);
internal void OnDeviceChange (Message m)
{
// Purpose : Called when a WM_DEVICECHANGE message has arrived,
// : indicating that a device has been attached or removed.
// Accepts : m - a message with information about the device
Debug.WriteLine("WM_DEVICECHANGE");
try
{
if (m.WParam.ToInt32() == DeviceManagementApiDeclarations.DBT_DEVICEARRIVAL)
{
// If WParam contains DBT_DEVICEARRIVAL, a device has been attached.
Debug.WriteLine("A device has been attached.");
// Find out if it's the device we're communicating with.
if (_MyDeviceManagement.DeviceNameMatch(m, _MyDevicePathName))
{
Debug.WriteLine("My device attached");
lstResults.Items.Add("My device attached.");
}
}
else if (m.WParam.ToInt32() == DeviceManagementApiDeclarations.DBT_DEVICEREMOVECOMPLETE)
{
// If WParam contains DBT_DEVICEREMOVAL, a device has been removed.
Debug.WriteLine("A device has been removed.");
// Find out if it's the device we're communicating with.
if (_MyDeviceManagement.DeviceNameMatch(m, _MyDevicePathName))
{
Debug.WriteLine("My device removed");
lstResults.Items.Add("My device removed.");
// Set MyDeviceDetected False so on the next data-transfer attempt,
// FindTheHid() will be called to look for the device
// and get a new handle.
this._MyDeviceDetected = false;
}
}
ScrollToBottomOfListBox();
} catch (Exception ex) {
HandleException(this.Name + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
}
private bool FindTheHid()
{
// Purpose : Uses a series of API calls to locate a HID-class device
// ; by its Vendor ID and Product ID.
// Returns : True if the device is detected, False if not detected.
bool DeviceFound = false;
string[] DevicePathName = new string[128];
string GUIDString;
System.Guid HidGuid;
int MemberIndex = 0;
short MyProductID = 0;
short MyVendorID = 0;
int Result = 0;
FileIOApiDeclarations.SECURITY_ATTRIBUTES Security = new HID_Test_Application.FileIOApiDeclarations.SECURITY_ATTRIBUTES();
bool Success = false;
try {
HidGuid = Guid.Empty;
_MyDeviceDetected = false;
// Values for the SECURITY_ATTRIBUTES structure:
Security.lpSecurityDescriptor = 0;
Security.bInheritHandle = System.Convert.ToInt32(true);
Security.nLength = Marshal.SizeOf(Security);
// Get the device's Vendor ID and Product ID from the form's text boxes.
GetVendorAndProductIDsFromTextBoxes(ref MyVendorID, ref MyProductID);
Console.WriteLine ("VendorID: " + MyVendorID.ToString());
Console.WriteLine ("ProductID: " + MyProductID.ToString());
/*
API function: 'HidD_GetHidGuid
Purpose: Retrieves the interface class GUID for the HID class.
Accepts: 'A System.Guid object for storing the GUID.
*/
HidApiDeclarations.HidD_GetHidGuid(ref HidGuid);
Debug.WriteLine(_MyDebugging.ResultOfAPICall("GetHidGuid"));
// Display the GUID.
GUIDString = HidGuid.ToString();
Debug.WriteLine(" GUID for system HIDs: " + GUIDString);
// Fill an array with the device path names of all attached HIDs.
DeviceFound = _MyDeviceManagement.FindDeviceFromGuid(HidGuid, ref DevicePathName);
// If there is at least one HID, attempt to read the Vendor ID and Product ID
// of each device until there is a match or all devices have been examined.
if (DeviceFound) {
MemberIndex = 0;
do {
// ***
// API function:
// CreateFile
// Purpose:
// Retrieves a handle to a device.
// Accepts:
// A device path name returned by SetupDiGetDeviceInterfaceDetail
// The type of access requested (read/write).
// FILE_SHARE attributes to allow other processes to access the device while this handle is open.
// A Security structure. Using Null for this may cause problems under Windows XP.
// A creation disposition value. Use OPEN_EXISTING for devices.
// Flags and attributes for files. Not used for devices.
// Handle to a template file. Not used.
// Returns: a handle that enables reading and writing to the device.
// ***
_HIDHandle = FileIOApiDeclarations.CreateFile
(DevicePathName[MemberIndex],
FileIOApiDeclarations.GENERIC_READ | FileIOApiDeclarations.GENERIC_WRITE,
FileIOApiDeclarations.FILE_SHARE_READ | FileIOApiDeclarations.FILE_SHARE_WRITE,
ref Security,
FileIOApiDeclarations.OPEN_EXISTING, 0, 0);
Debug.WriteLine(_MyDebugging.ResultOfAPICall("CreateFile"));
Debug.WriteLine(" Returned handle: " + _HIDHandle.ToString("x") + "h");
if (_HIDHandle != FileIOApiDeclarations.INVALID_HANDLE_VALUE) {
// The returned handle is valid,
// so find out if this is the device we're looking for.
// Set the Size property of DeviceAttributes to the number of bytes in the structure.
//_MyHID.DeviceAttributes.Size = _MyHID.DeviceAttributes.ToString().Length;
_MyHID.DeviceAttributes.Size = Marshal.SizeOf(_MyHID.DeviceAttributes);
// ***
// API function:
// HidD_GetAttributes
// Purpose:
// Retrieves a HIDD_ATTRIBUTES structure containing the Vendor ID,
// Product ID, and Product Version Number for a device.
// Accepts:
// A handle returned by CreateFile.
// A pointer to receive a HIDD_ATTRIBUTES structure.
// Returns:
// True on success, False on failure.
// ***
Result = HidApiDeclarations.HidD_GetAttributes(_HIDHandle, ref _MyHID.DeviceAttributes);
Debug.WriteLine(_MyDebugging.ResultOfAPICall("HidD_GetAttributes"));
if (Result != 0) {
Debug.WriteLine(" HIDD_ATTRIBUTES structure filled without error.");
//Debug.WriteLine(" Structure size: " + MyHID.DeviceAttributes.Size);
Debug.WriteLine(" Vendor ID: " + _MyHID.DeviceAttributes.VendorID.ToString("x"));
Debug.WriteLine(" Product ID: " + _MyHID.DeviceAttributes.ProductID.ToString("x"));
Debug.WriteLine(" Version Number: " + _MyHID.DeviceAttributes.VersionNumber.ToString("x"));
// Find out if the device matches the one we're looking for.
if ((_MyHID.DeviceAttributes.VendorID == MyVendorID) & (_MyHID.DeviceAttributes.ProductID == MyProductID)) {
// It's the desired device.
Debug.WriteLine(" My device detected");
// Display the information in form's list box.
lstResults.Items.Add("Device detected:");
lstResults.Items.Add(" Vendor ID = " + _MyHID.DeviceAttributes.VendorID.ToString("x"));
lstResults.Items.Add(" Product ID = " + _MyHID.DeviceAttributes.ProductID.ToString("x"));
ScrollToBottomOfListBox();
_MyDeviceDetected = true;
// Save the DevicePathName so OnDeviceChange() knows which name is my device.
_MyDevicePathName = DevicePathName[MemberIndex];
} else {
// It's not a match, so close the handle.
_MyDeviceDetected = false;
Result = FileIOApiDeclarations.CloseHandle(_HIDHandle);
Debug.WriteLine(_MyDebugging.ResultOfAPICall("CloseHandle"));
}
} else {
// There was a problem in retrieving the information.
Debug.WriteLine(" Error in filling HIDD_ATTRIBUTES structure.");
_MyDeviceDetected = false;
Result = FileIOApiDeclarations.CloseHandle(_HIDHandle);
}
}
// Keep looking until we find the device or there are no more left to examine.
MemberIndex = MemberIndex + 1;
} while (!((_MyDeviceDetected == true) |(MemberIndex == DevicePathName.Length + 1)));
}
if (_MyDeviceDetected) {
// The device was detected.
// Register to receive notifications if the device is removed or attached.
Success = _MyDeviceManagement.RegisterForDeviceNotifications(_MyDevicePathName, this.Handle, HidGuid, ref _DeviceNotificationHandle);
Debug.WriteLine("RegisterForDeviceNotifications = " + Success);
// Learn the capabilities of the device.
_MyHID.Capabilities = _MyHID.GetDeviceCapabilities(_HIDHandle);
if (Success) {
// Get and display the Input report buffer size.
GetInputReportBufferSize();
cmdInputReportBufferSize.Enabled = true;
// Get another handle to use in overlapped ReadFiles (for requesting Input reports).
_ReadHandle = FileIOApiDeclarations.CreateFile(_MyDevicePathName, FileIOApiDeclarations.GENERIC_READ | FileIOApiDeclarations.GENERIC_WRITE, FileIOApiDeclarations.FILE_SHARE_READ | FileIOApiDeclarations.FILE_SHARE_WRITE, ref Security, FileIOApiDeclarations.OPEN_EXISTING, FileIOApiDeclarations.FILE_FLAG_OVERLAPPED, 0);
Debug.WriteLine(_MyDebugging.ResultOfAPICall("CreateFile, ReadHandle"));
Debug.WriteLine(" Returned handle: " + _ReadHandle.ToString("x") + "h");
// (optional)
// Flush any waiting reports in the input buffer.
_MyHID.FlushQueue(_ReadHandle);
}
} else {
// The device wasn't detected.
lstResults.Items.Add("Device not found.");
cmdInputReportBufferSize.Enabled = false;
cmdOnce.Enabled = true;
Debug.WriteLine(" Device not found.");
ScrollToBottomOfListBox();
}
} catch (Exception ex) {
HandleException(this.Name + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
return _MyDeviceDetected;
}
private void cmdContinuous_Click (System.Object eventSender, System.EventArgs eventArgs)
{
// Start or stop a series of periodic transfers.
try
{
if (cmdContinuous.Text == "Continuous") {
// Start doing periodic transfers.
// Change the command button to "Cancel Continuous"
cmdContinuous.Text = "Cancel Continuous";
// Enable the timer event to trigger a set of transfers.
tmrContinuousDataCollect.Enabled = true;
ReadAndWriteToDevice();
} else {
// Stop doing continuous transfers.
// Change the command button to "Continuous"
cmdContinuous.Text = "Continuous";
// Disable the timer that triggers the transfers.
tmrContinuousDataCollect.Enabled = false;
}
} catch (Exception ex) {
HandleException(this.Name + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
}
private void cmdInputReportBufferSize_Click (System.Object sender, System.EventArgs e)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -