- 浏览: 112436 次
文章分类
最新评论
-
myisland:
可以运行!一开始还以为要用本身就是透明背景的png呢,原来不是 ...
在CodeBlocks中用wxWidgets创建不规则窗口 -
lonerzf:
可以的。感谢。但是还有个问题,工程建立的时候有Configur ...
在CodeBlocks中用wxWidgets创建不规则窗口 -
鸵鸟大仙:
麻烦请问一下怎么在wxwidgets中加载msword.olb ...
利用wxwidgets操纵word -
dqifa:
Rat_boy 写道我现在也在做wxWidgets操作Word ...
利用wxwidgets操纵word -
Rat_boy:
我现在也在做wxWidgets操作Word的功能 但是搞了好久 ...
利用wxwidgets操纵word
wxWidgets提供了一个用来检测是否只有一个实例(instance)在运行的wxSingleInstanceChecker类。为了检测程序只运行一个实例,你可以在程序运行之初使用该类创建一个m_check对象,这个对象将存在于程序的整个生命周期。然后就可以在OnInit函数中调用其IsAnotherRunning函数检测是否已经有别的实例在运行。代码如下所示:
bool MainApp::OnInit() { wxString name = wxString::Format(wxT("MainApp-%s"), wxGetUserId().GetData()); m_checker = new wxSingleInstanceChecker(name); if (m_checker->IsAnotherRunning()) { wxLogError(wxT("Another program instance is already running, aborting.")); delete m_checker; return false; } ... more initializations ... return true; } int MainApp::OnExit() { delete m_checker; return 0; }
注意,上面使用了wxGetUserId()来构建实例名,这表示允许不同的用户能同时运行程序的一个实例。如果不这样,那么程序就只能被一个用户运行一次。
但是,如果你想把旧的实例提到前台,或者想使旧的实例打开传递给新的实例的作为命令行参数的文件,该怎么办呢?一般来说,这需要在这两个实例间进行通讯。我们可以使用wxWidgets提供的进程间通讯类来实现。
在下面的实例中,我们将实现程序多个实例间的通讯,以便允许第二个实例请求第一个实例将自己带到前台以提醒用户它已经在运行。下面的代码实现了一个连接类,这个类将被两个实例使用。一个服务器类被旧的实例使用,以便监听新的实例的连接请求。一个客户端类被新的实例使用,以便和旧的实例进行通讯。
class AppServer : public wxServer { public: virtual wxConnectionBase* OnAcceptConnection(const wxString& topic); };
class AppClient : public wxClient { public: virtual wxConnectionBase* OnMakeConnection(); };
class AppConnection : public wxConnection { public: virtual bool OnExecute(const wxString& WXUNUSED(topic), wxChar* WXUNUSED(data), int WXUNUSED(size), wxIPCFormat WXUNUSED(format)); };
当有新的实例(Client)进行连接请求时,旧的实例(Server)中的OnAcceptConnection函数首先检查旧的实例中没有任何模式对话框。
wxConnectionBase* AppServer::OnAcceptConnection(const wxString& topic) { if (topic.Lower() == wxT("only-one")) { wxWindowList::Node* node = wxTopLevelWindows.GetFirst(); while (node) { wxDialog* dialog = wxDynamicCast(node->GetData(), wxDialog); if (dialog && dialog->IsModal()) { return false; } node = node->GetNext(); } return new AppConnection(); } else return NULL; }
OnExecute函数是一个回调函数,在新的实例对其连接对象(由AppConnection创建的对象)调用Execute函数时被调用。OnExecute函数可以有一个空的参数,这表示它只要将自己提到前台就可以了。
bool AppConnection::OnExecute(const wxString& WXUNUSED(topic), wxChar* WXUNUSED(data), int WXUNUSED(size), wxIPCFormat WXUNUSED(format)) { wxFrame* frame = wxDynamicCast(wxGetApp().GetTopWindow(), wxFrame); if (frame) { frame->Restore(); // 必须要有这句,不然当主窗口最小化时,就不能被提到前台 frame->Raise(); } return true; }
接下来我们还需要修改OnInit()函数。当没有别的实例在运行时,这个实例需要将自己设置为Server,等待别的实例的连接请求,如果已经有实例在运行,那么就创建一个和那个实例的连接,请求那个实例将程序的主窗口提到前台。下面的修改后的代码:
bool MainApp::OnInit() { wxString name = wxString::Format(wxT("MainApp-%s"), wxGetUserId().GetData()); m_checker = new wxSingleInstanceChecker(name); if (!m_checker->IsAnotherRunning()) { m_server = new AppServer(); if (!m_server->Create(wxT("wxMainApp"))) { wxLogDebug(wxT("Failed to create an IPC service.")); return false; } } else { AppClient* client = new AppClient(); wxString hostName = wxT("localhost"); wxConnectionBase* conn = client->MakeConnection(hostName, wxT("wxMainApp"), wxT("only-one")); if (conn) { conn->Execute(wxEmptyString); conn->Disconnect(); delete conn; } else { wxString msg = wxT("Sorry, the existing instance may be too busy to respond.n") wxT("Please close any open dialogs and retry."); wxMessageBox(msg, wxT("wxMainApp"), wxICON_INFORMATION | wxOK); } delete client; // 如果没有这句,在运行Debug版本时就会显示如下图的警告 return false; } ... more initializations ... return true; }
int MainApp::OnExit() { delete m_checker; delete m_server; return 0; }
问题:
1. 调用wxGetApp问题
在调用wxGetApp()时可能会有编译错误,提示说"identifier not found"。这可以通过在App类后加上一行DECLARE_APP(XXXApp)来解决。
2. 引入ipc.h和wx.h时的顺序问题
运行第二个实例的时候,发现它总是会挂起在MakeConnection处,查看进程可以看到有两个实例在运行。在网上找了n久,只在wxWidgets Forum上发现有提到这个问题(Windows service using wxWidgets ipc),可是也没有提到如何解决。只能靠自己啦,经过对程序的一步步排除,终于发现是因为引入头文件时将ipc.h放在wx.h之前的原因,掉换引入头文件的顺序后问题被解决。
from:http://hi.baidu.com/zshua_404/blog/item/0f7e441342a84f56f819b8a3.html
- wxsingleton-activation.zip (4 KB)
- 下载次数: 2
- wxsingleton-simplicity.zip (3.1 KB)
- 下载次数: 2
发表评论
-
WX_DEFINE_ARRAY的使用
2018-03-20 12:07 624/**************************** ... -
wxBase64Encode和wxBase64Decode
2016-04-09 15:23 803#include <wx/base64.h> ... -
wxWidgets中 wxButton实现自动点击
2015-06-30 12:59 1047之前在用wxSocket通讯的时候,EVT_SOCKET事件 ... -
按键转换
2015-03-15 12:27 8981 void PopTextCtrl::OnChar(wxK ... -
获取当前路径
2014-03-09 16:51 655#include <wx/stdpaths.h> ... -
程序只运行一个实例,并将前一个实例提到前台
2014-02-28 18:28 866wxWidgets提供了一个用来检测是否只有一个实例(ins ... -
通过重载实现修改wxWidgets文本处理框wxTextCtrl和wxRichTextCtrl的右键弹出菜单
2014-02-27 13:44 2333wxWidget中这块是写死的,这让我感到非常 ... -
过滤wxTextCtrl控件输入的两种方法
2014-02-27 13:40 1921以下两种方法实现wxTextCtrl只接收0-9的数字. ... -
wxBoxSizer,wxFlexGridSizer,wxGridBagSizer,wxGridSizer使用示例
2014-02-26 10:44 1813wxBoxSizer,wxFlexGridSizer,wx ... -
wxWidgets类库结构图
2014-02-26 09:08 1143自从2.5.0开始,wxWidgets既可以编译成单一的代 ... -
wxWidgets框架下基于wxDialog程序的标准退出方法
2014-02-25 16:56 1476退出程序的标准方法 ... -
在exe程序中嵌入图片
2012-10-20 23:44 15481、利用Bin2C将图片转换成“*.c”文件; 2、包含“* ... -
怎样解决静态编译对mingwm10.dll的依赖?
2012-10-15 14:14 1113使用CodeBlocks+wxWidgets2.9.4编写的静 ... -
wxRegEx的使用
2012-10-09 20:35 1595#include <wx/regex.h>#inc ... -
wxWidgets中的wxTimer使用
2012-09-26 15:51 22351、包含头文件: #include <wx/ti ... -
使用wxStringTokenizer分割字符串
2012-08-30 21:51 2363//wxStringTokenizer::wxStringTo ... -
给图片添加图片水印
2012-08-20 10:21 804写在开始 不能用代码同时实现半透明和不规则形状的水印,只能选 ... -
绘制图形并填充
2012-08-17 13:32 946=====文件名:DrawShape.h=== ... -
wxMathPlot
2012-08-17 09:39 1151wxMathPlot wxMathPlot ... -
使用wxWidgets实现所见即所得打印(CodeBlocks)
2012-08-14 18:10 25151、从wxPrintout派生一个类Printout,类源码如 ...
相关推荐
虚拟控制台最有用的是,当一个程序出错造成系统死锁时,可以切换到其它虚拟控制台工作,关闭这个程序。 shutdown 1.作用 shutdown命令的作用是关闭计算机,它的使用权限是超级用户。 2.格式 shutdown [-h][-i...
您也可以禁止某些程序运行,记录所有进程运行日志,当进程终止时或达到资源的消耗极限时自动重启,限制了运行实例数量,等等。您甚至可以指示进程,促使其进入高性能电源使用方案和/或防止PC睡眠。游戏模式可以很...
当你在客户端调用Blash.toString(reply)时,后台将采用java.util.date的默认构造方法创建一个实例.然后调用实例的tostring方法.客户端的javascript将返回给reply对象(此时reply是java.util.date的字符串形式) 3.5 The...
这意味着对于每个 SQL Server 实例,都存在一个专用的 MSFTESQL 实例,其中包括专用的组件(例如断字符和筛选器)、资源(例如内存)和配置(例如服务级设置,实例级的 resource_usage 是一个更具体的例子)。...
-Button控件将不再自动拥有display:inline属性,如果希望两个按钮在一行显示,请为第一个按钮设置CssStyle="float:left;"属性。 -修正了弹出菜单的位置在Firefox下不正确的BUG(feedback:eroach)。 -为TriggerBox...
-修正DatePicker中的一个bug(31/01/2010将会返回NULL)使用DateFormatString来生成SelectedDate属性(feedback:OktaEndy)。 -修正extjs最新版本(v3.2.2)中的一个bug,如果下拉列表中存在两个相同的Text,则...