none
A first chance exception of type 'System.NullReferenceException' occurred RRS feed

  • 问题

  • 新人学习VB,用开源的USB上位机软件做实验是。VB的书没涉及这方面错误介绍,网上的解决方法要不雷同,要不看不明不理,解错误提示如下:

    A first chance exception of type 'System.NullReferenceException' occurred in GenericHid.exe
    Exception: 未将对象引用设置到对象的实例。
    Module: FrmMain
    Method: CTLX2_TP_selftestA first chance exception of type 'System.NullReferenceException' occurred in GenericHid.exe

    就是新加的CTLX2_TP_selftest()函数有问题,如果删掉,运行正常;就是不明不问题出哪,请各位指教。请用CTRL+F定位CTLX2_TP_selftest()函数

    Option Strict On
    Option Explicit On
    
    Imports GenericHid.DeviceManagement
    Imports GenericHid.FileIo
    Imports GenericHid.Hid
    Imports Microsoft.Win32.SafeHandles
    Imports System.Globalization
    Imports System.IO
    Imports System.Runtime.InteropServices
    Imports System.Timers
    
    '''<summary>
    ''' 
    ''' Project: GenericHid
    ''' 
    ''' ***********************************************************************
    ''' Software License Agreement
    '''
    ''' Licensor grants any person obtaining a copy of this software ("You") 
    ''' a worldwide, royalty-free, non-exclusive license, for the duration of 
    ''' the copyright, free of charge, to store and execute the Software in a 
    ''' computer system and to incorporate the Software or any portion of it 
    ''' in computer programs You write.   
    ''' 
    ''' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    ''' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    ''' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    ''' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    ''' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    ''' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    ''' THE SOFTWARE.
    ''' ***********************************************************************
    ''' 
    ''' Author             
    ''' Jan Axelson        
    ''' </summary>
    
    Friend Class FrmMain
    
        Inherits System.Windows.Forms.Form
    
        Private deviceNotificationHandle As IntPtr
        Private exclusiveAccess As Boolean
        Private fileStreamdevicedata As FileStream
        Private hidHandle As SafeFileHandle
        Private hidUsage As String
        Private myDeviceDetected As Boolean
        Private myDevicePathName As String
        Private transferInProgress As Boolean = False
        Private writeHandle As SafeFileHandle
    
        Private MyDebugging As New Debugging() ' For viewing results of API calls via Debug.Write.
        Private MyDeviceManagement As New DeviceManagement()
        Private MyHid As New Hid()
    
        Private Shared tmrReadTimeout As System.Timers.Timer
        Private Shared tmrContinuousDataCollect As System.Timers.Timer
    
        Friend FrmMy As FrmMain
    
        Dim myProductID As Int32
        Dim myVendorID As Int32
        Dim GetReportBuffer() As Byte = Nothing
        Dim SetReportBuffer() As Byte = Nothing
    
        ' This delegate has the same parameters as AccessForm.
        ' Used in accessing the application's form from a different thread.
    
        Private Delegate Sub MarshalToForm _
         (ByVal action As String, _
         ByVal textToAdd As String)
    
        '''  <summary>
        '''  Exchange data with the device.
        '''  </summary>
        '''  
        '''  <remarks>
        '''  The timer is enabled only if cmdContinous has been clicked, 
        '''  selecting continous (periodic) transfers.
        '''  </remarks>
        ''' 
        Private Sub OnDataCollect(ByVal source As Object, ByVal e As ElapsedEventArgs)
    
            Try
                If (transferInProgress = False) Then
    
                    ReadAndWriteToDevice()
                End If
    
            Catch ex As Exception
    
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' System timer timeout if read via interrupt transfer doesn't return.
        ''' </summary>
        ''' <param name="source"></param>
        ''' <param name="e"></param>
        ''' <remarks></remarks>
    
        Private Sub OnReadTimeout(ByVal source As Object, ByVal e As ElapsedEventArgs)
    
            MyMarshalToForm("AddItemToListBox", "The attempt to read a report timed out.")
    
            CloseCommunications()
    
            tmrReadTimeout.Stop()
    
            '  Enable requesting another transfer.
    
            MyMarshalToForm("EnableCmdOnce", "")
            MyMarshalToForm("ScrollToBottomOfListBox", "")
    
        End Sub
    
        ''' <summary>
        ''' Called when a WM_DEVICECHANGE message has arrived,
        ''' indicating that a device has been attached or removed.
        ''' </summary>
        ''' 
        ''' <param name="m"> a message with information about the device </param>
    
        Friend Sub OnDeviceChange(ByVal m As Message)
    
            Debug.WriteLine("WM_DEVICECHANGE")
    
            Try
                If (m.WParam.ToInt32 = DBT_DEVICEARRIVAL) Then
    
                    ' 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) Then
                        lstResults.Items.Add("My device attached.")
                    End If
    
                ElseIf (m.WParam.ToInt32 = DBT_DEVICEREMOVECOMPLETE) Then
    
                    ' 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) Then
    
                        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.
    
                        FrmMy.myDeviceDetected = False
                    End If
                End If
    
                ScrollToBottomOfListBox()
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
        End Sub
    
        ''' <summary>
        ''' Uses a series of API calls to locate a HID-class device
        ''' by its Vendor ID and Product ID.
        ''' </summary>
        '''         
        ''' <returns>
        '''  True if the device is detected, False if not detected.
        ''' </returns>
    
        Private Function FindTheHid() As Boolean
    
            Dim deviceFound As Boolean
            Dim devicePathName(127) As String
            Dim hidGuid As System.Guid
            Dim inputReportBuffer As Byte() = Nothing
            Dim memberIndex As Int32
            Dim outputReportBuffer As Byte() = Nothing
            Dim success As Boolean
    
            Try
                myDeviceDetected = False
    
                ' ***
                ' API function: 'HidD_GetHidGuid
    
                ' Purpose: Retrieves the interface class GUID for the HID class.
    
                ' Accepts: 'A System.Guid object for storing the GUID.
                ' ***
    
                HidD_GetHidGuid(hidGuid)
    
                Debug.WriteLine(MyDebugging.ResultOfAPICall("GetHidGuid"))
                Debug.WriteLine("  GUID for system HIDs: " & hidGuid.ToString)
    
                ' Fill an array with the device path names of all attached HIDs.
    
                deviceFound = MyDeviceManagement.FindDeviceFromGuid _
                 (hidGuid, _
                 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 Then
    
                    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 or IntPtr.Zero. 
                        ' 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 without read or write access.
                        ' This enables obtaining information about all HIDs, even system
                        ' keyboards and mice. 
                        ' Separate handles are used for reading and writing.
                        ' ***
    
                        ' Open the handle without read/write access to enable getting information about any HID, even system keyboards and mice.
    
                        hidHandle = CreateFile _
                         (devicePathName(memberIndex), _
                         0, _
                         FILE_SHARE_READ Or FILE_SHARE_WRITE, _
                         IntPtr.Zero, _
                         OPEN_EXISTING, _
                         0, _
                         0)
    
                        Debug.WriteLine(MyDebugging.ResultOfAPICall("CreateFile"))
                        Debug.WriteLine("  Returned handle: " & hidHandle.ToString)
    
                        If Not (hidHandle.IsInvalid) Then
    
                            ' 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 = 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.
                            ' ***
    
                            success = HidD_GetAttributes(hidHandle, MyHid.DeviceAttributes)
    
                            If success Then
    
                                Debug.WriteLine("  HIDD_ATTRIBUTES structure filled without error.")
                                Debug.WriteLine("  Structure size: " & MyHid.DeviceAttributes.Size)
                                Debug.WriteLine("  Vendor ID: " & Hex(MyHid.DeviceAttributes.VendorID))
                                Debug.WriteLine("  Product ID: " & Hex(MyHid.DeviceAttributes.ProductID))
                                Debug.WriteLine("  Version Number: " & Hex(MyHid.DeviceAttributes.VersionNumber))
    
                                ' Find out if the device matches the one we're looking for.
    
                                If (MyHid.DeviceAttributes.VendorID = myVendorID) And _
                                 (MyHid.DeviceAttributes.ProductID = myProductID) Then
    
                                    Debug.WriteLine("  My device detected")
    
                                    ' Display the information in form's list box.
    
                                    lstResults.Items.Add("Device detected:")
                                    lstResults.Items.Add("  Vendor ID= " & Hex(MyHid.DeviceAttributes.VendorID))
                                    lstResults.Items.Add("  Product ID = " & Hex(MyHid.DeviceAttributes.ProductID))
    
                                    ScrollToBottomOfListBox()
    
                                    myDeviceDetected = True
    
                                    ' Save the DevicePathName for OnDeviceChange().
    
                                    myDevicePathName = devicePathName(memberIndex)
                                Else
    
                                    ' It's not a match, so close the handle.
    
                                    myDeviceDetected = False
    
                                    hidHandle.Close()
    
                                End If
    
                            Else
                                ' There was a problem in retrieving the information.
    
                                Debug.WriteLine("  Error in filling HIDD_ATTRIBUTES structure.")
                                myDeviceDetected = False
                                hidHandle.Close()
                            End If
    
                        End If
    
                        ' Keep looking until we find the device or there are no devices left to examine.
    
                        memberIndex = memberIndex + 1
    
                    Loop Until (myDeviceDetected Or (memberIndex = devicePathName.Length))
    
                End If
    
                If myDeviceDetected Then
    
                    ' The device was detected.
                    ' Register to receive notifications if the device is removed or attached.
    
                    success = MyDeviceManagement.RegisterForDeviceNotifications _
                     (myDevicePathName, _
                     FrmMy.Handle, _
                     hidGuid, _
                     deviceNotificationHandle)
    
                    Debug.WriteLine("RegisterForDeviceNotifications = " & success)
    
                    ' Learn the capabilities of the device.
    
                    MyHid.Capabilities = MyHid.GetDeviceCapabilities(hidHandle)
    
                    If success Then
    
                        ' Find out if the device is a system mouse or keyboard.
    
                        hidUsage = MyHid.GetHidUsage(MyHid.Capabilities)
    
                        'Close the handle and reopen it with read/write access.
    
                        hidHandle.Close()
    
                        hidHandle = CreateFile _
                         (myDevicePathName, _
                         GENERIC_READ Or GENERIC_WRITE, _
                         FILE_SHARE_READ Or FILE_SHARE_WRITE, _
                         IntPtr.Zero, _
                         OPEN_EXISTING, _
                         0, _
                         0)
    
                        If hidHandle.IsInvalid Then
    
                            exclusiveAccess = True
                            lstResults.Items.Add("The device is a system " + hidUsage + ".")
                            lstResults.Items.Add("Windows 2000 and Windows XP obtain exclusive access to Input and Output reports for this devices.")
                            lstResults.Items.Add("Applications can access Feature reports only.")
                            ScrollToBottomOfListBox()
    
                        Else
    
                            If (MyHid.Capabilities.InputReportByteLength > 0) Then
    
                                ' Set the size of the Input report buffer. 
                                ' Subtract 1 from the value in the Capabilities structure because 
                                ' the array begins at index 0.
    
                                Array.Resize(inputReportBuffer, MyHid.Capabilities.InputReportByteLength)
    
                                fileStreamdevicedata = New FileStream(hidHandle, FileAccess.Read Or FileAccess.Write, inputReportBuffer.Length, False)
    
                            End If
    
                            If (MyHid.Capabilities.OutputReportByteLength > 0) Then
    
                                ' Set the size of the Output report buffer. 
                                ' Subtract 1 from the value in the Capabilities structure because 
                                ' the array begins at index 0.
    
                                Array.Resize(outputReportBuffer, MyHid.Capabilities.OutputReportByteLength)
    
                            End If
    
                            ' Flush any waiting reports in the input buffer. (optional)
    
                            MyHid.FlushQueue(hidHandle)
    
                        End If
                    End If
                Else
                    ' The device wasn't detected.
    
                    lstResults.Items.Add("Device not found.")
                    cmdOnce.Enabled = True
    
                    Debug.WriteLine(" Device not found.")
    
                    ScrollToBottomOfListBox()
                End If
    
                Return myDeviceDetected
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
        End Function
    
        ''' <summary>
        ''' Performs various application-specific functions that
        ''' involve accessing the application's form.
        ''' </summary>
        ''' 
        ''' <param name="action"> a string that names the action to perform on the form</param>
        ''' <param name="formText"> text that the form displays or the code uses for 
        ''' another purpose. Actions that don't use text ignore this parameter. </param>
    
        Private Sub AccessForm(ByVal action As String, ByVal formText As String)
    
            Try
                ' Select an action to perform on the form:
    
                Select Case action
    
                    Case "AddItemToListBox"
    
                        lstResults.Items.Add(formText)
    
                    Case "AddItemToTextBox"
    
                        txtBytesReceived.SelectedText = formText & vbCrLf
    
                    Case "EnableCmdOnce"
    
                        ' If it's a single transfer, re-enable the command button.
    
                        If cmdContinuous.Text = "Continuous" Then
                            cmdOnce.Enabled = True
                        End If
    
                    Case "ScrollToBottomOfListBox"
    
                        lstResults.SelectedIndex = lstResults.Items.Count - 1
    
                    Case "TextBoxSelectionStart"
    
                        txtBytesReceived.SelectionStart = Len(formText)
    
                    Case Else
    
                End Select
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Start or stop a series of periodic transfers.
        ''' </summary>
    
        Private Sub cmdContinuous_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdContinuous.Click
    
            Try
                If cmdContinuous.Text = "Continuous" Then
    
                    ' Start doing periodic transfers.
    
                    If Not cmdOnce.Enabled Then
    
                        AccessForm("AddItemToListBox", "A previous transfer hasn't completed. Please try again.")
                    Else
    
                        cmdOnce.Enabled = False
    
                        ' Change the command button's text to "Cancel Continuous"
    
                        cmdContinuous.Text = "Cancel Continuous"
    
                        tmrContinuousDataCollect.Start()
                        ReadAndWriteToDevice()
                    End If
    
                Else
                    ' Stop doing continuous transfers.
                    ' Change the command button's text to "Continuous"
    
                    cmdContinuous.Text = "Continuous"
    
                    tmrContinuousDataCollect.Stop()
    
                    cmdOnce.Enabled = True
                End If
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
        End Sub
    
        ''' <summary>
        ''' Search for a specific device.
        ''' </summary>
    
        Private Sub cmdFindDevice_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdFindDevice.Click
    
            Try
                FindTheHid()
    
                CTLX2_TP_selftest()
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Attempt to write a report and read a report.
        ''' </summary>
        ''' 
        Private Sub cmdOnce_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdOnce.Click
    
            Try
                ' Don't allow another transfer request until this one completes.
                ' Move the focus away from cmdOnce to prevent the focus from 
                ' switching to the next control in the tab order on disabling the button.
    
                fraSendAndReceive.Focus()
                cmdOnce.Enabled = False
    
                ReadAndWriteToDevice()
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
        End Sub
    
        ''' <summary>
        ''' Close the handle and FileStreams for a device.
        ''' </summary>
    
        Private Sub CloseCommunications()
    
            If (Not (fileStreamdevicedata Is Nothing)) Then
    
                fileStreamdevicedata.Close()
            End If
    
            If ((Not (hidHandle Is Nothing)) And (Not hidHandle.IsInvalid)) Then
    
                hidHandle.Close()
            End If
    
            ' The next attempt to communicate will get new handles and FileStreams.
    
            myDeviceDetected = False
    
    
        End Sub
    
        ''' <summary>
        ''' Called if the user changes the Vendor ID or Product ID in the text box.
        ''' </summary>
        ''' 
        Private Sub DeviceHasChanged()
    
            Try
                ' If a device was previously detected, stop receiving notifications about it.
    
                If myDeviceDetected Then
                    MyDeviceManagement.StopReceivingDeviceNotifications(deviceNotificationHandle)
                End If
    
                ' Search for the device the next time FindTheHid is called.
    
                myDeviceDetected = False
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
        End Sub
    
        ''' <summary>
        ''' Sends an Output report
        ''' Assumes report ID = 0 for both reports.
        ''' </summary>
    
        Private Sub ExchangeOutputReports()
    
            Dim byteValue As String
            Dim count As Int32
            Dim success As Boolean
    
            Try
                success = False
    
                ' Don't attempt to exchange reports if valid handles aren't available
                ' (as for a mouse or keyboard under Windows 2000/XP.)
    
                If (Not (hidHandle.IsInvalid)) Then
    
                    ' Don't attempt to send an Output report if the HID has no Output report.
    
                    If (MyHid.Capabilities.OutputReportByteLength > 0) Then
    
                        ' Set the upper bound of the Output report buffer. 
                        ' Subtract 1 from OutputReportByteLength because the array begins at index 0.
    
                        Array.Resize(SetReportBuffer, MyHid.Capabilities.OutputReportByteLength)
    
                        ' Store the report ID in the first byte of the buffer:
    
                        SetReportBuffer(0) = 0
    
                        ' Store the report data following the report ID.
                        ' Use the data in the combo boxes on the form.
    
                        'SetReportBuffer(1) = Convert.ToByte(cboByte0.SelectedIndex)
    
                        'If UBound(SetReportBuffer) > 1 Then
                        'SetReportBuffer(8) = Convert.ToByte(cboByte1.SelectedIndex)
                        'End If
    
                        ' Write a report.
    
                        ' If the HID has an interrupt OUT endpoint, the host uses an 
                        ' interrupt transfer to send the report. 
                        ' If not, the host uses a control transfer.
    
                        If (fileStreamdevicedata.CanWrite) Then
                            fileStreamdevicedata.Write(SetReportBuffer, 0, SetReportBuffer.Length)
                            success = True
                        Else
                            CloseCommunications()
                            lstResults.Items.Add("The attempt to read an Input report has failed.")
                        End If
    
    
                        If success Then
    
                            lstResults.Items.Add("An Output report has been written.")
    
                            ' Display the report data in the form's list box.
    
                            lstResults.Items.Add(" Output Report ID: " & String.Format("{0:X2} ", SetReportBuffer(0)))
                            lstResults.Items.Add(" Output Report Data:")
    
                            For count = 1 To UBound(SetReportBuffer)
    
                                ' Display bytes as 2-character hex strings.
    
                                byteValue = String.Format("{0:X2} ", SetReportBuffer(count))
                                lstResults.Items.Add(" " & byteValue)
    
                            Next count
                        Else
                            CloseCommunications()
                            lstResults.Items.Add("The attempt to write an Output report failed.")
                        End If
    
                        ' Enable requesting another transfer.
    
                        AccessForm("EnableCmdOnce", "")
    
                    Else
                        lstResults.Items.Add("The HID doesn't have an Output report.")
                    End If
    
                Else
                    lstResults.Items.Add("Invalid handle. The device is probably a system mouse or keyboard.")
                    lstResults.Items.Add("No attempt to write an Output report or read an Input report was made.")
                    AccessForm("EnableCmdOnce", "")
                End If
    
                ScrollToBottomOfListBox()
    
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        Private Sub ExchangeInputReports()
    
            Dim byteValue As String
            Dim count As Int32
            Dim success As Boolean
    
            Try
                success = False
    
                ' Don't attempt to exchange reports if valid handles aren't available
                ' (as for a mouse or keyboard under Windows 2000/XP.)
    
                If (Not (hidHandle.IsInvalid)) Then
    
                    ' Read an Input report.
    
                    success = False
    
                    ' Don't attempt to send an Input report if the HID has no Input report.
                    ' (The HID spec requires all HIDs to have an interrupt IN endpoint,
                    ' which suggests that all HIDs must support Input reports.)
    
                    If (MyHid.Capabilities.InputReportByteLength > 0) Then
    
                        ' Set the size of the Input report buffer. 
                        ' Subtract 1 from the value in the Capabilities structure because 
                        ' the array begins at index 0.
    
                        Array.Resize(GetReportBuffer, MyHid.Capabilities.InputReportByteLength)
    
    
                        ' Read a report using a control transfer.
    
                        success = MyHid.GetInputReportViaControlTransfer(hidHandle, GetReportBuffer)
    
                        If success Then
                            lstResults.Items.Add("An Input report has been read.")
    
                            ' Display the report data received in the form's list box.
    
                            lstResults.Items.Add(" Input Report ID: " & String.Format("{0:X2} ", GetReportBuffer(0)))
                            lstResults.Items.Add(" Input Report Data:")
    
                            'txtBytesReceived.Text = ""
                            For count = 1 To UBound(GetReportBuffer)
    
                                ' Display bytes as 2-character Hex strings.
    
                                byteValue = String.Format("{0:X2} ", GetReportBuffer(count))
    
                                lstResults.Items.Add(" " & byteValue)
    
                                ' Display the received bytes in the text box.
    
                                'txtBytesReceived.SelectionStart = Len(txtBytesReceived.Text)
                                'txtBytesReceived.SelectedText = byteValue & vbCrLf
                            Next count
    
                        Else
                            CloseCommunications()
                            lstResults.Items.Add("The attempt to read an Input report has failed.")
    
                        End If
    
                        ScrollToBottomOfListBox()
    
                        ' Enable requesting another transfer.
    
                        AccessForm("EnableCmdOnce", "")
    
                        CTL22()
    
                    Else
                        lstResults.Items.Add("No attempt to read an Input report was made.")
                        lstResults.Items.Add("The HID doesn't have an Input report.")
                        AccessForm("EnableCmdOnce", "")
                    End If
                Else
                    lstResults.Items.Add("Invalid handle. The device is probably a system mouse or keyboard.")
                    lstResults.Items.Add("No attempt to write an Output report or read an Input report was made.")
                    AccessForm("EnableCmdOnce", "")
                End If
    
                ScrollToBottomOfListBox()
    
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Perform shutdown operations.
        ''' </summary>
    
        Private Sub frmMain_Closed(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Closed
    
            Try
                Shutdown()
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
        End Sub
    
        ''' <summary>
        ''' Perform startup operations.
        ''' </summary>
    
        Private Sub frmMain_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
    
            Try
                FrmMy = Me
                Startup()
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Retrieves Input report data and status information.
        ''' This routine is called automatically when myInputReport.Read
        ''' returns. Calls several marshaling routines to access the main form.
        ''' </summary>
        ''' 
        ''' <param name="ar"> an object containing status information about 
        ''' the asynchronous operation. </param>
    
        Private Sub GetInputReportData(ByVal ar As IAsyncResult)
    
            Dim byteValue As String
            Dim count As Int32
            Dim inputReportBuffer As Byte() = Nothing
    
            Try
                inputReportBuffer = CType(ar.AsyncState, Byte())
    
                fileStreamdevicedata.EndRead(ar)
    
                tmrReadTimeout.Stop()
    
                ' Display the received report data in the form's list box.
    
                If (ar.IsCompleted) Then
    
                    MyMarshalToForm("AddItemToListBox", "An Input report has been read.")
    
                    MyMarshalToForm("AddItemToListBox", " Input Report ID: " & String.Format("{0:X2} ", inputReportBuffer(0)))
    
                    MyMarshalToForm("AddItemToListBox", " Input Report Data:")
    
                    For count = 1 To UBound(inputReportBuffer)
    
                        ' Display bytes as 2-character Hex strings.
    
                        byteValue = String.Format("{0:X2} ", inputReportBuffer(count))
    
                        MyMarshalToForm("AddItemToListBox", " " & byteValue)
                        MyMarshalToForm("TextBoxSelectionStart", txtBytesReceived.Text)
                        MyMarshalToForm("AddItemToTextBox", byteValue)
    
                    Next count
    
                Else
                    MyMarshalToForm("AddItemToListBox", "The attempt to read an Input report has failed.")
                    Debug.Write("The attempt to read an Input report has failed")
                End If
    
                MyMarshalToForm("ScrollToBottomOfListBox", "")
    
                ' Enable requesting another transfer.
    
                MyMarshalToForm("EnableCmdOnce", "")
                transferInProgress = False
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Initialize the elements on the form.
        ''' </summary>
        ''' 
        Private Sub InitializeDisplay()
    
            Dim count As Int16
            Dim byteValue As String
    
            Try
                ' Create a dropdown list box for each byte to send in a report.
                ' Display the values as 2-character hex strings.
    
                For count = 0 To 255
    
                    byteValue = String.Format("{0:X2} ", count)
                    FrmMy.cboByte0.Items.Insert(count, byteValue)
                    FrmMy.cboByte1.Items.Insert(count, byteValue)
    
                Next count
    
                ' Select a default value for each box
    
                FrmMy.cboByte0.SelectedIndex = 0
                FrmMy.cboByte1.SelectedIndex = 128
    
                lstResults.Items.Add("For a more detailed event log, view debug statements in Visual Studio's Output window:")
                lstResults.Items.Add("Click Build > Configuration Manager > Active Solution Configuration > Debug > Close.")
                lstResults.Items.Add("Then click View > Output.")
                lstResults.Items.Add("")
    
                act_dis.BackColor = SystemColors.Control
                men_dis.BackColor = SystemColors.Control
                rmt_dis.BackColor = SystemColors.Control
                tx_dis.BackColor = SystemColors.Control
                hld_dis.BackColor = SystemColors.Control
                off_dis.BackColor = SystemColors.Control
                on_dis.BackColor = SystemColors.Control
                sqoff_dis.BackColor = SystemColors.Control
                Light_5_28_up.BorderColor = Color.Black
                Light_5_28_dn.BorderColor = Color.Black
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Enables accessing a form's controls from another thread 
        ''' </summary>
        ''' 
        ''' <param name="action"> a string that names the action to perform on the form </param>
        ''' <param name="textToDisplay"> text that the form displays or the code uses for 
        ''' another purpose. Actions that don't use text ignore this parameter.  </param>
    
        Private Sub MyMarshalToForm _
         (ByVal action As String, _
         ByVal textToDisplay As String)
    
            Dim args() As Object = {action, textToDisplay}
            Dim MarshalToFormDelegate As MarshalToForm
    
            ' The AccessForm routine contains the code that accesses the form.
    
            MarshalToFormDelegate = New MarshalToForm(AddressOf AccessForm)
    
            ' Execute AccessForm, passing the parameters in args.
    
            MyBase.Invoke(MarshalToFormDelegate, args)
    
        End Sub
    
        ''' <summary>
        ''' Initiates exchanging reports. 
        ''' The application sends a report and requests to read a report.
        ''' </summary>
    
        Private Sub ReadAndWriteToDevice()
    
            'Report header for the debug display:
    
            Debug.WriteLine("")
            Debug.WriteLine("***** HID Test Report *****")
            Debug.WriteLine(Today & ": " & TimeOfDay)
    
            Try
                ' If the device hasn't been detected, was removed, or timed out on a previous attempt
                ' to access it, look for the device.
    
                If (myDeviceDetected = False) Then
    
                    myDeviceDetected = FindTheHid()
    
                End If
    
                If (myDeviceDetected = True) Then
    
                    ' Get the bytes to send in a report from the combo boxes.
                    ' Increment the values if the autoincrement check box is selected.
    
                    ExchangeOutputReports()
    
                End If
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Scroll to the bottom of the list box and trim as needed.
        ''' </summary>
    
        Private Sub ScrollToBottomOfListBox()
    
            Try
                Dim count As Int32
    
                lstResults.SelectedIndex = lstResults.Items.Count - 1
    
                ' If the list box is getting too large, trim its contents by removing the earliest data.
    
                If lstResults.Items.Count > 1000 Then
    
                    For count = 1 To 500
                        lstResults.Items.RemoveAt(4)
                    Next count
    
                End If
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
        End Sub
    
        ''' <summary>
        ''' Perform actions that must execute when the program ends.
        ''' </summary>
    
        Private Sub Shutdown()
    
            Try
                CloseCommunications()
    
                ' Stop receiving notifications.
    
                MyDeviceManagement.StopReceivingDeviceNotifications(deviceNotificationHandle)
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Perform actions that must execute when the program starts.
        ''' </summary>
    
        Private Sub Startup()
    
            Try
                MyHid = New Hid()
                InitializeDisplay()
    
                tmrContinuousDataCollect = New System.Timers.Timer(1000)
                AddHandler tmrContinuousDataCollect.Elapsed, AddressOf OnDataCollect
                tmrContinuousDataCollect.Stop()
                tmrContinuousDataCollect.SynchronizingObject = Me
    
                tmrReadTimeout = New System.Timers.Timer(5000)
                AddHandler tmrReadTimeout.Elapsed, AddressOf OnReadTimeout
                tmrReadTimeout.SynchronizingObject = Me
                tmrReadTimeout.Stop()
    
                ' Default USB Vendor ID and Product ID:
    
                myVendorID = Int32.Parse("03EB", NumberStyles.AllowHexSpecifier)
                myProductID = Int32.Parse("201D", NumberStyles.AllowHexSpecifier)
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Finalize method.
        ''' </summary>
    
        Protected Overrides Sub Finalize()
            MyBase.Finalize()
        End Sub
    
        ''' <summary>
        '''  Overrides WndProc to enable checking for and handling WM_DEVICECHANGE messages.
        ''' </summary>
        ''' 
        ''' <param name="m"> a Windows Message </param>
    
        Protected Overrides Sub WndProc(ByRef m As Message)
    
            Try
                ' The OnDeviceChange routine processes WM_DEVICECHANGE messages.
    
                If m.Msg = WM_DEVICECHANGE Then
                    OnDeviceChange(m)
                End If
    
                ' Let the base form process the message.
    
                MyBase.WndProc(m)
    
            Catch ex As Exception
                DisplayException(Me.Name, ex)
                Throw
            End Try
    
        End Sub
    
        ''' <summary>
        ''' Provides a central mechanism for exception handling.
        ''' Displays a message box that describes the exception.
        ''' </summary>
        ''' 
        ''' <param name="moduleName"> the module where the exception occurred. </param>
        ''' <param name="e"> the exception </param>
    
        Shared Sub DisplayException(ByVal moduleName As String, ByVal e As Exception)
    
            Dim message As String
            Dim caption As String
    
            ' Create an error message.
    
            message = "Exception: " & e.Message & ControlChars.CrLf & _
            "Module: " & moduleName & ControlChars.CrLf & _
            "Method: " & e.TargetSite.Name
    
            caption = "Unexpected Exception"
    
            MessageBox.Show(message, caption, MessageBoxButtons.OK)
            Debug.Write(message)
    
        End Sub
    
        Private Sub cmdOnce_Rx_Click(sender As System.Object, e As System.EventArgs) Handles cmdOnce_Rx.Click
    
            ExchangeInputReports()
    
        End Sub
    
        Private Sub CTLX2_TP_selftest()
    
            Dim byteValue As String
            Dim count As Int32
    
            'CTLX2_TP First Selftest
            If myDeviceDetected = True Then
    
                SetReportBuffer(8) = &H81
                ExchangeOutputReports()
    
                SetReportBuffer(8) = &H1
                ExchangeOutputReports()
                ExchangeInputReports()
    
                If (GetReportBuffer(1) And &H1) = 0 Then
    
                    SetReportBuffer(8) = &H84
                    ExchangeOutputReports()
    
                End If
    
                ' Display the report data in the form's list box.
    
                lstResults.Items.Add(" Output Report ID: " & String.Format("{0:X2} ", SetReportBuffer(0)))
                lstResults.Items.Add(" Output Report Data:")
    
                For count = 1 To UBound(SetReportBuffer)
    
                    ' Display bytes as 2-character hex strings.
    
                    byteValue = String.Format("{0:X2} ", SetReportBuffer(count))
                    lstResults.Items.Add(" " & byteValue)
    
                Next count
    
            End If
    
        End Sub
    
        Private Sub CTL22()
    
            Select Case GetReportBuffer(8)
                Case &H2
                    txtBytesReceived.Text = ("1" & Hex(GetReportBuffer(5)) & "." & Hex(GetReportBuffer(4)))
                    'txtBytesReceived.Text = ("888" & "." & "88")
    
                Case &H4
                    SwitchState()
            End Select
    
        End Sub
    
        Private Sub SwitchState()
    
            Dim ADC_Val As Integer
    
            act_dis.BackColor = SystemColors.Control
            men_dis.BackColor = SystemColors.Control
            rmt_dis.BackColor = SystemColors.Control
            tx_dis.BackColor = SystemColors.Control
            hld_dis.BackColor = SystemColors.Control
            off_dis.BackColor = SystemColors.Control
            on_dis.BackColor = SystemColors.Control
            sqoff_dis.BackColor = SystemColors.Control
            Light_5_28_up.BorderColor = Color.Black
            Light_5_28_dn.BorderColor = Color.Black
    
            'ADC Channel check
    
            If (GetReportBuffer(1) And &H1) = &H1 Then
    
                ADC_Val = GetReportBuffer(5)
                ADC_Val = ((ADC_Val << 8) Or GetReportBuffer(4))
    
                If ADC_Val > 716 Then
    
                    off_dis.BackColor = Color.Orange
    
                Else
    
                    off_dis.BackColor = Color.Black
    
                End If
    
            End If
    
            '5V OR 28V Light bit
    
            If (((GetReportBuffer(1) And &H10) = &H10) Or ((GetReportBuffer(1) And &H20) = &H20)) Then
    
                Light_5_28_up.BorderColor = Color.Orange
                Light_5_28_dn.BorderColor = Color.Orange
    
            Else
    
                Light_5_28_up.BorderColor = Color.Black
                Light_5_28_dn.BorderColor = Color.Black
    
            End If
    
            'RMT Display
    
            If ((GetReportBuffer(3) And &H20) = &H20) Then
    
                rmt_dis.BackColor = Color.Orange
    
            Else
    
                rmt_dis.BackColor = Color.Black
    
            End If
    
        End Sub
    
    End Class
    


    • 已编辑 Shaozh 2013年10月28日 8:45
    2013年10月28日 8:40

答案

  • 已解决!

    原来是GetReportBuffer和SetReportBuffer在设置值后,又被ExchangeOutputReports和ExchangeInputReports函数内从定义长度出错

    • 已标记为答案 Shaozh 2013年10月29日 2:09
    2013年10月29日 2:09

全部回复