2013-10-31 47 views
2

誰能告訴我爲什麼當使用下面的代碼我收到多個(三個或四個設備到達通知)?多設備插入通知

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通知。

感謝

+0

你可能想看看[微軟的設備通知示例應用程序(HTTP:// msdn.microsoft.com/en-us/library/windows/desktop/aa363432%28v=vs.85%29.aspx),看看它是否有同樣的問題。 – jdigital

+0

有沒有人有任何想法?我找不到任何關於此的信息。 – thehoten

+0

只是一個小竅門......在'If m.Msg = WM_DEVICECHANGE Then'拋出一個斷點,然後在Visual Studio中運行該程序。按F11逐步瀏覽,看看它在做什麼。最終你會看到它再次被解僱的地方。雖然這可能不會直接解決您的問題,但它將證明無價。 – Skindeep2366

回答

0

我想這可能會幫助你

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 

原裝http://www.codeproject.com/Questions/546243/Howplustoplustellplusaplususerplusplusthatplusaplu