二、Qt+windows API驱动USB设备——热插拔获取对应USB设备信息

上一章介绍了如何获取USB设备信息列表。如果你详细阅读过上一篇的代码后,会发现,如果我们有同时使用两种同类型的设备,很难过滤出来,这时候我们就需要用到本章介绍的方法——热插拔获取对应USB设备信息

以下内容来自网络,未找到出处,等确定出处,改成转载。
逐行注释的版本丢了,不明白的地方可以google一下

原理是通过Qt窗口自带的消息机制过滤设备注册消息进行处理

.h
#include <qt_windows.h>
#include <Dbt.h>
.cpp
//注册设备
void Dialog::registerDevice()
{
    const GUID GUID_DEVINTERFACE_LIST[] =
    {
        { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }, //USB设备的GUID
        { 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } }
    };

    HDEVNOTIFY hDevNotify;
    DEV_BROADCAST_DEVICEINTERFACE NotifacationFiler;
    ZeroMemory(&NotifacationFiler,sizeof(DEV_BROADCAST_DEVICEINTERFACE));
    NotifacationFiler.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotifacationFiler.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;

    for (int i = 0; i < sizeof(GUID_DEVINTERFACE_LIST)/sizeof(GUID); i++) 
    {
        NotifacationFiler.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];
        hDevNotify = RegisterDeviceNotification((HANDLE)this->winId(), &NotifacationFiler, DEVICE_NOTIFY_WINDOW_HANDLE);
        if (!hDevNotify) 
        {
            qDebug() << "注册失败!";
        }
    }
}

//重写事件
bool Dialog::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 (WM_DEVICECHANGE == msgType) {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
        switch (msg->wParam) {
        case DBT_DEVICEARRIVAL:
        {
            if (DBT_DEVTYP_VOLUME == lpdb->dbch_devicetype)
            {
                PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
                if (0 == lpdbv->dbcv_flags) { //优盘
                    QString USBDisk = QString(this->firstDriveFromMask(lpdbv ->dbcv_unitmask));
                    ui->labelShowMsg->setText(QString(QStringLiteral("已检测到USB设备插入--盘符:<%1>")).arg(USBDisk));
                } else if (DBTF_MEDIA == lpdbv->dbcv_flags) {
                    qDebug() << "CD_Arrived.";
                }

            }
            else if (DBT_DEVTYP_DEVICEINTERFACE == lpdb->dbch_devicetype)
            {
                PDEV_BROADCAST_DEVICEINTERFACE pDevInf  = (PDEV_BROADCAST_DEVICEINTERFACE)lpdb;
                QString name = QString::fromWCharArray(pDevInf->dbcc_name);
                qDebug() << name;
                if (!name.isEmpty())
                {
                    if (name.contains("USBSTOR"))
                    {
                        QStringList listAll = name.split('#');
                        QStringList listInfo = listAll.at(1).split('&');
                        m_usbInfoList.append(listInfo.at(1).mid(4)); //设备制造商 3
                        m_usbInfoList.append(listInfo.at(2).mid(5)); //设备型号 4
                        m_usbInfoList.append(listInfo.at(3).mid(4)); //设备版本 5
                    }
                    else
                    {
                        m_usbInfoList.clear();
                        QStringList listAll = name.split('#');
                        QStringList listID = listAll.at(1).split('&');
                        m_usbInfoList.append(listID.at(0).right(4)); //vid 0
                        m_usbInfoList.append(listID.at(1).right(4)); //pid 1
                        m_usbInfoList.append(listAll.at(2)); //设备序列号 2
                    }
                }

                display();
            }
        }
            break;
        case DBT_DEVICEREMOVECOMPLETE:
        {
            if (DBT_DEVTYP_VOLUME == lpdb->dbch_devicetype) {
                PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
                if (0 == lpdbv->dbcv_flags) {
                    ui->labelShowMsg->setText(QString(QStringLiteral("USB设备已拔出!")));
                    QTimer::singleShot(1000, ui->labelShowMsg, SLOT(clear()));
                }

                if (DBTF_MEDIA == lpdbv->dbcv_flags) {
                    ui->labelShowMsg->setText("CD_Removed.");
                }
            }
        }
            break;
        }
    }

    return false;
}

void Dialog::display()
{
    if (m_usbInfoList.count() >= 6) {
        ui->lineEditVid->setText(m_usbInfoList.at(0));
        ui->lineEditPid->setText(m_usbInfoList.at(1));
        ui->lineEditSerialNum->setText(m_usbInfoList.at(2));
        ui->lineEditProduct->setText(m_usbInfoList.at(3));
        ui->lineEditVendorID->setText(m_usbInfoList.at(4));
        ui->lineEditProductVersion->setText(m_usbInfoList.at(5));
    } else {
        ui->lineEditVid->setText(m_usbInfoList.at(0));
        ui->lineEditPid->setText(m_usbInfoList.at(1));
        ui->lineEditSerialNum->setText(m_usbInfoList.at(2));
    }
}

char Dialog::firstDriveFromMask(ULONG unitmask)
{
    char i;
    for (i = 0; i < 26; ++i) {
        if (unitmask & 0x1) {
            break;
        }
        unitmask = unitmask >> 1;
    }

    return (i + 'A');
}
设备拔下插入输出内容
"\\\\?\\USB#VID_258A&PID_1007#5&21cd2d89&0&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"

![在这里插入图片描述](https://img-blog.csdnimg.cn/51164af8531e48b382b9e41a0a7e56f9.png

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值