4

谁能告诉我为什么在使用以下代码时我收到多个(三个或四个设备到达通知)?

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    Const WM_DEVICECHANGE As Integer = &H219
    Const DBT_DEVICEARRIVAL As Integer = &H8000
    Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004

    If m.Msg = WM_DEVICECHANGE Then
        If m.WParam.ToInt32() = DBT_DEVICEARRIVAL then

          messagebox.show("Device arrived")

        ElseIf m.WParam.ToInt32 = DBT_DEVICEREMOVECOMPLETE And valid = True Then
           messagebox.show("device left")
        End If
    End If


    MyBase.WndProc(m)

End Sub

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Public Structure DEV_BROADCAST_DEVICEINTERFACE
    Public dbcc_size As Integer
    Public dbcc_devicetype As Integer
    Public dbcc_reserved As Integer
    <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.U1, SizeConst:=16)> _
    Public dbcc_classguid As Byte()

    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)> _
    Public dbcc_name As Char()
End Structure


Public Sub RegisterDeviceNotification()
    Dim usb_id As String = "745dd1a8-fca4-4659-9df2-954176705158"
    Dim deviceInterface As New DEV_BROADCAST_DEVICEINTERFACE()
    Dim size As Integer = Marshal.SizeOf(deviceInterface)
    deviceInterface.dbcc_size = size
    deviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE
    deviceInterface.dbcc_reserved = 0
    deviceInterface.dbcc_classguid = New Guid(usb_id).ToByteArray
    Dim buffer As IntPtr = Nothing
    buffer = Marshal.AllocHGlobal(size)
    Marshal.StructureToPtr(deviceInterface, buffer, True)
    rPS4000 = RegisterDeviceNotification(Me.Handle, buffer, _
                            DEVICE_NOTIFY_WINDOW_HANDLE Or _
                            DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)

End Sub

当设备到达时,我希望启动一个线程来检测哪些设备连接到我的机器。如果新设备是我感兴趣的特定硬件(示波器),那么我想使用相应的驱动程序连接到该设备。我遇到的问题是我收到多个 DBT_DEVICEARRIVAL 通知,因此当我的设备被插入时,我的软件会尝试多次连接它——我只希望这种情况发生一次。我有一个使用计时器来解决这个问题的方法,但我想知道是否有某种方法可以只接收一个 DBT_DEVICEARRIVAL 通知。

谢谢

4

1 回答 1

-1

I think this might help you

Imports System.Runtime.InteropServices
Public Class Form1
    'Used to detected if any of the messages are any of these constants values.
    Private Const WM_DEVICECHANGE As Integer = &H219
    Private Const DBT_DEVICEARRIVAL As Integer = &H8000
    Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
    Private Const DBT_DEVTYP_VOLUME As Integer = &H2  '
    '
    'Get the information about the detected volume.
    Private Structure DEV_BROADCAST_VOLUME
        Dim Dbcv_Size As Integer
        Dim Dbcv_Devicetype As Integer
        Dim Dbcv_Reserved As Integer
        Dim Dbcv_Unitmask As Integer
        Dim Dbcv_Flags As Short
    End Structure

    Protected Overrides Sub WndProc(ByRef M As System.Windows.Forms.Message)
        '
        'These are the required subclassing codes for detecting device based removal and arrival.
        '
        If M.Msg = WM_DEVICECHANGE Then
            Select Case M.WParam
                '
                'Check if a device was added.
                Case DBT_DEVICEARRIVAL
                    Dim DevType As Integer = Runtime.InteropServices.Marshal.ReadInt32(M.LParam, 4)
                    If DevType = DBT_DEVTYP_VOLUME Then
                        Dim Vol As New DEV_BROADCAST_VOLUME
                        Vol = Runtime.InteropServices.Marshal.PtrToStructure(M.LParam, GetType(DEV_BROADCAST_VOLUME))
                        If Vol.Dbcv_Flags = 0 Then
                            For i As Integer = 0 To 20
                                If Math.Pow(2, i) = Vol.Dbcv_Unitmask Then
                                    Dim Usb As String = Chr(65 + i) + ":\"
                                    MsgBox("Looks like a USB device was plugged in!" & vbNewLine & vbNewLine & "The drive letter is: " & Usb.ToString)
                                    Exit For
                                End If
                            Next
                        End If
                    End If
                    '
                    'Check if the message was for the removal of a device.
                Case DBT_DEVICEREMOVECOMPLETE
                    Dim DevType As Integer = Runtime.InteropServices.Marshal.ReadInt32(M.LParam, 4)
                    If DevType = DBT_DEVTYP_VOLUME Then
                        Dim Vol As New DEV_BROADCAST_VOLUME
                        Vol = Runtime.InteropServices.Marshal.PtrToStructure(M.LParam, GetType(DEV_BROADCAST_VOLUME))
                        If Vol.Dbcv_Flags = 0 Then
                            For i As Integer = 0 To 20
                                If Math.Pow(2, i) = Vol.Dbcv_Unitmask Then
                                    Dim Usb As String = Chr(65 + i) + ":\"
                                    MsgBox("Looks like a volume device was removed!" & vbNewLine & vbNewLine & "The drive letter is: " & Usb.ToString)
                                    Exit For
                                End If
                            Next
                        End If
                    End If
            End Select
        End If
        MyBase.WndProc(M)
    End Sub
End Class

Original from http://www.codeproject.com/Questions/546243/Howplustoplustellplusaplususerplusplusthatplusaplu

于 2015-01-29T23:29:48.187 回答