本人在做USB熱插拔功能時,發現使用以往監測USB熱插拔U盤代碼時,發現msg->wParam的值一直是0x0007,包括插拔鍵盤、滑鼠都是傳回這個值,後查詢資料後可通過對所需監測裝置進行事先注冊再調用原先的函數進行監測即可實作該功能。具體實作方法如下:
頭檔案:
#include <Dbt.h>
#include <Windows.h>
#include <InitGuid.h>
第一步:注冊所需監測裝置
//給裝置注冊通知
DEV_BROADCAST_DEVICEINTERFACE Notificationfilter;
ZeroMemory(&Notificationfilter, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
Notificationfilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
Notificationfilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
//Notificationfilter.dbcc_classguid ={0x745a17a0,0x74d3,0x11d0,{0xb6,0xfe,0x00,0xa0,0xc9,0x0f,0x57,0xda}};
//Notificationfilter.dbcc_classguid = {0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b};//硬碟
//Notificationfilter.dbcc_classguid = { 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };//滑鼠
//Notificationfilter.dbcc_classguid = { 0x36FC9E60, 0xC465, 0x11CF, { 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 } };
Notificationfilter.dbcc_classguid = { 0xae18aa60,0x7f6a,0x11d4,0x97,0xdd, 0x00, 0x01, 0x02, 0x29, 0xb9, 0x59 };//USB通訊裝置
HDEVNOTIFY hDevNotify = RegisterDeviceNotificationW((HANDLE)this->winId(), &Notificationfilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (!hDevNotify)
{
qDebug() << "注冊失敗" << endl;
}
其中dbcc_classguid 的值為所需監測裝置的GUID值,在裝置管理器中查詢該裝置的VID和PID後,進入系統資料庫如下路徑查詢對應的GUID值
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\下面找裝置的VID與PID對應的項目即是GUID的值。使用此GUID可以對裝置進行讀寫
如查詢值{ae18aa60-7f6a-11d4-97dd-00010229b959}則書寫成代碼格式如下Notificationfilter.dbcc_classguid = { 0xae18aa60,0x7f6a,0x11d4,0x97,0xdd, 0x00, 0x01, 0x02, 0x29, 0xb9, 0x59 };
第二步驟:注冊完畢後檢測WM_DEVICECHANGE,進行相應的處理
/**
Description:
動态擷取裝置資訊
@param 無
@return 無
/
bool nativeEvent(const QByteArray& eventType, void message, long* result);
/***********************************************************************/
/ 動态擷取裝置資訊 /
/*******************************************************************/
bool myClass::nativeEvent(const QByteArray& eventType, void message, long result)
{
MSG msg = reinterpret_cast<MSG>(message);
int msgType = msg->message;
if (WM_DEVICECHANGE == msgType)
{
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
printf(“wParam = %#04x\n”, msg->wParam);
switch (msg->wParam)
{
case DBT_DEVICEARRIVAL: //0x8000
if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)//0x05 USB裝置 0x02 U盤
{
printf(“0x8000\n”);
StartLoadFX3DeviceThread();
printf("%s\n", QStringLiteral(“USB已連接配接”).toLocal8Bit().data());
//PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
//printf(“lpdbv->dbcv_flags = %d\n”, lpdbv->dbcv_flags);
//if (lpdbv->dbcv_flags == 0)//驅動器的類别 1- CD光牒驅動 2 - 網路驅動 0 - 硬碟、U盤
//{
// // 插入U盤,此處可以做你想做的事
// // lpdbv->dbcv_unitmask 即盤符标志位,1bit,0為A,1為B,10為C,11為D…以此類推
// QString USBDisk = QString(this->FirstDriveFromMask(lpdbv->dbcv_unitmask));
// //qDebug() << “USB_Arrived and The USBDisk is: " << USBDisk;
//}
}
//qDebug() << “DBT_DEVICEARRIVAL”;
break;
case DBT_DEVICEREMOVECOMPLETE://0x8004
if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
StartLoadFX3DeviceThread();
printf(”%s\n", QStringLiteral(“USB連接配接異常”).toLocal8Bit().data());
//PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
//if (lpdbv->dbcv_flags == 0)
//{
// //qDebug() << “USB_delete”;
//}
}
break;
default:
break;
}
return true;
}
return false;//預設傳回值
}
/U盤周遊函數/
char FirstDriveFromMask(ULONG unitmask);
char myClass::FirstDriveFromMask(ULONG unitmask)
{
char i;
for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}
return (i + 'A');
}