Single instance, argv and windows context menu !

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
bidou
In need of some credit
In need of some credit
Posts: 4
Joined: Wed Jun 06, 2007 9:03 am

Single instance, argv and windows context menu !

Post by bidou » Thu Jun 07, 2007 9:41 pm

Helle everybody !

I've an application MyApp in wxWidgets code.
I use wxSingleInstanceChecker to have one instance of the program, but I want can retrieve the "argv" from the other instance (which are not created) and pass it into my single instance. I read about wxDDEClient and wxDDEServer and I understood nothing!

My english is not so good, so I hope you understood my problem :wink:

Thanks, Bidou

mc2r
wxWorld Domination!
wxWorld Domination!
Posts: 1195
Joined: Thu Feb 22, 2007 4:47 pm
Location: Denver, Co
Contact:

Post by mc2r » Thu Jun 07, 2007 11:07 pm

Hi,

I've never used wxSingleInstanceChecker. But could you do something like this.

Code: Select all

class mySingleInstanceChecker : public wxSingleInstanceChecker {
    public:
        void SetAppInstance(MyApp *myApp){ m_myApp = myApp};
        MyApp* GetAppInstance(void){ return m_myApp};
    protected:
        static MyApp *m_myApp;
};
Then

Code: Select all

bool MyApp::OnInit()
{
    const wxString name = wxString::Format("MyApp-%s", wxGetUserId().c_str());
    m_checker = new wxSingleInstanceChecker(name);
    if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
    m_checker-.SetAppInstance(this);
    ... more initializations ...

    return true;
}
Not sure if there is a better way to do this.

Hope this helps.

-Max

bidou
In need of some credit
In need of some credit
Posts: 4
Joined: Wed Jun 06, 2007 9:03 am

Post by bidou » Fri Jun 08, 2007 7:50 am

Thanks for your answer, it's a good idea, but the problem is that when I try to create a new instance of myApp it pass through the if statement :

Code: Select all

if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
but m_checker is a new instance for this app too, so GetAppInstance() return NULL and not the application which is running!

Maybe can I limit the instance of m_checker... I don't know how.

Any ideas ?

Thanks, Bidou :wink:

mc2r
wxWorld Domination!
wxWorld Domination!
Posts: 1195
Joined: Thu Feb 22, 2007 4:47 pm
Location: Denver, Co
Contact:

Post by mc2r » Fri Jun 08, 2007 3:41 pm

bidou wrote:Thanks for your answer, it's a good idea, but the problem is that when I try to create a new instance of myApp it pass through the if statement :

Code: Select all

if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
but m_checker is a new instance for this app too, so GetAppInstance() return NULL and not the application which is running!

Maybe can I limit the instance of m_checker... I don't know how.

Any ideas ?

Thanks, Bidou :wink:
I'm not sure what the problem is unless you are starting 2 instances of the app at the same time.
mc2r wrote:

Code: Select all

bool MyApp::OnInit()
{
    const wxString name = wxString::Format("MyApp-%s", wxGetUserId().c_str());
    m_checker = new wxSingleInstanceChecker(name);
    if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
    m_checker-.SetAppInstance(this);
    ... more initializations ...

    return true;
}
If there is no other instance of my app running m_checker->IsAnotherRunning(name) returns false so the if check is skipped. and m_checker->SetAppInstance(this) is called. If another instance is already running ie... m_checker->SetAppInstance(this) on another instance has been called the if statement will be entered for and get instance will be called.

I am not sure what the problem is, unless you are worried about two instances of MyApp starting close enough together that there is a race condition where both enter the if statement. Which I suppose could happen. That being the case lock the check in a wxMutex..


new MyApp.cpp:

Code: Select all

bool MyApp::OnInit()
{
    wxMutexLocker lock(MyAppInitMutex);
    const wxString name = wxString::Format("MyApp-%s", wxGetUserId().c_str());
    m_checker = new wxSingleInstanceChecker(name);
    if ( m_checker->IsAnotherRunning() )
    {
        MyApp *runningInstance = m_checker->GetAppInstance();
        // Call whatever methods in your app you want to pass arguments
        return false;
    }
    m_checker->SetAppInstance(this);
    ... more initializations ...

    return true;
}
static protected member of MyApp:

Code: Select all

        static wxMutex MyAppInitMutex;
-Max

cavolaccimiei
Knows some wx things
Knows some wx things
Posts: 41
Joined: Thu Feb 08, 2007 10:48 am

Post by cavolaccimiei » Tue Oct 09, 2007 5:33 pm

I'm having troubles implementing this... I really hope this works but i have some doubts because:

the m_myApp var of mySingleInstance instance named m_checker is relative to the "original" instance of the program... i think there is no way to pass that var among processes... for that i'm afraid i'll need IPC (inter process communication).

Am i wrong?

that is, in other words, i think that m_myApp is static, so it belongs to all instances of mySingleInstanceChecker one may create inside... the same Application! Which is kinda useless....

Please tell me that i'm wrong and where :)

cavolaccimiei
Knows some wx things
Knows some wx things
Posts: 41
Joined: Thu Feb 08, 2007 10:48 am

Post by cavolaccimiei » Thu Oct 11, 2007 1:18 pm

in fact, i was right.
I had to do it through IPC, as mentioned in another post.
The real code is really really simple, so, if you are reading this, go ahead and use IPC straight away!

jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 » Fri Oct 03, 2008 7:16 pm

Well it has been almost a year.... if you have it... could you share your IPC code? My needs are almost exactly what you are describing here.

Thanks
John A. Mason
Midland, TX

Post Reply