2024-10-31 16:48:38 +08:00
|
|
|
#include "appserial.h"
|
|
|
|
#include <QSerialPort>
|
|
|
|
#include <QSerialPortInfo>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QMutex>
|
|
|
|
#include <dbt.h>
|
|
|
|
|
|
|
|
AppSerial::AppSerial(QObject *parent) : QObject(parent)
|
|
|
|
{
|
|
|
|
qApp->installNativeEventFilter(this); // 安装事件过滤器
|
|
|
|
m_SerialPort = new QSerialPort;
|
|
|
|
connect(m_SerialPort, &QSerialPort::readyRead, this, &AppSerial::slot_RecvSerialData);
|
|
|
|
}
|
|
|
|
|
|
|
|
AppSerial::~AppSerial()
|
|
|
|
{
|
|
|
|
m_SerialPort->close();
|
|
|
|
delete m_SerialPort;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 获取系统中所有可用的串口名
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
QStringList AppSerial::getAvailablePort()
|
|
|
|
{
|
|
|
|
QStringList strName;
|
|
|
|
foreach(const QSerialPortInfo& info, QSerialPortInfo::availablePorts())
|
|
|
|
{
|
|
|
|
QSerialPort port(info);
|
|
|
|
if(port.open(QIODevice::ReadWrite))
|
|
|
|
{
|
|
|
|
strName << info.portName() + "(" + info.manufacturer() + ")";
|
|
|
|
// qDebug() << strName;
|
|
|
|
port.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
strName.sort();
|
|
|
|
return strName;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 设置窗口句柄用于过滤事件
|
|
|
|
* @param hwnd
|
|
|
|
*/
|
|
|
|
void AppSerial::setHWND(HWND hwnd)
|
|
|
|
{
|
|
|
|
this->m_hwnd = hwnd;
|
|
|
|
}
|
|
|
|
|
2024-11-01 11:24:09 +08:00
|
|
|
bool AppSerial::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result)
|
2024-10-31 16:48:38 +08:00
|
|
|
{
|
|
|
|
Q_UNUSED(eventType);
|
|
|
|
Q_UNUSED(result);
|
|
|
|
MSG* msg = reinterpret_cast<MSG*>(message);
|
|
|
|
int msgType = msg->message;
|
|
|
|
if (msgType == WM_DEVICECHANGE) {
|
|
|
|
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
|
|
|
|
switch (msg->wParam) {
|
|
|
|
case DBT_DEVICEARRIVAL:
|
|
|
|
/* 串口插入事件 */
|
|
|
|
if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT) {
|
|
|
|
PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;
|
|
|
|
QString portName = QString::fromWCharArray(lpdbv->dbcp_name);//插入的串口名
|
|
|
|
emit comChangeStatus(portName, true);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DBT_DEVICEREMOVECOMPLETE:
|
|
|
|
/* 串口拔出事件 */
|
|
|
|
if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT) {
|
|
|
|
PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;
|
|
|
|
QString portName = QString::fromWCharArray(lpdbv->dbcp_name);//拔出的串口名
|
|
|
|
emit comChangeStatus(portName, false);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DBT_DEVNODES_CHANGED:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AppSerial::slot_RecvSerialData()
|
|
|
|
{
|
|
|
|
QByteArray recvData = m_SerialPort->readAll();
|
|
|
|
emit sig_RecvSerialData(recvData, TypeRecvData);
|
|
|
|
// qDebug() << __FUNCTION__ << "recvData:" << recvData;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AppSerial::slot_SendSerialData(const QByteArray &sendData)
|
|
|
|
{
|
|
|
|
emit sig_RecvSerialData(sendData, TypeSendData);
|
|
|
|
qDebug() << __FUNCTION__ << "recvData:" << sendData;
|
|
|
|
m_SerialPort->write(sendData);
|
|
|
|
if (m_SerialPort->waitForBytesWritten(3000)) {
|
|
|
|
// 数据成功写入
|
|
|
|
} else {
|
|
|
|
// 写入失败
|
|
|
|
}
|
|
|
|
}
|