Qt MFC支持USB设备热插拔

17 篇文章 0 订阅
3 篇文章 0 订阅

一.某MFC开发代码:

BEGIN_MESSAGE_MAP(CHWDetectDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange)
//}}AFX_MSG_MAP
ON_WM_CONTEXTMENU()
ON_COMMAND(ID_POPUP_DISABLE, OnPopupDisable)
END_MESSAGE_MAP()

//-----------处理函数---------------

LRESULT CHWDetectDlg::OnMyDeviceChange(WPARAM wParam, LPARAM lParam)
{
if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) {
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
PDEV_BROADCAST_DEVICEINTERFACE pDevInf;
PDEV_BROADCAST_HANDLE pDevHnd;
PDEV_BROADCAST_OEM pDevOem;
PDEV_BROADCAST_PORT pDevPort;
PDEV_BROADCAST_VOLUME pDevVolume;
switch( pHdr->dbch_devicetype ) {
case DBT_DEVTYP_DEVICEINTERFACE:
pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
UpdateDevice(pDevInf, wParam);
break;


case DBT_DEVTYP_HANDLE:
pDevHnd = (PDEV_BROADCAST_HANDLE)pHdr;
break;


case DBT_DEVTYP_OEM:
pDevOem = (PDEV_BROADCAST_OEM)pHdr;
break;


case DBT_DEVTYP_PORT:
pDevPort = (PDEV_BROADCAST_PORT)pHdr;
break;


case DBT_DEVTYP_VOLUME:
pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;
break;
}
}
return 0;
}

二.说明

WM_DEVICECHANGE的使用方式有二種,一種是透過WindowProc()的方式,一種是直接在程式裡加上OnDeviceChange()的函數,底下就先介紹第二種方式。

1. 新增消息 -- 在Dialog的.cpp裡加上藍色部份:
BEGIN_MESSAGE_MAP(CDeviceMonitorDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()

注意:不添加新增消息,就不能响应OnDeviceChange函数
2.新增一個函數 -- 這是Microsoft所提供的函數型態
DECLARE_MESSAGE_MAP()
public:
afx_msg BOOL OnDeviceChange(UINT nEventType,DWORD_PTR dwData);

3.函数內容的实现

下面是以USB插入响应为例

BOOL CCLMemTestDlg::OnDeviceChange( UINT nEventType, DWORD_PTR dwData )

{   

     switch(nEventType)

     {

     case DBT_DEVICEARRIVAL:

         UpdateUsbDeviceList();

         break;

     case DBT_DEVICEREMOVECOMPLETE:

         UpdateUsbDeviceList();

         UpdateWindow();

         break;

     }

     return TRUE;

}


三.

串口热拔插监听
关于串口热拔插监听,请更多地参考
《Qt中捕获Windows消息》
《USB转串口突然拔出检测解决方案》
《USB设备监控深入分析》


代码

  1. #include <dbt.h>

  2. bool WndTest::winEvent( MSG * message, long * result )
  3. {
  4.     if( WM_DEVICECHANGE == message->message ){
  5.     }
  6.     else
  7.         goto ev_out;
  8.    
  9.     if( 0x8004 == message->wParam ){
  10.         DEV_BROADCAST_PORT *vol = (DEV_BROADCAST_PORT*)message->lParam;
  11.         QString str = QString::fromWCharArray(vol->dbcp_name); //获取要处理的串口名称

  12.         if( 3 != vol->dbcp_devicetype )
  13.             goto ev_out;
  14.        
  15.         if( m_serial ){
  16.             if( str.size() > 0 ){
  17.                 if( str.compare(cbComPort->currentText()) ==&& m_connected ){ //比较串口名称,判定是否为当前使用的串口
  18.                     closeport(); //关闭串口
  19.                     qDebug()<<"close port:"<<str;
  20.                 }
  21.             }
  22.         }
  23.     }
  24.     if( 0x8000 == message->wParam ){
  25.         DEV_BROADCAST_PORT * vol = (DEV_BROADCAST_PORT*)message->lParam; //DEV_BROADCAST_VOLUME
  26.         QString str = QString::fromWCharArray(vol->dbcp_name);
  27.             if( str.size() > 0 ){
  28.                     qDebug()<<"to open port:"<<str; //在DEBUG信息中输出要处理的串口名称
  29.             }
  30.        
  31.     }
  32. ev_out:
  33.     return false;
  34. }

Qt中,要实现多平台USB设备热插拔监测,你可以利用Qt的跨平台特性以及QSerialPort模块。QSerialPort是一个用于访问串行端口(如USB设备)的高级API,它允许你在各种操作系统上编写一致的代码。 首先,你需要在项目中包含QSerialPort库,并创建一个QSerialPort的对象来代表USB设备。下面是一些基本步骤: 1. **初始化**: 确保在你的应用程序启动时检查USB设备是否已经连接。可以使用`QSerialPortInfo`类遍历可用的串口并查找特定于USB设备名。 ```cpp QSerialPort port; foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { if (info.description().contains("USB")) { port.setPortName(info.portName()); // 接下来尝试打开端口 } } ``` 2. **打开端口**: 使用`open()`函数打开USB设备。如果端口未连接,这将失败。 ```cpp if (!port.open(QIODevice::ReadOnly | QIODevice::WriteOnly)) { qDebug() << "Failed to open serial port."; return; // 或者处理错误 } ``` 3. **监听事件**: 设置事件处理器来检测USB设备的插入和移除。你可以使用`readyRead()`、`stateChanged()`等信号。 ```cpp connect(&port, &QSerialPort::readyRead, this, &YourClass::onDataReceived); connect(&port, &QSerialPort::stateChanged, this, &YourClass::onPortStateChanged); ``` 4. **处理事件**: 根据接收到的状态改变处理不同的操作,例如数据接收、设备断开等情况。 ```cpp void YourClass::onPortStateChanged(QSerialPort::State state) { if (state == QSerialPort::Open) { // 设备已连接,开始监控 } else if (state == QSerialPort::Error) { // 处理错误 } } void YourClass::onDataReceived() { // 数据已准备好,进行相应的处理 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值