QT侦测HID设备的插拔
1.需要包含的头文件
#include <windows.h> #include <dbt.h> #include <WinUser.h> #include <devguid.h> #include <SetupAPI.h> #include <InitGuid.h>
2.注册HID消息
void MyClass::RegisterHid() { //给设备注册通知 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 = {0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 }}; hDevNotify = RegisterDeviceNotificationW((HANDLE)this->winId(),&Notificationfilter,DEVICE_NOTIFY_WINDOW_HANDLE); if(!hDevNotify) { } }
3.重载naviteEvent,在里面接收WM_DEVICECHANGE消息
bool MyClass::nativeEvent(const QByteArray &eventType, void *message, long *result) { Q_UNUSED(eventType); Q_UNUSED(result); MSG* msg = reinterpret_cast<MSG*>(message); int msgType = msg->message; if(msgType == WM_DEVICECHANGE) { //qDebug("Recv Event %d", msg->wParam); PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam; switch(msg->wParam) { case DBT_DEVICEARRIVAL: //设备插入 qDebug("DBT_DEVICEARRIVAL\n"); if(lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { PDEV_BROADCAST_DEVICEINTERFACE pDevInf =(PDEV_BROADCAST_DEVICEINTERFACE)lpdb; QString strHidName=QString::fromWCharArray(pDevInf->dbcc_name+4); qDebug(qPrintable(strHidName)); //IfDeviceInMyList(strHidName,true); } break; case DBT_DEVICEREMOVECOMPLETE: //设备拔出 if(lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { PDEV_BROADCAST_DEVICEINTERFACE pDevInf =(PDEV_BROADCAST_DEVICEINTERFACE)lpdb; QString strHidName=QString::fromWCharArray(pDevInf->dbcc_name+4); qDebug(qPrintable(strHidName)); //IfDeviceInMyList(strHidName,false); } qDebug("DBT_DEVICEREMOVECOMPLETE\n"); break; } } return false; }
4.得到的strHidName是设备在系统里的全路径,可以直接用hidapi打开进行操作,
也可以用QRegularExpression正则表达式分离出vid pid和描述对要侦测的vid pid进行比较
bool MyClass::IfDeviceInMouseList(QString strPath,bool bPlug) { QRegularExpression re1("HID#VID_(?<vid>\\w{4})&PID_(?<pid>\\w{4})&mi_02&col01",QRegularExpression::CaseInsensitiveOption); QRegularExpression re2("HID#VID_(?<vid>\\w{4})&PID_(?<pid>\\w{4})&mi_02&col02",QRegularExpression::CaseInsensitiveOption); QRegularExpressionMatch match1 = re1.match(strPath); QRegularExpressionMatch match2 = re2.match(strPath); int iVid = 0; int iPid = 0; int iSel = 0; QString strTmp; if (match1.hasMatch()) { strTmp = match1.captured(1); iVid = strTmp.toInt(nullptr,16); strTmp = match1.captured(2); iPid = strTmp.toInt(nullptr,16); iSel = 1; } else if (match2.hasMatch()) { strTmp = match2.captured(1); iVid = strTmp.toInt(nullptr,16); strTmp = match2.captured(2); iPid = strTmp.toInt(nullptr,16); iSel = 2; } qDebug("vid = %d, pid = %d\n",iVid,iPid); }