我正在为一个现有应用程序编写扩展,需要处理 USB 插入/拔出事件。我知道感兴趣的设备的 VID/PID。但是,我没有访问窗口句柄的权限,所以不知道
如何修改此代码以接收 USB 插入/拔出事件?或者,我应该采取其他方式进行操作?我正在使用 Visual Studio 2008。谢谢。 附加信息 这是我目前有的代码(除去错误处理):
消息窗口是否需要在新线程中启动,还是创建一个新窗口会自动派生出一个新线程?
RegisterDeviceNotification
是否有用,除非有一种通过 WINAPI
获取句柄的方法。使用 C++ 检测 USB 插入/拔出事件的最佳方法是什么?
Microsoft 网站上的此示例代码 显示如何通过 WMI 接收事件通知:如何修改此代码以接收 USB 插入/拔出事件?或者,我应该采取其他方式进行操作?我正在使用 Visual Studio 2008。谢谢。 附加信息 这是我目前有的代码(除去错误处理):
DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, 0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);
MyClass::MyClass()
{
// Generate message-only window
_pWndClassEx = (WNDCLASSEX *)malloc( sizeof(WNDCLASSEX) );
memset( _pWndClassEx, 0, sizeof(WNDCLASSEX) );
_pWndClassEx->cbSize = sizeof(WNDCLASSEX);
_pWndClassEx->lpfnWndProc = (WNDPROC)WndProc; // function which will handle messages
_pWndClassEx->hInstance = GetCurrentModule();
_pWndClassEx->lpszClassName = pClassName;
atom = RegisterClassEx( _pWndClassEx );
_hWnd = CreateWindowEx( 0, pClassName, pWindowName, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );
// Register the USB device for notification
_pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
_pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
_pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
_pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
_hNotifyDevNode = RegisterDeviceNotification( _hWnd, _pDevIF, DEVICE_NOTIFY_WINDOW_HANDLE );
}
static bool OnDeviceChange(UINT nEventType, DWORD dwData)
{
switch ( nEventType )
{
case DBT_DEVICEARRIVAL:
// A device has been inserted adn is now available.
break;
case DBT_DEVICEREMOVECOMPLETE:
// Device has been removed.
break;
default:
break;
}
return true;
}
static LRESULT WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_DEVICECHANGE:
OnDeviceChange( wParam, lParam ); // Set breakpoint (never gets here)
break;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
我的电脑能够进入WndProc
,但是当我移除或插入我的USB设备时却不能。我的电脑似乎永远也无法进入OnDeviceChange
。如果您有任何提示,我将不胜感激。我需要处理意外的USB设备插拔。如果有区别的话,该USB设备在Windows中显示为虚拟COM端口。谢谢。
附加信息: 使用由RegisterClassEx
返回的atom
类调用CreateWindowEx
将失败,并显示错误消息“找不到窗口类”。
_hWnd = CreateWindowEx( 0, (LPCTSTR)&atom, pWindowName, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );
新方法
我也正在尝试这种新方法。我正试图创建一个仅用于接收USB设备更改通知消息的消息窗口。我使用MFC、C++和Visual Studio 2008。所有的编译都通过了,它能够运行而不崩溃或锁定,但是事件处理程序从未被触发。需要注意的是,这个感兴趣的设备在Windows上安装为虚拟串口。
我的主应用程序实例化了下面描述的类,然后等待键盘输入字符,使用while循环轮询。在此等待期间,我移除并插入我的USB设备,并期望事件将被触发。
class CMessageOnlyWindow : public CWnd
{
DECLARE_DYNAMIC(CMessageOnlyWindow)
private:
DEV_BROADCAST_DEVICEINTERFACE * _pDevIF; // The notification filter.
HDEVNOTIFY _hNotifyDev; // The device notification handle.
public:
CMessageOnlyWindow();
virtual ~CMessageOnlyWindow();
protected:
afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );
private:
void RegisterNotification( void );
void UnregisterNotification( void );
protected:
DECLARE_MESSAGE_MAP() // Must be last.
};
为了简单起见,我删除了所有的清理和错误处理:
DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, \
0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);
IMPLEMENT_DYNAMIC(CMessageOnlyWindow, CWnd)
CMessageOnlyWindow::CMessageOnlyWindow()
{
CString cstrWndClassName = ::AfxRegisterWndClass( NULL );
BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
L"CMessageOnlyWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0 );
this->RegisterNotification();
}
CMessageOnlyWindow::~CMessageOnlyWindow() {}
BEGIN_MESSAGE_MAP(CMessageOnlyWindow, CWnd)
ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()
afx_msg BOOL CMessageOnlyWindow::OnDeviceChange( UINT nEventType, DWORD dwData )
{
switch ( nEventType ) // <-- Never gets here.
{
case DBT_DEVICEARRIVAL:
break;
case DBT_DEVICEREMOVECOMPLETE:
break;
default:
break;
}
return TRUE;
}
void CMessageOnlyWindow::RegisterNotification(void)
{
_pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
_pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
_pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
_pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
_hNotifyDev = RegisterDeviceNotification( this->m_hWnd, _pDevIF, DEVICE_NOTIFY_WINDOW_HANDLE );
}
void CMessageOnlyWindow::UnregisterNotification(void)
{
UnregisterDeviceNotification( _hNotifyDev );
}
非常感谢您的想法或建议。如果有任何细节缺失,请告诉我,我很乐意添加。谢谢。消息窗口是否需要在新线程中启动,还是创建一个新窗口会自动派生出一个新线程?
java.exe
,但我不确定。也就是说,这是我附加到运行应用程序中测试我的 DLL 的进程(MSVS2008->工具->附加到进程)。 - Jim Fell