首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

VC++ 捕獲裝置管理器啟用/禁用事件:WM_DEVICECHANGE 與 DBT_DEVICEARRIVAL 完整實作

     編輯:程式設計疑難解答

需求背景

程式需即時偵測特定裝置(如網卡)被啟用或禁用,並在 UI 更新狀態。裝置管理器能即時反映,原理是接收 Windows 發送的裝置變更廣播訊息。

核心 API:WM_DEVICECHANGE

視窗程式透過處理 WM_DEVICECHANGE 訊息,配合 DBT_DEVICEARRIVAL(裝置到達/啟用)與 DBT_DEVICEREMOVECOMPLETE(裝置移除/禁用)事件類型實現。

MFC 類向導自動生成訊息映射

// Header
afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD_PTR dwData);

// CPP
BEGIN_MESSAGE_MAP(CMyDlg, CDialogEx)
    ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()

BOOL CMyDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData) {
    PDEV_BROADCAST_HDR hdr = (PDEV_BROADCAST_HDR)dwData;
    switch (nEventType) {
        case DBT_DEVICEARRIVAL: // 裝置啟用/插入
            if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
                PDEV_BROADCAST_DEVICEINTERFACE dif = (PDEV_BROADCAST_DEVICEINTERFACE)hdr;
                // dif->dbcc_name 包含裝置介面路徑,可解析 VID/PID
                if (IsTargetDevice(dif->dbcc_name)) {
                    OnDeviceConnected(); // 自定義處理
                }
            }
            break;
        case DBT_DEVICEREMOVECOMPLETE: // 裝置禁用/拔出
            if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
                PDEV_BROADCAST_DEVICEINTERFACE dif = (PDEV_BROADCAST_DEVICEINTERFACE)hdr;
                if (IsTargetDevice(dif->dbcc_name)) {
                    OnDeviceDisconnected();
                }
            }
            break;
    }
    return TRUE;
}

關鍵輔助函數

bool IsTargetDevice(const wchar_t* devicePath) {
    // 解析 devicePath 中的 VID_XXXX&PID_YYYY
    // 或呼叫 SetupDiGetDeviceInterfaceDetail 取得詳細屬性比對
    return wcsstr(devicePath, L"VID_1234&PID_5678") != nullptr;
}

注意事項

  • 需在視窗建立前註冊裝置介面通知:RegisterDeviceNotification(m_hWnd, &filter, DEVICE_NOTIFY_WINDOW_HANDLE)。
  • 服務程式(無視窗)應使用 RegisterDeviceNotification(hService, &filter, DEVICE_NOTIFY_SERVICE_HANDLE) 並在 HandlerEx 處理 SERVICE_CONTROL_DEVICEEVENT。
  • 64 位元編譯時 DWORD_PTR 確保指標大小正確。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved