多个设备插入的通知 [英] Multiple device inserted notifications
问题描述
谁能告诉我为什么使用以下代码时会收到多个(三个或四个设备到达通知)?
Can anyone tell me why when using the following code I receive multiple (three or four device arrival notifications)?
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通知.
When a device arrives I am looking to start a thread which will detect which devices are connected to my machine. If the new device is a particular piece of hardware I am interested in (an oscilloscope) then I want to connect to this device using the corresponding driver. The issue I am having is that I get multiple DBT_DEVICEARRIVAL notifications and hence when my device is inserted my software tries to connect with it multiple times - I only want this to happen once. I have a solution to this problem using a timer but I would like to know is there is some way to only receive one DBT_DEVICEARRIVAL notification.
谢谢
推荐答案
我认为这可能对您有所帮助
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
这篇关于多个设备插入的通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!