USB の挿入/取り外しイベントを処理する必要がある既存のアプリケーションの拡張機能を作成しています。対象のデバイスの VID/PID を知っています。RegisterDeviceNotification
ただし、ウィンドウ ハンドルにアクセスできないため、 を介してハンドルを取得する方法がない限り、あまり役立つかどうかわかりませんWINAPI
。C++ で USB の挿入/取り外しイベントを検出する最良の方法は何ですか?
Microsoft の Web サイトにあるこのサンプル コードは、 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);
}
PC は に入りますWndProc
が、USB デバイスを取り外したり挿入したりしても入りません。PC が に入ることがないようですOnDeviceChange
。ヒントをいただければ幸いです。USB デバイスの予期しない挿入/取り外しに対処する必要があります。違いがある場合、USB デバイスは Windows に対して仮想 COM ポートとして表示されます。ありがとう。
追加情報:によって返されCreateWindowEx
たクラスを使用して呼び出すと、「ウィンドウ クラスが見つかりません」というエラー メッセージが表示されて失敗します。atom
RegisterClassEx
_hWnd = CreateWindowEx( 0, (LPCTSTR)&atom, pWindowName, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );
新しいアプローチ
私もこの新しいアプローチを試みています。USB デバイスのデバイス変更通知メッセージを受信するメッセージのみのウィンドウを作成しようとしています。私は MFC、C++、および Visual Studio 2008 を使用しています。すべてがコンパイルされ、クラッシュまたはロックアップすることなく実行されますが、イベント ハンドラーがトリガーされることはありません。目的のデバイスは、仮想 COM ポートとして 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 );
}
ご意見やご提案をいただければ幸いです。詳細が不足している場合はお知らせください。喜んで追加します。ありがとう。
メッセージのみのウィンドウを新しいスレッドで開始する必要がありますか?それとも、新しいウィンドウを作成すると、新しいスレッドが自動的にスピンオフしますか?