您的位置:首页 > 编程语言 > Qt开发

Windows平台下Qt4与Qt5检测USB设备插拔

2017-03-17 21:57 351 查看
主要是通过消息实现的,想要检测USB设备的插拔动作,需要捕获设备变动消息

在不使用Qt的情况下可以在重写窗口过程函数并在其内捕获消息并实现自己想要做的动作

Qt4

来自:http://blog.csdn.net/zhuyingqingfen/article/details/37726981

参考网上资料,通过QT 实现

[cpp] view
plain copy

 print?

#ifndef WIDGET_H  

#define WIDGET_H  

   

#include <QtGui/QWidget>  

  

#include <windows.h>  

#include <QString>  

   

class Widget : public QWidget  

{  

    Q_OBJECT  

   

public:  

    Widget(QWidget *parent = 0);  

    ~Widget();  

   

protected:  

    bool winEvent(MSG *msg, long *result);  

   

private:  

    //UsbConfig usbConfig;  

    char FirstDriveFromMask (ULONG unitmask);  

};  

   

#endif // WIDGET_H  

[cpp] view
plain copy

 print?

#include "qt_Watch/qwidget.h"  

#include <QDebug>  

  

#include <Windows.h>  

#include <dbt.h>  

  

Widget::Widget(QWidget *parent)  

    : QWidget(parent)  

{  

    setWindowFlags(Qt::Window);    //窗口以Window为父窗口  

}  

  

Widget::~Widget()  

{  

}  

  

bool Widget::winEvent(MSG *msg,long *result)  

{  

    int msgType = msg->message;  

    if(msgType == WM_DEVICECHANGE)  

    {  

        qDebug() << "收到事件 " ;  

        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;  

        switch(msg->wParam)  

        {  

        case DBT_DEVICETYPESPECIFIC:  

            {  

                qDebug() << "DBT_DEVICETYPESPECIFIC " ;  

                break;  

            }  

        case DBT_DEVICEARRIVAL:  

            if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)  

            {  

                PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;  

                if (lpdbv -> dbcv_flags == 0)  

                {  

                    // 插入U盘,此处可以做你想做的事  

                    QString USBDisk = QString(this->FirstDriveFromMask(lpdbv ->dbcv_unitmask));  

                    qDebug() << "USB_Arrived and The USBDisk is: "<<USBDisk ;  

                }  

            }  

            qDebug() << "DBT_DEVICEARRIVAL" ;  

            break;  

        case DBT_DEVICEREMOVECOMPLETE:  

            if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)  

            {  

                PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;  

                if (lpdbv -> dbcv_flags == 0)  

                {  

                    qDebug() << "USB_设备移除";  

                }  

            }  

            qDebug() << "DBT_DEVICEREMOVECOMPLETE" ;  

            break;  

        }  

    }  

    return false;  

}  

  

char Widget::FirstDriveFromMask (ULONG unitmask)  

{  

    char i;  

  

    for (i = 0; i < 26; ++i)  

    {  

        if (unitmask & 0x1)  

            break;  

        unitmask = unitmask >> 1;  

    }  

    return (i + 'A');  

}  

[cpp] view
plain copy

 print?

#include <QApplication>  

#include "qt_Watch/qwidget.h"  

  

int main(int argc,char ** argv)  

{  

    QApplication app(argc,argv);  

  

    Widget widget;  

    widget.show();  

  

    return app.exec();  

}  

Qt5
来自:http://blog.csdn.net/mhpmii/article/details/50240809

上来直接贴代码 

完整工程文件下载 
QT5 USB 插拔检测完整工程

mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <windows.h>
#include <QMainWindow>
#include <dbt.h>
#include<devguid.h>
#include<SetupAPI.h>
#include<InitGuid.h>
#include <QString>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private:
Ui::MainWindow *ui;
char FirstDriveFromMask (ULONG unitmask);

protected:
bool nativeEvent(const QByteArray & eventType, void * message, long*result);

private slots:
void on_pushButton_clicked();
};

#endif // MAINWINDOW_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <locale>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

#if 1
static const GUID GUID_DEVINTERFACE_LIST[] =
{
// GUID_DEVINTERFACE_USB_DEVICE
{ 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } },
// GUID_DEVINTERFACE_DISK
{ 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } },
// GUID_DEVINTERFACE_HID,
{ 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } },
// GUID_NDIS_LAN_CLASS
{ 0xad498944, 0x762f, 0x11d0, { 0x8d, 0xcb, 0x00, 0xc0, 0x4f, 0xc3, 0x35, 0x8c } }
//// GUID_DEVINTERFACE_COMPORT
//{ 0x86e0d1e0, 0x8089, 0x11d0, { 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73 } },
//// GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
//{ 0x4D36E978, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } },
//// GUID_DEVINTERFACE_PARALLEL
//{ 0x97F76EF0, 0xF883, 0x11D0, { 0xAF, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x5C } },
//// GUID_DEVINTERFACE_PARCLASS
//{ 0x811FC6A5, 0xF728, 0x11D0, { 0xA5, 0x37, 0x00, 0x00, 0xF8, 0x75, 0x3E, 0xD1 } }
};

//注册插拔事件
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];//GetCurrentUSBGUID();//m_usb->GetDriverGUID();

hDevNotify = RegisterDeviceNotification((HANDLE)this->winId(),&NotifacationFiler,DEVICE_NOTIFY_WINDOW_HANDLE);
if(!hDevNotify)
{
int Err = GetLastError();
qDebug() << "注册失败" <<endl;
}
//else
}
#endif

}

MainWindow::~MainWindow()
{
delete ui;
}

char MainWindow::FirstDriveFromMask(ULONG unitmask)
{
char i;
for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}
return (i + 'A');
}

bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
int msgType = msg->message;
if(msgType==WM_DEVICECHANGE)
{
//qDebug() << "Event DEVICECHANGE Happend" << endl;
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
switch (msg->wParam) {
case DBT_DEVICEARRIVAL:
if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
if(lpdbv->dbcv_flags ==0)
{
//插入u盘
QString USBDisk = QString(this->FirstDriveFromMask(lpdbv ->dbcv_unitmask));
qDebug() << "USB_Arrived and The USBDisk is: "<<USBDisk ;
ui->textBrowser->append("USB_Arrived and The USBDisk is " + USBDisk);

}
}
if(lpdb->dbch_devicetype = DBT_DEVTYP_DEVICEINTERFACE)
{
PDEV_BROADCAST_DEVICEINTERFACE pDevInf  = (PDEV_BROADCAST_DEVICEINTERFACE)lpdb;

QString strname = QString::fromWCharArray(pDevInf->dbcc_name,pDevInf->dbcc_size);

// ui->textBrowser->append("插入设备 :" + strname);
}
break;
case DBT_DEVICEREMOVECOMPLETE:
qDebug() << "设备移除" <<endl;
if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
if(lpdbv->dbcv_flags == 0)
{
//qDebug() << "USB_Removed";
ui->textBrowser->append("USB_Remove");

}
}
if(lpdb->dbch_devicetype = DBT_DEVTYP_DEVICEINTERFACE)
{
PDEV_BROADCAST_DEVICEINTERFACE pDevInf  = (PDEV_BROADCAST_DEVICEINTERFACE)lpdb;
qDebug()<< "移除设备(name):" << pDevInf->dbcc_name;
//qDebug()<< "移除设备(guid):" << pDevInf->dbcc_classguid;
qDebug()<< "移除设备(size):" << pDevInf->dbcc_size;

QString strname = QString::fromWCharArray(pDevInf->dbcc_name,pDevInf->dbcc_size);

ui->textBrowser->append("移除设备 " + strname);
}
break;
}
}
return false;

}

void MainWindow::on_pushButton_clicked()
{
ui->textBrowser->clear();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

最后留下一些说明 

qt 检测usb插拔基本上是和vc,mfc的做法是一致的,上面的代码段我也是直接从VC工程中拷贝出来的 

在QT里的做法 

1.头文件
#include <windows.h>
#include <dbt.h>
#include<devguid.h>
#include<SetupAPI.h>
#include<InitGuid.h>
1
2
3
4
5
1
2
3
4
5

2.重写QMainWindow的方法
bool nativeEvent(const QByteArray & eventType, void * message, long*result);
1
1

这里qt4和qt5可能不一样,我这是QT5的写法 

在里面处理usb插拔事件 

到这一步可以识别U盘,和部分USB设备了,但是还是不能识别usb-key

3 RegisterDeviceNotification 

注释掉了几个,要是你的设备还是不能识别,把注释掉的几个打开看看
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: