ZBLOG

Windows QT可以识别usb接入的设备属于U盘还是鼠标吗

是的,Windows上的Qt应用程序可以识别USB接入的设备是U盘还是鼠标。以下是实现方法:

1. 使用Windows API检测USB设备

可以通过Windows的设备管理接口来获取设备信息:

#include <windows.h>
#include <dbt.h>
#include <setupapi.h>
#include <devguid.h>

class USBDetector : public QWidget
{
public:
    USBDetector(QWidget *parent = nullptr) : QWidget(parent)
    {
        // 注册接收设备变化消息
        registerForDeviceNotifications();
    }

private:
    void registerForDeviceNotifications()
    {
        DEV_BROADCAST_DEVICEINTERFACE dbch;
        ZeroMemory(&dbch, sizeof(dbch));
        dbch.dbcc_size = sizeof(dbch);
        dbch.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
        
        HDEVNOTIFY hDevNotify = RegisterDeviceNotification(
            (HANDLE)winId(), 
            &dbch, 
            DEVICE_NOTIFY_WINDOW_HANDLE
        );
    }

protected:
    bool nativeEvent(const QByteArray &eventType, void *message, long *result) override
    {
        MSG* msg = static_cast<MSG*>(message);
        if (msg->message == WM_DEVICECHANGE) {
            handleDeviceChange(msg->wParam, msg->lParam);
        }
        return QWidget::nativeEvent(eventType, message, result);
    }

    void handleDeviceChange(WPARAM wParam, LPARAM lParam)
    {
        if (wParam == DBT_DEVICEARRIVAL) {
            // 设备插入
            detectUSBDeviceType();
        }
        else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
            // 设备移除
            qDebug() << "USB device removed";
        }
    }
};

2. 检测设备类型的方法

#include <initguid.h>
#include <cfgmgr32.h>

void USBDetector::detectUSBDeviceType()
{
    HDEVINFO deviceInfoSet = SetupDiGetClassDevs(
        NULL,
        NULL,
        NULL,
        DIGCF_ALLCLASSES | DIGCF_PRESENT
    );

    if (deviceInfoSet == INVALID_HANDLE_VALUE) return;

    SP_DEVINFO_DATA deviceInfoData;
    deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, &deviceInfoData); i++) {
        
        // 获取设备描述
        char deviceDesc[256];
        if (SetupDiGetDeviceRegistryPropertyA(
            deviceInfoSet, &deviceInfoData, SPDRP_DEVICEDESC,
            NULL, (PBYTE)deviceDesc, sizeof(deviceDesc), NULL)) {
            
            QString desc = QString::fromLocal8Bit(deviceDesc);
            
            // 判断设备类型
            if (isStorageDevice(desc)) {
                qDebug() << "USB Storage Device detected:" << desc;
                emit usbStorageInserted(desc);
            }
            else if (isMouseDevice(desc)) {
                qDebug() << "Mouse Device detected:" << desc;
                emit mouseInserted(desc);
            }
            else if (isKeyboardDevice(desc)) {
                qDebug() << "Keyboard Device detected:" << desc;
                emit keyboardInserted(desc);
            }
        }
        
        // 通过设备类GUID进一步判断
        GUID classGuid;
        if (SetupDiGetDeviceRegistryProperty(
            deviceInfoSet, &deviceInfoData, SPDRP_CLASSGUID,
            NULL, (PBYTE)&classGuid, sizeof(classGuid), NULL)) {
            
            detectByClassGuid(classGuid);
        }
    }

    SetupDiDestroyDeviceInfoList(deviceInfoSet);
}

bool USBDetector::isStorageDevice(const QString &desc)
{
    return desc.contains("usb", Qt::CaseInsensitive) && 
           (desc.contains("storage", Qt::CaseInsensitive) || 
            desc.contains("disk", Qt::CaseInsensitive) ||
            desc.contains("flash", Qt::CaseInsensitive));
}

bool USBDetector::isMouseDevice(const QString &desc)
{
    return desc.contains("mouse", Qt::CaseInsensitive) ||
           desc.contains("hid-compliant mouse", Qt::CaseInsensitive);
}

bool USBDetector::isKeyboardDevice(const QString &desc)
{
    return desc.contains("keyboard", Qt::CaseInsensitive) ||
           desc.contains("hid-compliant keyboard", Qt::CaseInsensitive);
}

void USBDetector::detectByClassGuid(const GUID &classGuid)
{
    static const GUID diskClassGuid = {0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}};
    
    if (IsEqualGUID(classGuid, diskClassGuid)) {
        qDebug() << "Disk drive detected via GUID";
    }
}

3. pro文件配置

在.pro文件中添加Windows库:

QT += core gui widgets

win32 {
    LIBS += -lsetupapi -lcfgmgr32 -lole32
    
    # Windows版本设置(可选)
#   win32:greaterThan(QT_MAJOR_VERSION ,4): QT += winextras
    
}

4. 更简单的方法 - 使用QStorageInfo(仅存储设备)

#include <QStorageInfo>
#include <QTimer>

class SimpleUSBDetector : public QObject
{
public:
    SimpleUSBDetector()
    {
         //定时检查存储设备变化  
         QTimer *timer = new QTimer(this);  
         connect(timer,&QTimer :: timeout , this ,&SimpleUSBDetector :: checkRemovableDrives );  
         timer -> start(2000);  
     }  

private slots:  
     void checkRemovableDrives(){  
         auto drives=QStorageInfo :: mountedVolumes();  
         for(auto&drive:drives){  
             if(drive.isValid()&&drive.isReady()){  
                 if(drive.fileSystemType().contains("fat")||drive.fileSystemType().contains("ntfs")){   
                     qDebug()<<"Removable Drive:"<<drive.name();   
                 }   
             }   
         }   
     }   

};

⚠️注意事项:

  1. 管理员权限:某些操作可能需要管理员权限
  2. 代码签名:在生产环境中可能需要代码签名证书
  3. 兼容性:不同Windows版本可能有差异

这种方法可以准确区分U盘、鼠标、键盘等不同类型的USB设备。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=24429

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?