'===========标准模式============
Option ExplicitType GUID
    Data1   As Long
    Data2   As Integer
    Data3   As Integer
    Data4(7)   As Byte
End Type    '固定常数Type DEV_BROADCAST_DEVICEINTERFACE
    dbcc_size   As Long
    dbcc_devicetype   As Long
    dbcc_reserved   As Long
    dbcc_classguid   As GUID
    dbcc_name   As Long
End Type    '规定的常数Type DEV_BROADCAST_VOLUME
    dbcv_size   As Long
    dbcv_devicetype   As Long
    dbcv_reserved   As Long
    dbcv_unitmask   As Long
    dbcv_flags   As Integer
End Type    '规定的常数Const GWL_WNDPROC = -4
Const DEVICE_NOTIFY_WINDOW_HANDLE = 0
Const WM_DEVICECHANGE = &H219&
Const DBT_DEVTYP_DEVICEINTERFACE = &H5&
Const DBT_DEVTYP_VOLUME = &H2&
Const DBT_DEVICEARRIVAL = &H8000&
Const DBT_DEVICEREMOVECOMPLETE = &H8004&
Const DRIVE_REMOVABLE = 2
Const DRIVE_NO_ROOT_DIR = 1Declare Function SetWindowLongA Lib "User32.dll " (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function CallWindowProcA Lib "User32.dll " (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function RegisterDeviceNotificationA Lib "User32.dll " (ByVal hRecipient As Long, NotificationFilter As Any, ByVal Flags As Long) As Long
Declare Function UnregisterDeviceNotification Lib "User32.dll " (ByVal Handle As Long) As Long
Declare Sub RtlMoveMemory Lib "kernel32 " (Destination As Any, Source As Any, ByVal Length As Long)
Private m_hwnd     As Long
Private m_lpPrevWndProc     As Long
Private m_hDevNotify     As LongPublic Sub RegDevNotify(ByVal hwnd As Long)           '注册钩子
    Dim dbcc     As DEV_BROADCAST_DEVICEINTERFACE
    If m_lpPrevWndProc = 0 Then
          m_hwnd = hwnd
          m_lpPrevWndProc = SetWindowLongA(m_hwnd, GWL_WNDPROC, AddressOf WndProc)
          dbcc.dbcc_size = Len(dbcc)
          dbcc.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE
          m_hDevNotify = RegisterDeviceNotificationA(hwnd, dbcc, DEVICE_NOTIFY_WINDOW_HANDLE)
    End If
End SubPublic Sub UnregDevNotify()      '解除钩子
    If m_lpPrevWndProc Then
          UnregisterDeviceNotification m_hDevNotify
          SetWindowLongA m_hwnd, GWL_WNDPROC, m_lpPrevWndProc
          m_lpPrevWndProc = 0
    End If
End Sub
Private Function WndProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long                                        '消息拦截 当有消息时候会在这里出现
    If msg = WM_DEVICECHANGE Then          '当消息是 磁盘发生改变
        Debug.Print msg           '打印变量值
        Debug.Print wParam        '打印变量值
        Debug.Print lParam        '打印变量值
          If wParam = DBT_DEVICEARRIVAL Or wParam = DBT_DEVICEREMOVECOMPLETE Then                  '当标志是插入一个磁盘 或者 移动完成
                MsgBox ("USB Changed !!")
          End If
    End If
    WndProc = CallWindowProcA(m_lpPrevWndProc, m_hwnd, msg, wParam, lParam)               '返回消息给系统 否则系统所有消息都被拦截 你的电脑几乎就是废了 关机都不行
End Function'===============调用==============
Sub Form_Load()
    RegDevNotify Me.hwnd     '向系统注册一个拦截优盘状态的钩子
End SubSub Form_Unload(Cancel As Integer)
    UnregDevNotify  '解除钩子
End Sub
经过拔插USB设备,调试打印的3个变量值,其中:
msg = 537
wParam = 7(并非预期的&H8000或者&H8004)
lParam =0代码网上很多,但都试了,情况都是这样,有人说要注册什么的,但解决方法都不成功,希望在此能得到帮助,感激!

解决方案 »

  1.   

    USB插拔的系统消息肯定是可以获取到的。
      

  2.   

    按说明拷贝下面代码到新的工程,拿个U盘插拔测试一切正常!
    '===========标准模块============
    Option ExplicitType GUID
        Data1   As Long
        Data2   As Integer
        Data3   As Integer
        Data4(7)   As Byte
    End Type    '固定常数Type DEV_BROADCAST_DEVICEINTERFACE
        dbcc_size   As Long
        dbcc_devicetype   As Long
        dbcc_reserved   As Long
        dbcc_classguid   As GUID
        dbcc_name   As Long
    End Type    '规定的常数Type DEV_BROADCAST_VOLUME
        dbcv_size   As Long
        dbcv_devicetype   As Long
        dbcv_reserved   As Long
        dbcv_unitmask   As Long
        dbcv_flags   As Integer
    End Type    '规定的常数Public Const GWL_WNDPROC = -4
    Const DEVICE_NOTIFY_WINDOW_HANDLE = 0
    Const WM_DEVICECHANGE = &H219&
    Const DBT_DEVTYP_DEVICEINTERFACE = &H5&
    Const DBT_DEVTYP_VOLUME = &H2&
    Const DBT_DEVICEARRIVAL = &H8000&
    Const DBT_DEVICEREMOVECOMPLETE = &H8004&
    Const DRIVE_REMOVABLE = 2
    Const DRIVE_NO_ROOT_DIR = 1Public Declare Function SetWindowLongA Lib "User32.dll " (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Declare Function CallWindowProcA Lib "User32.dll " (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Declare Function RegisterDeviceNotificationA Lib "User32.dll " (ByVal hRecipient As Long, NotificationFilter As Any, ByVal Flags As Long) As Long
    Declare Function UnregisterDeviceNotification Lib "User32.dll " (ByVal Handle As Long) As Long
    Declare Sub RtlMoveMemory Lib "kernel32 " (Destination As Any, Source As Any, ByVal Length As Long)
    Private m_hwnd     As Long
    Private m_lpPrevWndProc     As Long
    Private m_hDevNotify     As LongPublic lpPrev As Long
    'Public Sub RegDevNotify(ByVal hwnd As Long)           '注册钩子
    '    Dim dbcc     As DEV_BROADCAST_DEVICEINTERFACE
    '    If m_lpPrevWndProc = 0 Then
    '          m_hwnd = hwnd
    '          m_lpPrevWndProc = SetWindowLongA(m_hwnd, GWL_WNDPROC, AddressOf WndProc)
    '          dbcc.dbcc_size = Len(dbcc)
    '          dbcc.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE
    '          m_hDevNotify = RegisterDeviceNotificationA(hwnd, dbcc, DEVICE_NOTIFY_WINDOW_HANDLE)
    '    End If
    'End Sub
    '
    'Public Sub UnregDevNotify()      '解除钩子
    '    If m_lpPrevWndProc Then
    '          UnregisterDeviceNotification m_hDevNotify
    '          SetWindowLongA m_hwnd, GWL_WNDPROC, m_lpPrevWndProc
    '          m_lpPrevWndProc = 0
    '    End If
    'End Sub
    Public Function WndProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long                                          '消息拦截 当有消息时候会在这里出现
        If msg = WM_DEVICECHANGE Then          '当消息是 磁盘发生改变
            Debug.Print msg        '打印变量值[/color]
            Debug.Print wParam        '打印变量值[/color]
            Debug.Print lParam      '打印变量值[/color]
    '          If wParam = DBT_DEVICEARRIVAL Or wParam = DBT_DEVICEREMOVECOMPLETE Then                  '当标志是插入一个磁盘 或者 移动完成
    '                MsgBox ("USB Changed !!")
    '          End If
        End If
        WndProc = CallWindowProcA(lpPrev, hwnd, msg, wParam, lParam)               '返回消息给系统 否则系统所有消息都被拦截 你的电脑几乎就是废了 关机都不行
    End Function''===============调用==============
    'Sub Form_Load()
    '    RegDevNotify Me.hwnd     '向系统注册一个拦截优盘状态的钩子
    'End Sub
    '
    'Sub Form_Unload(Cancel As Integer)
    '    UnregDevNotify  '解除钩子
    'End Sub'窗口代码
    Option ExplicitPrivate Sub Form_Load()
        lpPrev = SetWindowLongA(hwnd, GWL_WNDPROC, AddressOf WndProc)
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        If lpPrev <> 0 Then
            lpPrev = SetWindowLongA(hwnd, GWL_WNDPROC, lpPrev)
            lpPrev = 0
        End If
    End Sub