Home Search Contact us About us
Title Single Instance of application
Summary This will show how to create an application that only allows one instance to be launched at any one time.
Contributor John McTainsh
Published 19-Sep-2000
Last updated 19-Sep-2000
Page rating   97% for 7 votes Useless Brilliant

Description.

Sometimes more than one instance of an application can cause problems with resources such as multi media players and socket servers. To overcome this it is first necessary to detect if the application is already running and secondly activate the application to allowing the user to do what they initially wanted.

Detecting the other installation.

To detect if the other application is running we simply create a unique event and detect if it has already been created indicating the application is already running.

Where you want to detect if the other application is running, use the following code. I like to do this in CMyApp::InitInstance().

//Check if another application is already running and note start
LPCTSTR szEventName = _T("PtkBneReadyRefEvent");
if( OpenEvent( EVENT_ALL_ACCESS, true, szEventName ) )
{
    return false;
}
CreateEvent( NULL, false, false, szEventName );

If you want to be picky Bounds Checker will say the event was not freed, to prevent this you may save the handle and destroy it in the destructor with CloseHandle.

Detecting and Restoring the other installation.

Preventing the application starting is only half the problem, if you just do this the user may get frustrated when the application does not appear. To overcome this force it to appear by posting a message to it.

Create a member variable UINT m_OtherAppMsgId to hold a global window message. Set it to NULL in the constructor and initialise it as below in CMyApp::InitInstance(). This will create the message and post it of to the already running instance if it exists.
//Check if another application is already running and note start
LPCTSTR szEventName = _T("PtkBneReadyRefEvent");
m_OtherAppMsgId = ::RegisterWindowMessage("SingleInstanceOfReadyRefApp");
if( OpenEvent( EVENT_ALL_ACCESS, true, szEventName ) )
{
    //Another application exists so get the other to activate.
    ::PostMessage( HWND_BROADCAST, m_OtherAppMsgId, 0, 0L );
    return false;
}
CreateEvent( NULL, false, false, szEventName );
Add the PreTranslateMessage message handller as follows.
 BOOL CMyApp::PreTranslateMessage(MSG* pMsg)
{
    ... 
    //Catch requests to start another instance and restore window 
    if(pMsg->message == m_OtherAppMsgId ) 
    { 
        // Bring the main window or its popup to
        // the foreground
        ASSERT( m_pMainWnd); 
        if( m_pMainWnd->IsIconic())
            m_pMainWnd->ShowWindow(SW_RESTORE);
        m_pMainWnd->SetForegroundWindow();
    }
    ...
    return CWinApp::PreTranslateMessage(pMsg);
}
Comments Date
Home Search Contact us About us