wxWidgets教程(11)——App与进程管理
来源:互联网 发布:高校财经数据库 编辑:程序博客网 时间:2024/05/20 12:22
一、wxApp与wxAppConsole介绍
1、创建一个自己的MyApp继承自wxApp。文档上说,必须重写OnInit方法。
然后在头文件中,调用wxDECLARE_APP;在cpp文件中,调用wxIMPLEMENT_APP。
前者可以让你在其他文件中使用wxGetApp来获得App的实例。
后者可以创建App的实例。
2、wxApp有很多可以重载的虚函数,比如
OnExit:程序结束调用。
ProcessPendingEvents:QueueEvent与AddPendingEvent发送的事件,由此调用处理。
OnAssertFailure:wxASSERT判断失败会调用。
很多函数不太常用。
二、事件wxEvtHandler
1、Connect | DisConnect : 动态绑定事件与控件。
2、QueueEvent:工作线程向主窗口线程,异步发送事件,一般发送wxThreadEvent事件的clone版本,易携带wxString。
3、AddPendingEvent:和QueueEvent差不多,只是不能携带wxString。
三、wxExecute与wxProcess
1、wxExecute的参数之中有wxProcess,用来沟通主进程与子进程之间的通信管道,在做参数之前,需要调用wxProcess-》Redirect函数。
2、调用Kill与Open可以终止一个进程和执行一个cmd命令。
3、wxEXEC_ASYNC:异步调用子程序,wxProcess进程结束以后会自动销毁,不需要delete,wxExecute返回值为进程的id(pid)。
4、wxEXEC_SYNC:同步调用子程序,阻塞我们的应用程序,直到wxProcess结束,需要手动delete掉wxProcess,wxExecute返回值为进程的退出码。
5、通过wxProcess来获取子进程的标准输出流wxInputStream,要注意,异步调用的话,一旦子进程退出,wxProcess就被删除了,那么再去获取wxInputStream会报异常;同步调用的话,子进程退出,但是wxProcess并没有被删除,而是等待我们自己来删除,所以还是能获取到wxInputStream的。
6、为了解决wxProcess在异步调用下,仍然能获取到输出流,可以定义个成员变量缓冲区,在wxExecute调用后立即获取wxInputStream,并把所有的数据拷贝到成员变量缓冲区,留着以后使用。
四、wxSingleInstanceChecker
这个类可以实现单一进程。
下面是实际当中的使用示例:
MyApp的头文件:
#pragma once#define wxUSE_GUI 0#include <wx/app.h>#include <wx/cmdline.h>#include <wx/snglinst.h>#include <wx/dynlib.h>#include <wx/process.h>wxDECLARE_EVENT(wxMY_EVT_1, wxThreadEvent);class MyApp :public wxAppConsole{public:virtual bool OnInit() override;virtual int OnExit() override;virtual int FilterEvent(wxEvent& event) override;virtual void OnInitCmdLine(wxCmdLineParser& parser) override;virtual bool OnCmdLineParsed(wxCmdLineParser& parser) override;virtual bool OnCmdLineHelp(wxCmdLineParser& parser) override;virtual bool OnCmdLineError(wxCmdLineParser& parser) override;protected:wxSingleInstanceChecker * m_checker;wxProcess * m_process;wxDynamicLibrary m_dynlib;};wxDECLARE_APP(MyApp);
MyApp的cpp文件
#include "MyApp.h"#include <iostream>#include <thread>wxDEFINE_EVENT(wxMY_EVT_1, wxThreadEvent);wxIMPLEMENT_APP(MyApp);bool MyApp::OnInit(){// 单一进程实例的实现,必须在堆上新建checker,保持活性才会让另一个进程检测到m_checker = new wxSingleInstanceChecker();if (m_checker->IsAnotherRunning()) {delete m_checker;m_checker = nullptr;return false;}// 获取User32.dll的MessageBox方法if (m_dynlib.Load(wxT("User32.dll"))) {if (m_dynlib.HasSymbol(wxT("MessageBoxA"))) {using msgBoxType = int __stdcall(int, const wchar_t*, const wchar_t*, int);msgBoxType* msgBox = (msgBoxType*)m_dynlib.GetSymbolAorW(wxT("MessageBox"));msgBox(NULL, wxT("消息内容"), wxT("消息标题"), 0);}}// wxProcess使用,异步读取另一个程序的标准输出m_process = new wxProcess(this);m_process->Redirect();wxExecute(wxT("cmd /k \"D:\\cpp\\pro\\win32demo1\\Debug\\win32demo1.exe\""),wxEXEC_ASYNC, m_process);wxTextInputStream tis(*(process->GetInputStream()));wxString buf = tis.ReadLine();// 临时开启一个detach线程,来模拟发送线程事件std::thread t([this]() {wxThreadEvent evt(wxMY_EVT_1);evt.SetString(wxT("I am a thread."));this->QueueEvent(evt.Clone());});t.detach();// 调用父类默认的初始化函数,初始化一些命令行参数注入等return __super::OnInit();}int MyApp::OnExit(){delete m_checker;return 0;}int MyApp::FilterEvent(wxEvent& event){if (event.GetEventType() == wxMY_EVT_1) {wxThreadEvent * evt = (wxThreadEvent *)&event;wxLogDebug(wxT("Recieve a thread event string: %s"), evt->GetString());}return __super::FilterEvent(event);}void MyApp::OnInitCmdLine(wxCmdLineParser& parser){parser.AddOption(wxT("m"), wxT("name"), wxT("your real name"), wxCMD_LINE_VAL_STRING);parser.AddOption(wxT("n"), wxT("age"), wxT("your real age"), wxCMD_LINE_VAL_NUMBER);// 默认为/作为选项的前缀的,可以修改为-为前缀parser.SetSwitchChars(wxT("-"));// 调用基类,提供了一些标准的选项或参数,诸如--help等等__super::OnInitCmdLine(parser);}bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser){//获取m参数wxString param_m;if (parser.Found(wxT("m"), ¶m_m)) {wxLogDebug(param_m);}//获取f参数long param_f;if (parser.Found(wxT("n"), ¶m_f)) {wxLogDebug(wxT("%d"), param_f);}// 返回false,这会让OnInit返回false来结束程序// 返回true,继续执行程序return true;}bool MyApp::OnCmdLineHelp(wxCmdLineParser& parser){std::cout << parser.GetUsageString() << std::endl;// 返回false,这会让OnInit返回false来结束程序// 返回true,继续执行程序return true;}bool MyApp::OnCmdLineError(wxCmdLineParser& parser){// 返回false,这会让OnInit返回false来结束程序// 返回true,继续执行程序return true;}
- wxWidgets教程(11)——App与进程管理
- wxWidgets教程(13)——wxArchive解压与压缩
- wxWidgets教程(18)——wxWizard与wxWebView使用方法
- wxWidgets教程(16)——wxMenuBar、wxToolBar与wxStatusBar用法
- wxWidgets教程(10)——wxAUI相关用法总结
- wxWidgets教程(12)——wxConfig使用说明
- wxWidgets教程(14)——书签控件wxBookCtrl
- wxWidgets教程(15)——wxListCtrl用法
- wxWidgets教程(17)——wxSqlite3用法
- 进程管理——进程与线程(二)
- wxWidgets教程(3)- 窗口、对话框与控件
- [ZETCODE]wxWidgets教程五:布局管理
- wxWidgets初学者导引(2)——下载、安装wxWidgets
- wxWidgets教程(4)- 绘图
- 进程与线程(二)——进程的管理、创建与销毁
- wxWidgets教程
- linux内核设计与实现(三) linux进程管理 之 进程描述—1
- 进程管理----进程与线程(一)
- Python 安装pyad库方法
- 17.11.07日报
- 洛谷P1962 斐波那契数列
- Java中String的常用API
- NUMA架构下的CPU拓扑
- wxWidgets教程(11)——App与进程管理
- angular中使用锚点
- Java 字符串Split方法的一个坑
- 深入理解机器学习:从理论到算法-习题全解之第二十章:神经元网络
- leetcode: 19. Remove Nth Node From End of List
- Javaweb-xml编程-考生成绩管理系统(2)
- STM32 gcc编译环境搭建
- vsftpd服务
- RSA不同于模数攻击的破解法