Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

There can be only one...

0.00/5 (No votes)
1 Apr 2002 1  
Limiting an application to a single instance.

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:

  1. 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");
  2. Now we create a mutex somewhere at the start of your program:
    HANDLE hMutexOneInstance = CreateMutex( NULL, FALSE, _T("MY_UNIQUE_GUID"));
  3. Check the last error to see what happened:
    bool AlreadyRunning = ( GetLastError() == ERROR_ALREADY_EXISTS || 
                               GetLastError() == ERROR_ACCESS_DENIED);
  4. 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; // Here we quit this application
     // or exit(0);
     // or PostQuitMessage() ... etc...
    }
  5. 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 ...;
    }
  6. Now in the handler for this message we just make sure this application becomes the foreground and active one.
    LRESULT CMainFrame::OnCheckItsMe(...)
    {
    // If we are using Chris Maunder's CSystemTray it's handy
    
     m_SystemTray.MaximiseFromTray(this->m_hWnd); 
     
    // or else you can call all sorts of restore/maximise functions:
    
     - ShowWindow(SW_RESTORE);
     - SetForegroundWindow();
     - SetWindowPlacement(m_MyWindowPlacement);
    
     return WM_CHECK_ITS_ME;
    }
  7. That should work!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here