📄 hid.vb
字号:
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Friend Class Hid
'For communicating with HID-class devices.
'Used in error messages.
Const ModuleName As String = "Hid"
Friend Capabilities As HIDP_CAPS
Friend DeviceAttributes As HIDD_ATTRIBUTES
'For viewing results of API calls in debug.write statements:
Shared MyDebugging As New Debugging()
Friend MustInherit Class DeviceReport
'For reports that the device sends to the host.
Friend HIDHandle As Integer
Friend MyDeviceDetected As Boolean
Friend Result As Integer
Friend ReadHandle As Integer
'Each DeviceReport class defines a ProtectedRead method for reading a type of report.
'ProtectedRead and Read are declared as Subs rather than as Functions because
'asynchronous reads use a callback method that can access parameters passed by ByRef
'but not Function return values.
Protected MustOverride Sub ProtectedRead _
(ByVal readHandle As Integer, _
ByVal hidHandle As Integer, _
ByVal writeHandle As Integer, _
ByRef myDeviceDetected As Boolean, _
ByRef readBuffer() As Byte, _
ByRef success As Boolean)
Friend Sub Read _
(ByVal readHandle As Integer, _
ByVal hidHandle As Integer, _
ByVal writeHandle As Integer, _
ByRef myDeviceDetected As Boolean, _
ByRef readBuffer() As Byte, _
ByRef success As Boolean)
'Purpose : Calls the overridden ProtectedRead routine.
' Enables other classes to override ProtectedRead
' while limiting access as Friend.
' (Directly declaring Write as Friend MustOverride causes the
' compiler warning : "Other languages may permit Friend
' Overridable members to be overridden.")
'Accepts : readHandle - a handle for reading from the device.
' hidHandle - a handle for other device communications.
' myDeviceDetected - tells whether the device is currently
' attached and communicating.
' readBuffer - a byte array to hold the report ID and report data.
' success - read success
Try
'Request the report.
ProtectedRead _
(readHandle, _
hidHandle, _
writeHandle, _
myDeviceDetected, _
readBuffer, _
success)
Catch ex As Exception
Call HandleException(ModuleName, ex)
End Try
End Sub
End Class
Friend Class InFeatureReport
Inherits DeviceReport
'For reading Feature reports.
Protected Overrides Sub ProtectedRead _
(ByVal readHandle As Integer, _
ByVal hidHandle As Integer, _
ByVal writeHandle As Integer, _
ByRef myDeviceDetected As Boolean, _
ByRef inFeatureReportBuffer() As Byte, _
ByRef success As Boolean)
'Purpose : reads a Feature report from the device.
'Accepts : readHandle - the handle for reading from the device.
' hidHandle - the handle for other device communications.
' myDeviceDetected - tells whether the device is currently attached.
' readBuffer - contains the requested report.
' success - read success
Try
'***
'API function: HidD_GetFeature
'Attempts to read a Feature report from the device.
'Requires:
'A handle to a HID
'A pointer to a buffer containing the report ID and report
'The size of the buffer.
'Returns: true on success, false on failure.
'***
success = HidD_GetFeature _
(hidHandle, _
inFeatureReportBuffer(0), _
UBound(inFeatureReportBuffer) + 1)
Debug.WriteLine(MyDebugging.ResultOfAPICall("HidD_GetFeature"))
Debug.WriteLine("")
Catch ex As Exception
Call HandleException(ModuleName, ex)
End Try
End Sub
End Class
Friend Class InputReport
Inherits DeviceReport
'For reading Input reports.
Dim ReadyForOverlappedTransfer As Boolean ' initialize to false
Friend Sub CancelTransfer _
(ByVal readHandle As Integer, _
ByVal hidHandle As Integer, _
ByVal writeHandle As Integer)
'Purpose : closes open handles to a device.
'Accepts : ReadHandle - the handle for reading from the device.
' HIDHandle - the handle for other device communications.
Try
'***
'API function: CancelIo
'Purpose: Cancels a call to ReadFile
'Accepts: the device handle.
'Returns: True on success, False on failure.
'***
CancelIo(readHandle)
Debug.WriteLine("************ReadFile error*************")
Debug.WriteLine(MyDebugging.ResultOfAPICall("CancelIo"))
Debug.WriteLine("")
'The failure may have been because the device was removed,
'so close any open handles and
'set myDeviceDetected=False to cause the application to
'look for the device on the next attempt.
If (hidHandle <> 0) Then
CloseHandle(hidHandle)
Debug.WriteLine(MyDebugging.ResultOfAPICall("CloseHandle (HIDHandle)"))
Debug.WriteLine("")
End If
If (readHandle <> 0) Then
CloseHandle(readHandle)
Debug.WriteLine(MyDebugging.ResultOfAPICall("CloseHandle (ReadHandle)"))
End If
If (writeHandle <> 0) Then
CloseHandle(writeHandle)
Debug.WriteLine(MyDebugging.ResultOfAPICall("CloseHandle (WriteHandle)"))
End If
Catch ex As Exception
Call HandleException(ModuleName, ex)
End Try
End Sub
Friend Sub PrepareForOverlappedTransfer _
(ByRef hidOverlapped As OVERLAPPED, _
ByRef eventObject As Integer)
'Purpose : Creates an event object for the overlapped structure used with
' : ReadFile.
' ; Called before the first call to ReadFile.
Dim Security As SECURITY_ATTRIBUTES
Try
'Values for the SECURITY_ATTRIBUTES structure:
Security.lpSecurityDescriptor = 0
Security.bInheritHandle = CInt(True)
Security.nLength = Len(Security)
'***
'API function: CreateEvent
'Purpose: Creates an event object for the overlapped structure used with ReadFile.
'Accepts:
'A security attributes structure.
'Manual Reset = False (The system automatically resets the state to nonsignaled
'after a waiting thread has been released.)
'Initial state = True (signaled)
'An event object name (optional)
'Returns: a handle to the event object
'***
eventObject = CreateEvent(Security, CInt(False), CInt(True), "")
Debug.WriteLine(MyDebugging.ResultOfAPICall("CreateEvent"))
Debug.WriteLine("")
'Set the members of the overlapped structure.
hidOverlapped.Offset = 0
hidOverlapped.OffsetHigh = 0
hidOverlapped.hEvent = eventObject
ReadyForOverlappedTransfer = True
Catch ex As Exception
Call HandleException(ModuleName, ex)
End Try
End Sub
Protected Overrides Sub ProtectedRead _
(ByVal readHandle As Integer, _
ByVal hidHandle As Integer, _
ByVal writeHandle As Integer, _
ByRef myDeviceDetected As Boolean, _
ByRef inputReportBuffer() As Byte, _
ByRef success As Boolean)
'Purpose : reads an Input report from the device using interrupt transfers.
'Accepts : readHandle - the handle for reading from the device.
' hidHandle - the handle for other device communications.
' myDeviceDetected - tells whether the device is currently attached.
' readBuffer - contains the requested report.
' success - read success
Dim EventObject As Integer
Dim HIDOverlapped As OVERLAPPED
Dim NumberOfBytesRead As Integer
Dim Result As Integer
Try
'If it's the first attempt to read, set up the overlapped structure for ReadFile.
If ReadyForOverlappedTransfer = False Then
Call PrepareForOverlappedTransfer(HIDOverlapped, EventObject)
End If
'***
'API function: ReadFile
'Purpose: Attempts to read an Input report from the device.
'Accepts:
'A device handle returned by CreateFile
'(for overlapped I/O, CreateFile must have been called with FILE_FLAG_OVERLAPPED),
'A pointer to a buffer for storing the report.
'The Input report length in bytes returned by HidP_GetCaps,
'A pointer to a variable that will hold the number of bytes read.
'An overlapped structure whose hEvent member is set to an event object.
'Returns: the report in ReadBuffer.
'The overlapped call returns immediately, even if the data hasn't been received yet.
'To read multiple reports with one ReadFile, increase the size of ReadBuffer
'and use NumberOfBytesRead to determine how many reports were returned.
'Use a larger buffer if the application can't keep up with reading each report
'individually.
'***
Debug.Write("input report length = " & UBound(inputReportBuffer) + 1)
Result = ReadFile _
(readHandle, _
inputReportBuffer(0), _
UBound(inputReportBuffer) + 1, _
NumberOfBytesRead, _
HIDOverlapped)
Debug.WriteLine(MyDebugging.ResultOfAPICall("ReadFile"))
Debug.WriteLine("")
Debug.WriteLine("waiting for ReadFile")
'API function: WaitForSingleObject
'Purpose: waits for at least one report or a timeout.
'Used with overlapped ReadFile.
'Accepts:
'An event object created with CreateEvent
'A timeout value in milliseconds.
'Returns: A result code.
Result = WaitForSingleObject(EventObject, 3000)
Debug.WriteLine(MyDebugging.ResultOfAPICall("WaitForSingleObject"))
Debug.WriteLine("")
'Find out if ReadFile completed or timeout.
Select Case Result
Case WAIT_OBJECT_0
'ReadFile has completed
Debug.WriteLine("")
success = True
Debug.WriteLine("ReadFile completed successfully.")
Case WAIT_TIMEOUT
'Cancel the operation on timeout
Call CancelTransfer(readHandle, hidHandle, writeHandle)
Debug.WriteLine("Readfile timeout")
Debug.WriteLine("")
success = False
myDeviceDetected = False
Case Else
'Cancel the operation on other error.
Call CancelTransfer(readHandle, hidHandle, writeHandle)
Debug.WriteLine("")
Debug.WriteLine("Readfile undefined error")
success = False
myDeviceDetected = False
End Select
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -