本人在做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- 光盘驱动 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');
}