功能均已在windows下经过测试
串口通讯
pro文件需要添加serialport 初始化代码,包括ui
QSerialPort *serial;
QString m_strComName;
int m_iBaudRate;
int m_iDataBit;
QString m_strParity;
QString m_strStopBit;
QString m_strFlowBit;
QList<QString> *m_strRecvList;
serial = new QSerialPort;
QString description;
QString manufacturer;
QString serialNumber;
QList<QSerialPortInfo> serialPortInfos = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &serialPortInfo : serialPortInfos)
{
QStringList list;
description = serialPortInfo.description();
manufacturer = serialPortInfo.manufacturer();
serialNumber = serialPortInfo.serialNumber();
list << serialPortInfo.portName()
<< (!description.isEmpty() ? description : blankString)
<< (!manufacturer.isEmpty() ? manufacturer : blankString)
<< (!serialNumber.isEmpty() ? serialNumber : blankString)
<< serialPortInfo.systemLocation()
<< (serialPortInfo.vendorIdentifier() ? QString::number(serialPortInfo.vendorIdentifier(), 16) : blankString)
<< (serialPortInfo.productIdentifier() ? QString::number(serialPortInfo.productIdentifier(), 16) : blankString);
ui->cbCom->addItem(list.first(), list);
}
ui->cbRate->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
ui->cbRate->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
ui->cbRate->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
ui->cbRate->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
ui->cbRate->addItem(tr("Custom"));
ui->cbData->addItem(QStringLiteral("5"), QSerialPort::Data5);
ui->cbData->addItem(QStringLiteral("6"), QSerialPort::Data6);
ui->cbData->addItem(QStringLiteral("7"), QSerialPort::Data7);
ui->cbData->addItem(QStringLiteral("8"), QSerialPort::Data8);
ui->cbData->setCurrentIndex(3);
ui->cbParity->addItem(tr("None"), QSerialPort::NoParity);
ui->cbParity->addItem(tr("Even"), QSerialPort::EvenParity);
ui->cbParity->addItem(tr("Odd"), QSerialPort::OddParity);
ui->cbParity->addItem(tr("Mark"), QSerialPort::MarkParity);
ui->cbParity->addItem(tr("Space"), QSerialPort::SpaceParity);
ui->cbStop->addItem(QStringLiteral("1"), QSerialPort::OneStop);
ui->cbStop->addItem(QStringLiteral("2"), QSerialPort::TwoStop);
ui->cbFlowBit->addItem(tr("None"), QSerialPort::NoFlowControl);
ui->cbFlowBit->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
ui->cbFlowBit->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
功能方法
serial->setPortName(m_strComName);
serial->setBaudRate(m_iBaudRate);
switch (m_iDataBit) {
case 5:
serial->setDataBits(QSerialPort::Data5);
break;
case 6:
serial->setDataBits(QSerialPort::Data6);
break;
case 7:
serial->setDataBits(QSerialPort::Data7);
break;
case 8:
serial->setDataBits(QSerialPort::Data8);
break;
}
if(m_strParity=="None"){
serial->setParity(QSerialPort::NoParity);
}
else if(m_strParity=="Even"){
serial->setParity(QSerialPort::EvenParity);
}
else if(m_strParity=="Odd"){
serial->setParity(QSerialPort::OddParity);
}
else if(m_strParity=="Mark"){
serial->setParity(QSerialPort::MarkParity);
}
else if(m_strParity=="Space"){
serial->setParity(QSerialPort::SpaceParity);
}
if(m_strStopBit=="1"){
serial->setStopBits(QSerialPort::OneStop);
}
else if(m_strStopBit=="2"){
serial->setStopBits(QSerialPort::TwoStop);
}
if(m_strFlowBit=="None"){
serial->setFlowControl(QSerialPort::NoFlowControl);
}
else if(m_strFlowBit=="RTS/CTS"){
serial->setFlowControl(QSerialPort::HardwareControl);
}
else if(m_strFlowBit=="XON/XOFF"){
serial->setFlowControl(QSerialPort::SoftwareControl);
}
if (serial->open(QIODevice::ReadWrite))
{
ui->cbRate->setEnabled(false);
ui->cbData->setEnabled(false);
ui->cbFlowBit->setEnabled(false);
ui->cbParity->setEnabled(false);
ui->cbCom->setEnabled(false);
ui->cbStop->setEnabled(false);
ui->btSend->setEnabled(true);
connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData);
}
void MainWindow::readData()
{
QByteArray buf;
buf = serial->readAll();
if (!buf.isEmpty())
{
QString str = ui->tbRecv->toPlainText();
str += tr(buf);
ui->tbRecv->clear();
ui->tbRecv->append(str);
m_strRecvList->append(buf);
}
}
void MainWindow::on_btSend_clicked()
{
serial->write(ui->tbSend->toPlainText().toLocal8Bit());
}
关闭串口
serial->close();
m_strRecvList->clear();
ui->cbRate->setEnabled(true);
ui->cbData->setEnabled(true);
ui->cbFlowBit->setEnabled(true);
ui->cbParity->setEnabled(true);
ui->cbCom->setEnabled(true);
ui->cbStop->setEnabled(true);
ui->btOpenCom->setText(tr("打开串口"));
ui->btSend->setEnabled(false);
m_bIsConnect=false;
UI布局
网口通讯
pro文件需要添加network tips: 服务器模式: 打开服务器使用QTcpServer(管理服务器),接收连接的客户端套接字用QTcpSocket 客户端模式使用QTcpSocket 初始化代码
QTcpServer *m_server;
QTcpSocket *m_socket;
bool m_bIsConnect;
QString m_strTcpIP;
int m_iTcpPort;
m_server=new QTcpServer(this);
connect(m_server,&QTcpServer::newConnection,this,[=]()
{
m_socket = m_server->nextPendingConnection();
ui->tbTcpRecv->setText(ui->tbTcpRecv->toPlainText()+"\n成功和客户端建立了连
m_bIsConnect=true;
connect(m_socket,&QTcpSocket::readyRead,this,[=]()
{
QByteArray data = m_socket->readAll();
QStringList list = QString(data).split('\n', QString::SkipEmp
m_strRecvList->append(list);
for (int i = 0;i<list.count();i++) {
ui->tbTcpRecv->append("\n接收:"+list[i]);
}
});
connect(m_socket,&QTcpSocket::disconnected,this,[=]()
{
ui->tbTcpRecv->setText(ui->tbTcpRecv->toPlainText()+"\n客户端断开了
m_socket->close();
m_socket->deleteLater();
m_bIsConnect=false;
});
});
m_socket = new QTcpSocket;
connect(m_socket,&QTcpSocket::connected,this,[=]()
{
ui->tbTcpRecv->setText(ui->tbTcpRecv->toPlainText()+"\n与服务器连接成功!"
m_bIsConnect=true;
connect(m_socket,&QTcpSocket::readyRead,this,[=]()
{
QByteArray data = m_socket->readAll();
QStringList list = QString(data).split('\n', QString::SkipEmp
m_strRecvList->append(list);
for (int i = 0;i<list.count();i++) {
ui->tbTcpRecv->append("\n接收:"+list[i]);
}
});
connect(m_socket,&QTcpSocket::disconnected,this,[=]()
{
ui->tbTcpRecv->setText(ui->tbTcpRecv->toPlainText()+"\n客户端断开了
m_socket->close();
m_socket->deleteLater();
m_bIsConnect=false;
});
});
连接/监听代码:
void MainWindow::on_btTcpConnect_clicked()
{
if(ui->rbServer->isChecked())
{
try {
m_server->close();
} catch (...) {
}
QString localhost=QHostAddress(QHostAddress::LocalHost).toString();
QString any=QHostAddress(QHostAddress::AnyIPv4).toString();
m_server->listen(QHostAddress::AnyIPv4,m_iTcpPort);
}
else
{
try {
m_server->close();
m_socket->close();
} catch (...) {
}
m_socket->connectToHost(QHostAddress(m_strTcpIP),m_iTcpPort);
}
}
发送代码
if(m_bIsConnect){
m_socket->write(ui->tbTcpSend->toPlainText().toUtf8());
}
关闭代码
try {
if(m_bIsConnect){
m_server->close();
m_socket->close();
}
} catch (...) {
}
m_bIsConnect=false;
UI布局
内存拷贝
内存拷贝的双方软件一定要管理员模式打开,因为这是windows进程之间的通讯!!!!
这里使用C++的方式进行内存拷贝 引入头文件
#include "windows.h"
#include "winuser.h"
在使用的类中加入,否则会对windows的sendmessage,findwindow等函数报无法解析的外部符号错误,如下
#pragma comment (lib, "User32.lib")
在qt中要注意发送过来的字符格式,如果是宽字符/unicode(c++的LPCSTR,LPCWSTR,LPCTSTR),就需要用fromStdWString来接收,注意这个字符串长度也不一样,是默认的2倍,c++发送端如下
CString strText:
COPYDATASTRUCT cds;
memset(&cds, 0, sizeof(cds));
cds.dwData = 0;
cds.cbData = (strText.GetLength() ) * sizeof(TCHAR) + 1;
cds.lpData = (LPVOID)(LPCWSTR)(strText);
如果是短字符,1个字节为单位的ansi(c++的W2A,char*),就需要用fromStdString来接收,这个字符串的长度是默认长度,c++发送端如下
CString strText:
COPYDATASTRUCT cds;
memset(&cds, 0, sizeof(cds));
cds.dwData = 0;
cds.cbData = (strText.GetLength() ) * 1 + 1;
USES_CONVERSION;
cds.lpData = (LPVOID)W2A(strText);
c++接收端如下,不同格式ansi/unicode原理同上
LRESULT CTestCommunicationDlg::OnCopyData(WPARAM wParam,LPARAM lParam)
{
PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
LPCWSTR szNewString = (LPCWSTR)(pcds->lpData);
m_strDataRcv = (LPCWSTR)(pcds->lpData);
return 1L;
}
回到QT QT查找窗口
m_MemTargetWin = ::FindWindow(NULL, ui->tbMemTargerWinName->text().toStdWString().c_str());
if (NULL != m_MemTargetWin)
{
QMessageBox::information(this,"提示","找到名为:"+ui->tbMemTargerWinName->text()+"的窗口");
}else{
QMessageBox::warning(this,"提示","未找到名为:"+ui->tbMemTargerWinName->text()+"的窗口");
}
QT内存发送
WId wid = this->winId();
if (NULL != m_MemTargetWin)
{
std::thread th([=](){
QString command = QString("Command=ChangeCode=%1\r\n").arg(ui->tbMemSend->toPlainText());
COPYDATASTRUCT data;
data.dwData = 0;
data.cbData = command.length()*2+1;
data.lpData = command.data();
::SendMessage(m_MemTargetWin, WM_COPYDATA, (WPARAM)wid, (LPARAM)&data);
});
th.detach();
}
QT接收,在头文件中重写窗口事件消息
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE;
重写
bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
if (eventType == "windows_generic_MSG")
{
MSG* msg = reinterpret_cast<MSG*>(message);
if (msg->message == WM_APPCOMMAND || msg->message == WM_COPYDATA)
{
COPYDATASTRUCT *data ;
data = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
QString str=QString::fromStdString((char*)(data->lpData));
ui->tbMemRecv->append(str);
}
}
return QWidget::nativeEvent(eventType, message, result);
}
UI布局
|