zl程序教程

您现在的位置是:首页 >  工具

当前栏目

Qt上USB设备热插拔检测

Qt设备 检测 USB 热插拔
2023-09-14 09:07:01 时间

Qt上USB设备热插拔检测

1 头文件

#include <QWidget>
#include <dbt.h>
#include <windows.h>

2 示例代码

对于类 Form_usb头文件


#include "form_usb.h"
#include "ui_form_usb.h"

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

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

bool Form_usb::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
	Q_UNUSED(eventType);
	MSG* msg = reinterpret_cast<MSG*>(message);
	int msgType = msg->message;
	if(msgType == WM_DEVICECHANGE)
	{
		qDebug() << "Recv Event " ;
		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盘,此处可以做你想做的事
					// 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:
			if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
			{
				PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
				if (lpdbv -> dbcv_flags == 0)
				{
					qDebug() << "USB_delete";
				}
			}
			qDebug() << "DBT_DEVICEREMOVECOMPLETE" ;
			break;
		}
	}
	return false;
}

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

3. 进一步说明

主要是实现bool nativeEvent(const QByteArray &eventType, void *message, long *result);函数,来对设备的插拔事件进行监控。以上函数在Qt 5以上版本中受支持,其他版本使用的是函数
bool winEvent(MSG *message, long *result);。
对于部分事件类型现解释如下:

#define DBT_NO_DISK_SPACE 0x0047   
#define DBT_LOW_DISK_SPACE 0x0048
#define DBT_CONFIGMGPRIVATE 0x7FFF
#define DBT_DEVICEARRIVAL 0x8000    ///一个设备或者"piece of media" 已经插入并且有效
#define DBT_DEVICEQUERYREMOVE 0x8001  ///移除设备需要请求权限,任何设备可以忽略并取消该请求
#define DBT_DEVICEQUERYREMOVEFAILED 0x8002  ///取消移除设备的请求
#define DBT_DEVICEREMOVEPENDING 0x8003  ///设备将会移除,不能被忽略
#define DBT_DEVICEREMOVECOMPLETE 0x8004 ///设备移除
#define DBT_DEVICETYPESPECIFIC 0x8005
#define DBT_CUSTOMEVENT 0x8006  ///用户事件发生
#define DBT_DEVTYP_OEM 0x00000000
#define DBT_DEVTYP_DEVNODE 0x00000001
#define DBT_DEVTYP_VOLUME 0x00000002 ///逻辑卷标事件触发
#define DBT_DEVTYP_PORT 0x00000003
#define DBT_DEVTYP_NET 0x00000004
#define DBT_DEVTYP_DEVICEINTERFACE 0x00000005
#define DBT_DEVTYP_HANDLE 0x00000006
#define DBT_DEVNODES_CHANGED 0x0007 ///设备插入或者移除系统,设备节点变化