应用单实例wxWidgets
Application single instance wxWidgets
我正在尝试创建一个只能有一个实例的应用程序,而不是不打开第二个实例我想 "raise" 当前 运行 实例。我正在使用 wxSingleInstanceChecker
检查,但我不知道如何 "raise" 运行 一个。
single = new wxSingleInstanceChecker;
if (single->IsAnotherRunning()) {
wxDELETE(single); return false;
}
下面是如何向现有进程发送消息,但我不知道如何让进程的主框架保持在所有其他进程之上windows。在我看来,这是 window 管理器的工作,wxWidgets 不能或很难实现,但你可以在创建它时使你的 window wxSTAY_ON_TOP
.因此,它要么 "always on top" 要么最小化。
// BUILD: g++ this_file.cpp -Wall $(wx-config --cxxflags --libs net,core,base)
#include <wx/wx.h>
#include <wx/snglinst.h>
#include <wx/ipc.h>
class CConnection : public wxConnection
{
protected:
bool OnExec(const wxString& topic, const wxString& data);
};
class CServer : public wxServer
{
public:
wxConnectionBase *OnAcceptConnection(const wxString& topic) {
return new CConnection;
}
};
class CApp : public wxApp
{
public:
bool OnInit() {
// Check if there is another process running.
if (m_one.IsAnotherRunning()) {
// Create a IPC client and use it to ask the existing process to show itself.
wxClient *client = new wxClient;
wxConnectionBase *conn = client->MakeConnection("localhost", "/tmp/a_socket" /* or a port number */, "a_topic");
conn->Execute("raise");
delete conn;
delete client;
// Don't enter the message loop.
return false;
}
// Create the main frame.
wxFrame *frm = new wxFrame(NULL, wxID_ANY, "There can be only one.");
frm->Show(true);
// Start a IPC server.
m_server = new CServer;
m_server->Create("/tmp/a_socket" /* or the same port number */);
// Enter the message loop.
return this->wxApp::OnInit();
}
int OnExit() {
delete m_server;
return this->wxApp::OnExit();
}
private:
wxSingleInstanceChecker m_one;
CServer *m_server;
};
DECLARE_APP(CApp)
IMPLEMENT_APP(CApp)
bool CConnection::OnExec(const wxString& topic, const wxString& data)
{
if (topic.compare("a_topic") == 0 && data.compare("raise") == 0) {
wxTheApp->GetTopWindow()->Show(true); // This actually won't work.
}
return true;
}
您确实需要使用某种 IPC,如 所示,然后您可以使用 wxFrame::Raise()
将其置于 Z 顺序之上。
请注意,将第二个实例的命令行参数也转发给第一个实例是很常见的,例如在现有实例中打开命令行指定的文档,这解释了为什么你真的必须使用 IPC——wxWidgets 不能为你猜测你的命令行语法,尤其是语义。
我正在尝试创建一个只能有一个实例的应用程序,而不是不打开第二个实例我想 "raise" 当前 运行 实例。我正在使用 wxSingleInstanceChecker
检查,但我不知道如何 "raise" 运行 一个。
single = new wxSingleInstanceChecker;
if (single->IsAnotherRunning()) {
wxDELETE(single); return false;
}
下面是如何向现有进程发送消息,但我不知道如何让进程的主框架保持在所有其他进程之上windows。在我看来,这是 window 管理器的工作,wxWidgets 不能或很难实现,但你可以在创建它时使你的 window wxSTAY_ON_TOP
.因此,它要么 "always on top" 要么最小化。
// BUILD: g++ this_file.cpp -Wall $(wx-config --cxxflags --libs net,core,base)
#include <wx/wx.h>
#include <wx/snglinst.h>
#include <wx/ipc.h>
class CConnection : public wxConnection
{
protected:
bool OnExec(const wxString& topic, const wxString& data);
};
class CServer : public wxServer
{
public:
wxConnectionBase *OnAcceptConnection(const wxString& topic) {
return new CConnection;
}
};
class CApp : public wxApp
{
public:
bool OnInit() {
// Check if there is another process running.
if (m_one.IsAnotherRunning()) {
// Create a IPC client and use it to ask the existing process to show itself.
wxClient *client = new wxClient;
wxConnectionBase *conn = client->MakeConnection("localhost", "/tmp/a_socket" /* or a port number */, "a_topic");
conn->Execute("raise");
delete conn;
delete client;
// Don't enter the message loop.
return false;
}
// Create the main frame.
wxFrame *frm = new wxFrame(NULL, wxID_ANY, "There can be only one.");
frm->Show(true);
// Start a IPC server.
m_server = new CServer;
m_server->Create("/tmp/a_socket" /* or the same port number */);
// Enter the message loop.
return this->wxApp::OnInit();
}
int OnExit() {
delete m_server;
return this->wxApp::OnExit();
}
private:
wxSingleInstanceChecker m_one;
CServer *m_server;
};
DECLARE_APP(CApp)
IMPLEMENT_APP(CApp)
bool CConnection::OnExec(const wxString& topic, const wxString& data)
{
if (topic.compare("a_topic") == 0 && data.compare("raise") == 0) {
wxTheApp->GetTopWindow()->Show(true); // This actually won't work.
}
return true;
}
您确实需要使用某种 IPC,如 wxFrame::Raise()
将其置于 Z 顺序之上。
请注意,将第二个实例的命令行参数也转发给第一个实例是很常见的,例如在现有实例中打开命令行指定的文档,这解释了为什么你真的必须使用 IPC——wxWidgets 不能为你猜测你的命令行语法,尤其是语义。