Introduction
When reading Joseph Newcomer's article about this matter, I thought there must be a way to do this simpler. So based on his excellent work the past few years I've spent all my time devoted on this theorem. In the mean time I never saw any daylight and I've lost all my friends (Just kidding' ;)...
But after this long research and keeping it secret for too long I finally bring out the goods just to make sure such an important discovery like this doesn't fade away in history... uhum...
So here we go:
- We need a registered message that our application will respond to. Make this one global in your application.
static const UINT WM_CHECK_ITS_ME = RegisterWindowMessage("MY_UNIQUE_GUID");
- Now we create a mutex somewhere at the start of your program:
HANDLE hMutexOneInstance = CreateMutex( NULL, FALSE, _T("MY_UNIQUE_GUID"));
- Check the last error to see what happened:
bool AlreadyRunning = ( GetLastError() == ERROR_ALREADY_EXISTS ||
GetLastError() == ERROR_ACCESS_DENIED);
- Then we send out a message to all top level windows to make sure it pops up and becomes the active window. The trick here is to use HWND_BROADCAST, which is a little bit undocumented.
if ( AlreadyRunning )
{
DWORD result;
LRESULT ok = SendMessageTimeout(HWND_BROADCAST,
WM_CHECK_ITS_ME,
0, 0,
SMTO_BLOCK |
SMTO_ABORTIFHUNG,
200,
&result);
return FALSE;
}
- The already running application needs to respond the registered window message, so we add a message handler to the application.
If you are using MFC edit your messagemap:
ON_REGISTERED_MESSAGE( WM_CHECK_ITS_ME, OnCheckItsMe )
or WTL:
MESSAGE_HANDLER(WM_CHECK_ITS_ME, OnCheckItsMe)
or plain Windows API:
LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
if (msg == WM_CHECK_ITS_ME)
{
...
return 0;
}
....
return ...;
}
- Now in the handler for this message we just make sure this application becomes the foreground and active one.
LRESULT CMainFrame::OnCheckItsMe(...)
{
m_SystemTray.MaximiseFromTray(this->m_hWnd);
- ShowWindow(SW_RESTORE);
- SetForegroundWindow();
- SetWindowPlacement(m_MyWindowPlacement);
return WM_CHECK_ITS_ME;
}
- That should work!