应用单实例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 不能为你猜测你的命令行语法,尤其是语义。