From a53b7df333ba4e118b6bed4e62cdd04938dacbb9 Mon Sep 17 00:00:00 2001 From: 18650180552 Date: Mon, 20 Sep 2021 22:37:32 +0800 Subject: [PATCH] no message --- base/framework/message_loop_proxy.h | 4 +- examples/proto_debuger/base_form.h | 2 +- examples/proto_debuger/new_monitor_form.cpp | 144 ++++++++++- examples/proto_debuger/new_monitor_form.h | 7 + examples/proto_debuger/proto_debuger.rc | 1 - examples/proto_debuger/proto_debuger.vcxproj | 3 + examples/proto_debuger/serial_port.cpp | 252 +++++++++++++++++++ examples/proto_debuger/serial_port.h | 36 +++ examples/proto_debuger/uart_process.cpp | 10 + examples/proto_debuger/uart_process.h | 23 ++ 10 files changed, 465 insertions(+), 17 deletions(-) create mode 100644 examples/proto_debuger/serial_port.cpp create mode 100644 examples/proto_debuger/serial_port.h create mode 100644 examples/proto_debuger/uart_process.cpp create mode 100644 examples/proto_debuger/uart_process.h diff --git a/base/framework/message_loop_proxy.h b/base/framework/message_loop_proxy.h index 4839fb96..c5200b35 100644 --- a/base/framework/message_loop_proxy.h +++ b/base/framework/message_loop_proxy.h @@ -148,7 +148,7 @@ private: std::function std_task_; }; }; - +/* template<> void MessageLoopProxy::PostTaskAndReplyRelay::Run() { @@ -156,7 +156,7 @@ void MessageLoopProxy::PostTaskAndReplyRelay::Run() origin_loop_->PostTask( nbase::Bind(&PostTaskAndReplyRelay::RunReplyAndSelfDestruct, this)); } - +*/ } // namespace nbase #endif // BASE_MESSAGE_LOOP_PROXY_H_ diff --git a/examples/proto_debuger/base_form.h b/examples/proto_debuger/base_form.h index ee9cbd5f..d7ac9166 100644 --- a/examples/proto_debuger/base_form.h +++ b/examples/proto_debuger/base_form.h @@ -15,7 +15,7 @@ #include "duilib/UIlib.h" #include "ui_components/ui_components.h" #include "new_monitor_form.h" - +#include "uart_process.h" class BasicForm : public ui::WindowImplBase { diff --git a/examples/proto_debuger/new_monitor_form.cpp b/examples/proto_debuger/new_monitor_form.cpp index f1e7a909..a4a4a7b5 100644 --- a/examples/proto_debuger/new_monitor_form.cpp +++ b/examples/proto_debuger/new_monitor_form.cpp @@ -1,6 +1,75 @@ #include "new_monitor_form.h" + +#include +#include +#include + +using namespace std; + const std::wstring NewMonitorForm::kClassName = L"Basic"; + +vector EnumPortsWdm() +{ + int i, dwDetDataSize; + vector ret; + TCHAR fname[256], locinfo[256]; + HDEVINFO hDevInfo; + SP_DEVICE_INTERFACE_DETAIL_DATA* pDetData; + SP_DEVICE_INTERFACE_DATA ifcData; + SP_DEVINFO_DATA devdata; + + static const GUID ___GUID_CLASS_COMPORT = \ + { 0x86E0D1E0L, 0x8089, 0x11D0, { 0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73 } }; + /*static const GUID ___GUID_CLASS_COMPORT = \ + { 0xAD498944, 0x762F, 0x11D0, { 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C } };*/ + + + hDevInfo = SetupDiGetClassDevs(&___GUID_CLASS_COMPORT, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (hDevInfo == INVALID_HANDLE_VALUE) + { + return ret; + } + + dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256; + pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)calloc(1, dwDetDataSize); + if (!pDetData) + { + SetupDiDestroyDeviceInfoList(hDevInfo); + return ret; + } + + ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + for (i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &___GUID_CLASS_COMPORT, i, &ifcData); i++) + { + memset(&devdata, 0, sizeof(SP_DEVINFO_DATA)); + devdata.cbSize = sizeof(SP_DEVINFO_DATA); + + if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifcData, pDetData, dwDetDataSize, NULL, &devdata)) + { + break; + } + + if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL, (PBYTE)fname, sizeof(fname), NULL)) + { + ret.push_back(wstring(fname)); + } + + if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL, (PBYTE)locinfo, sizeof(locinfo), NULL)) + { + if (StrCmpN(locinfo, TEXT("USB"), 3) == 0) + { + } + } + } + + free(pDetData); + SetupDiDestroyDeviceInfoList(hDevInfo); + return ret; +} + NewMonitorForm::NewMonitorForm() { @@ -40,8 +109,8 @@ void NewMonitorForm::InitWindow() return true; }); } - ui::Combo* combo_add_new = dynamic_cast(FindControl(L"combo")); - if (NULL != combo_add_new) { + m_combo_type = dynamic_cast(FindControl(L"combo_type")); + if (NULL != m_combo_type) { ui::ListContainerElement* element = new ui::ListContainerElement; element->SetClass(L"listitem"); element->SetFixedHeight(30); @@ -49,7 +118,7 @@ void NewMonitorForm::InitWindow() element->SetTextPadding({ 6,0,6,0 }); element->SetText(nbase::StringPrintf(L"")); - combo_add_new->Add(element); + m_combo_type->Add(element); element = new ui::ListContainerElement; element->SetClass(L"listitem"); @@ -58,7 +127,7 @@ void NewMonitorForm::InitWindow() element->SetTextPadding({ 6,0,6,0 }); element->SetText(nbase::StringPrintf(L"uart")); - combo_add_new->Add(element); + m_combo_type->Add(element); element = new ui::ListContainerElement; element->SetClass(L"listitem"); @@ -66,7 +135,7 @@ void NewMonitorForm::InitWindow() element->SetBkColor(L"white"); element->SetTextPadding({ 6,0,6,0 }); element->SetText(nbase::StringPrintf(L"tcp client")); - combo_add_new->Add(element); + m_combo_type->Add(element); element = new ui::ListContainerElement; element->SetClass(L"listitem"); @@ -74,7 +143,7 @@ void NewMonitorForm::InitWindow() element->SetBkColor(L"white"); element->SetTextPadding({ 6,0,6,0 }); element->SetText(nbase::StringPrintf(L"tcp server")); - combo_add_new->Add(element); + m_combo_type->Add(element); element = new ui::ListContainerElement; element->SetClass(L"listitem"); @@ -82,7 +151,7 @@ void NewMonitorForm::InitWindow() element->SetBkColor(L"white"); element->SetTextPadding({ 6,0,6,0 }); element->SetText(nbase::StringPrintf(L"udp client")); - combo_add_new->Add(element); + m_combo_type->Add(element); element = new ui::ListContainerElement; element->SetClass(L"listitem"); @@ -90,12 +159,15 @@ void NewMonitorForm::InitWindow() element->SetBkColor(L"white"); element->SetTextPadding({ 6,0,6,0 }); element->SetText(nbase::StringPrintf(L"udp server")); - combo_add_new->Add(element); + m_combo_type->Add(element); } - ui::VBox* ip_config_vbox = dynamic_cast(FindControl(L"ip_config")); - ui::VBox* uart_config_vbox = dynamic_cast(FindControl(L"uart_config")); + m_ip_config_vbox = dynamic_cast(FindControl(L"ip_config")); + m_uart_config_vbox = dynamic_cast(FindControl(L"uart_config")); - combo_add_new->AttachAllEvents([this, uart_config_vbox, ip_config_vbox](ui::EventArgs* ev) { + m_uart_select_combo = dynamic_cast(FindControl(L"uart_type")); + m_uart_baurate_select = dynamic_cast(FindControl(L"uart_baurate_select")); + + m_combo_type->AttachAllEvents([this](ui::EventArgs* ev) { if (nullptr != ev) { auto p = static_cast(ev->pSender); if (ev->Type == 42) { @@ -103,8 +175,54 @@ void NewMonitorForm::InitWindow() wprintf(L"%s\r\n", text.c_str()); if (text == L"uart") { - ip_config_vbox->SetVisible(true); - uart_config_vbox->SetVisible(false); + this->m_ip_config_vbox->SetVisible(false); + this->m_uart_config_vbox->SetVisible(true); + auto ports = EnumPortsWdm(); + this->m_uart_select_combo->RemoveAll(); + for (auto x : ports) { + ui::ListContainerElement* element = new ui::ListContainerElement; + element->SetClass(L"listitem"); + element->SetFixedHeight(30); + element->SetBkColor(L"white"); + element->SetTextPadding({ 6,0,6,0 }); + element->SetText(nbase::StringPrintf(L"%s", &x.c_str()[x.find(L"COM")])); + + this->m_uart_select_combo->Add(element); + } + vector baurate; + baurate.push_back(L"110"); + baurate.push_back(L"300"); + baurate.push_back(L"600"); + baurate.push_back(L"1200"); + baurate.push_back(L"2400"); + baurate.push_back(L"4800"); + baurate.push_back(L"9600"); + baurate.push_back(L"14400"); + baurate.push_back(L"19200"); + baurate.push_back(L"38400"); + baurate.push_back(L"56000"); + baurate.push_back(L"57600"); + baurate.push_back(L"115200"); + + baurate.push_back(L"128000"); + baurate.push_back(L"256000"); + + m_uart_baurate_select->RemoveAll(); + for (auto baus : baurate) { + ui::ListContainerElement* element = new ui::ListContainerElement; + element->SetClass(L"listitem"); + element->SetFixedHeight(30); + element->SetBkColor(L"white"); + element->SetTextPadding({ 6,0,6,0 }); + element->SetText(nbase::StringPrintf(L"%s", baus.c_str())); + this->m_uart_baurate_select->Add(element); + } + + } + if ((text == L"tcp client")|| (text == L"tcp server") || + (text == L"udp client") || (text == L"udp server")) { + this->m_ip_config_vbox->SetVisible(true); + this->m_uart_config_vbox->SetVisible(false); } } } diff --git a/examples/proto_debuger/new_monitor_form.h b/examples/proto_debuger/new_monitor_form.h index f9a94481..e5cc41a1 100644 --- a/examples/proto_debuger/new_monitor_form.h +++ b/examples/proto_debuger/new_monitor_form.h @@ -41,5 +41,12 @@ public: virtual LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); static const std::wstring kClassName; +private: + ui::VBox* m_ip_config_vbox; + ui::VBox* m_uart_config_vbox; + ui::Combo* m_uart_select_combo; + ui::Combo* m_uart_baurate_select; + ui::Combo* m_combo_type; + }; diff --git a/examples/proto_debuger/proto_debuger.rc b/examples/proto_debuger/proto_debuger.rc index 9339e3e0..e56bc430 100644 --- a/examples/proto_debuger/proto_debuger.rc +++ b/examples/proto_debuger/proto_debuger.rc @@ -57,7 +57,6 @@ END // THEME // -IDR_THEME2 THEME "E:\\NIM_Duilib_Framework\\examples\\proto_debuger\\Release\\resources.zip" #endif // 中文(简体,中国) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/examples/proto_debuger/proto_debuger.vcxproj b/examples/proto_debuger/proto_debuger.vcxproj index 01103b6e..731d8ac0 100644 --- a/examples/proto_debuger/proto_debuger.vcxproj +++ b/examples/proto_debuger/proto_debuger.vcxproj @@ -97,6 +97,7 @@ Windows true LinkVerbose + Setupapi.lib;%(AdditionalDependencies) @@ -159,12 +160,14 @@ + + diff --git a/examples/proto_debuger/serial_port.cpp b/examples/proto_debuger/serial_port.cpp new file mode 100644 index 00000000..eb20b3ac --- /dev/null +++ b/examples/proto_debuger/serial_port.cpp @@ -0,0 +1,252 @@ +#include "serial_port.h" + + + +#include +#include + +#include +#include +#include +using namespace std; + +SerialPort::SerialPort() +{ + +} + +SerialPort::~SerialPort() +{ + +} + +bool SerialPort::open(const char* portname, + int baudrate, + char parity, + char databit, + char stopbit, + char synchronizeflag) +{ + this->synchronizeflag = synchronizeflag; + HANDLE hCom = NULL; + if (this->synchronizeflag) + { + //同步方式 + hCom = CreateFileA(portname, //串口名 + GENERIC_READ | GENERIC_WRITE, //支持读写 + 0, //独占方式,串口不支持共享 + NULL,//安全属性指针,默认值为NULL + OPEN_EXISTING, //打开现有的串口文件 + 0, //0:同步方式,FILE_FLAG_OVERLAPPED:异步方式 + NULL);//用于复制文件句柄,默认值为NULL,对串口而言该参数必须置为NULL + } + else + { + //异步方式 + hCom = CreateFileA(portname, //串口名 + GENERIC_READ | GENERIC_WRITE, //支持读写 + 0, //独占方式,串口不支持共享 + NULL,//安全属性指针,默认值为NULL + OPEN_EXISTING, //打开现有的串口文件 + FILE_FLAG_OVERLAPPED, //0:同步方式,FILE_FLAG_OVERLAPPED:异步方式 + NULL);//用于复制文件句柄,默认值为NULL,对串口而言该参数必须置为NULL + } + + if (hCom == (HANDLE)-1) + { + return false; + } + + //配置缓冲区大小 + if (!SetupComm(hCom, 1024, 1024)) + { + return false; + } + + // 配置参数 + DCB p; + memset(&p, 0, sizeof(p)); + p.DCBlength = sizeof(p); + p.BaudRate = baudrate; // 波特率 + p.ByteSize = databit; // 数据位 + + switch (parity) //校验位 + { + case 0: + p.Parity = NOPARITY; //无校验 + break; + case 1: + p.Parity = ODDPARITY; //奇校验 + break; + case 2: + p.Parity = EVENPARITY; //偶校验 + break; + case 3: + p.Parity = MARKPARITY; //标记校验 + break; + } + + switch (stopbit) //停止位 + { + case 1: + p.StopBits = ONESTOPBIT; //1位停止位 + break; + case 2: + p.StopBits = TWOSTOPBITS; //2位停止位 + break; + case 3: + p.StopBits = ONE5STOPBITS; //1.5位停止位 + break; + } + + if (!SetCommState(hCom, &p)) + { + // 设置参数失败 + return false; + } + + //超时处理,单位:毫秒 + //总超时=时间系数×读或写的字符数+时间常量 + COMMTIMEOUTS TimeOuts; + TimeOuts.ReadIntervalTimeout = 1000; //读间隔超时 + TimeOuts.ReadTotalTimeoutMultiplier = 500; //读时间系数 + TimeOuts.ReadTotalTimeoutConstant = 5000; //读时间常量 + TimeOuts.WriteTotalTimeoutMultiplier = 500; // 写时间系数 + TimeOuts.WriteTotalTimeoutConstant = 2000; //写时间常量 + SetCommTimeouts(hCom, &TimeOuts); + + PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);//清空串口缓冲区 + + memcpy(pHandle, &hCom, sizeof(hCom));// 保存句柄 + + return true; +} + +void SerialPort::close() +{ + HANDLE hCom = *(HANDLE*)pHandle; + CloseHandle(hCom); +} + +int SerialPort::send(string dat) +{ + HANDLE hCom = *(HANDLE*)pHandle; + + if (this->synchronizeflag) + { + // 同步方式 + DWORD dwBytesWrite = dat.length(); //成功写入的数据字节数 + BOOL bWriteStat = WriteFile(hCom, //串口句柄 + (char*)dat.c_str(), //数据首地址 + dwBytesWrite, //要发送的数据字节数 + &dwBytesWrite, //DWORD*,用来接收返回成功发送的数据字节数 + NULL); //NULL为同步发送,OVERLAPPED*为异步发送 + if (!bWriteStat) + { + return 0; + } + return dwBytesWrite; + } + else + { + //异步方式 + DWORD dwBytesWrite = dat.length(); //成功写入的数据字节数 + DWORD dwErrorFlags; //错误标志 + COMSTAT comStat; //通讯状态 + OVERLAPPED m_osWrite; //异步输入输出结构体 + + //创建一个用于OVERLAPPED的事件处理,不会真正用到,但系统要求这么做 + memset(&m_osWrite, 0, sizeof(m_osWrite)); + m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, L"WriteEvent"); + + ClearCommError(hCom, &dwErrorFlags, &comStat); //清除通讯错误,获得设备当前状态 + BOOL bWriteStat = WriteFile(hCom, //串口句柄 + (char*)dat.c_str(), //数据首地址 + dwBytesWrite, //要发送的数据字节数 + &dwBytesWrite, //DWORD*,用来接收返回成功发送的数据字节数 + &m_osWrite); //NULL为同步发送,OVERLAPPED*为异步发送 + if (!bWriteStat) + { + if (GetLastError() == ERROR_IO_PENDING) //如果串口正在写入 + { + WaitForSingleObject(m_osWrite.hEvent, 1000); //等待写入事件1秒钟 + } + else + { + ClearCommError(hCom, &dwErrorFlags, &comStat); //清除通讯错误 + CloseHandle(m_osWrite.hEvent); //关闭并释放hEvent内存 + return 0; + } + } + return dwBytesWrite; + } +} + +string SerialPort::receive() +{ + HANDLE hCom = *(HANDLE*)pHandle; + string rec_str = ""; + char buf[1024]; + if (this->synchronizeflag) + { + //同步方式 + DWORD wCount = 1024; //成功读取的数据字节数 + BOOL bReadStat = ReadFile(hCom, //串口句柄 + buf, //数据首地址 + wCount, //要读取的数据最大字节数 + &wCount, //DWORD*,用来接收返回成功读取的数据字节数 + NULL); //NULL为同步发送,OVERLAPPED*为异步发送 + for (int i = 0; i < 1024; i++) + { + if (buf[i] != -52) + rec_str += buf[i]; + else + break; + } + return rec_str; + } + else + { + //异步方式 + DWORD wCount = 1024; //成功读取的数据字节数 + DWORD dwErrorFlags; //错误标志 + COMSTAT comStat; //通讯状态 + OVERLAPPED m_osRead; //异步输入输出结构体 + + //创建一个用于OVERLAPPED的事件处理,不会真正用到,但系统要求这么做 + memset(&m_osRead, 0, sizeof(m_osRead)); + m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, L"ReadEvent"); + + ClearCommError(hCom, &dwErrorFlags, &comStat); //清除通讯错误,获得设备当前状态 + if (!comStat.cbInQue)return 0; //如果输入缓冲区字节数为0,则返回false + //std::cout << comStat.cbInQue << std::endl; + BOOL bReadStat = ReadFile(hCom, //串口句柄 + buf, //数据首地址 + wCount, //要读取的数据最大字节数 + &wCount, //DWORD*,用来接收返回成功读取的数据字节数 + &m_osRead); //NULL为同步发送,OVERLAPPED*为异步发送 + if (!bReadStat) + { + if (GetLastError() == ERROR_IO_PENDING) //如果串口正在读取中 + { + //GetOverlappedResult函数的最后一个参数设为TRUE + //函数会一直等待,直到读操作完成或由于错误而返回 + GetOverlappedResult(hCom, &m_osRead, &wCount, TRUE); + } + else + { + ClearCommError(hCom, &dwErrorFlags, &comStat); //清除通讯错误 + CloseHandle(m_osRead.hEvent); //关闭并释放hEvent的内存 + return 0; + } + } + for (int i = 0; i < 1024; i++) + { + if (buf[i] != -52) + rec_str += buf[i]; + else + break; + } + return rec_str; + } +} \ No newline at end of file diff --git a/examples/proto_debuger/serial_port.h b/examples/proto_debuger/serial_port.h new file mode 100644 index 00000000..a421105f --- /dev/null +++ b/examples/proto_debuger/serial_port.h @@ -0,0 +1,36 @@ +#pragma once + +#include +using namespace std; + +class SerialPort +{ + +public: + SerialPort(); + ~SerialPort(); + + // 打开串口,成功返回true,失败返回false + // portname(串口名): 在Windows下是"COM1""COM2"等,在Linux下是"/dev/ttyS1"等 + // baudrate(波特率): 9600、19200、38400、43000、56000、57600、115200 + // parity(校验位): 0为无校验,1为奇校验,2为偶校验,3为标记校验 + // databit(数据位): 4-8,通常为8位 + // stopbit(停止位): 1为1位停止位,2为2位停止位,3为1.5位停止位 + // synchronizable(同步、异步): 0为异步,1为同步 + bool Open(const char* portname, int baudrate = 115200, char parity = 0, char databit = 8, char stopbit = 1, char synchronizeflag = 0); + + //关闭串口,参数待定 + void Close(); + + //发送数据或写数据,成功返回发送数据长度,失败返回0 + int Send(string dat); + + //接受数据或读数据,成功返回读取实际数据的长度,失败返回0 + string Receive(); + +private: + int pHandle[16]; + char synchronizeflag; + +}; + diff --git a/examples/proto_debuger/uart_process.cpp b/examples/proto_debuger/uart_process.cpp new file mode 100644 index 00000000..37f52b6c --- /dev/null +++ b/examples/proto_debuger/uart_process.cpp @@ -0,0 +1,10 @@ +#include "uart_process.h" + +UartForm::UartForm() +{ +} + +void UartForm::Init() +{ + +} diff --git a/examples/proto_debuger/uart_process.h b/examples/proto_debuger/uart_process.h new file mode 100644 index 00000000..90316d84 --- /dev/null +++ b/examples/proto_debuger/uart_process.h @@ -0,0 +1,23 @@ +#pragma once + + +// C runtime header +#include +#include +#include +#include + +// base header +#include "base/base.h" + +// duilib +#include "duilib/UIlib.h" + +class UartForm : public ui::ChildBox +{ +public: + UartForm(); + /// 重写父类方法,提供个性化功能,请参考父类声明 + virtual void Init() override; +}; +