|
|
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 |
|
|
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);
}
|