Click here to Skip to main content
Licence CPOL
First Posted 1 Apr 2002
Views 101,740
Bookmarked 47 times

There can be only one...

By | 1 Apr 2002 | Article
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Niek Albers

Web Developer

Netherlands Netherlands

Member

Niek is the founder and programmer of DaanSystems.com and is working on many projects all the time. He makes a living by doing contractwork for others.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionSome needed extensions PinmemberKarstenK22:51 4 Jan '07  
GeneralUsing event object will be simpler... Pinmemberopsoft-op23:59 5 Dec '05  
GeneralStill the same old problem! PinmemberDaniel Lohmann7:07 19 Jul '02  
GeneralRe: Still the same old problem! Pinsussandy_kanaka17:23 17 Aug '02  
GeneralRe: Still the same old problem! PinmemberDaniel Lohmann21:52 17 Aug '02  
GeneralAccess violation PinmemberCapsuleDweller8:33 29 May '02  
GeneralRe: Access violation PinmemberAnonymous8:32 29 May '02  
GeneralRe: Access violation PinmemberCarl Ferreira5:05 11 Jul '02  
GeneralRe: Access violation PinmemberJan Deinhard3:27 5 Sep '02  
GeneralRe: Access violation Pinmemberxxxyyyzzz19:02 22 Dec '02  
QuestionWhere to register the message?? Pinmembercycosi5:17 9 Apr '02  
AnswerRe: Where to register the message?? PinmemberTrapper7:05 23 Apr '02  
GeneralOK but not perfect PinmemberPhilippe Lhoste3:47 8 Apr '02  
GeneralRe: OK but not perfect PinmemberAndreas Saurwein21:26 14 May '02  
Philippe Lhoste wrote:
the capability to give to the existing instance the command line parameters of the new instance
 
Just use the WPARAM/LPARAM of the registered message for flags, pointers or handles to pass whatever needed.
 
Its a nice and clean solution (does it it run correctly under TS?).
 
Vote against software patents in europe
QuestionIs this way good? PinmemberDaniel Madden0:53 8 Apr '02  
AnswerRe: Is this way good? PinmemberPhilippe Lhoste3:31 8 Apr '02  
GeneralRe: Is this way good? PinmemberDaniel Madden8:23 8 Apr '02  
GeneralThanks! PinmemberAnonymous11:16 2 Apr '02  
GeneralDialogs PinmemberAtlantys2:35 2 Apr '02  
GeneralRe: Dialogs PinmemberNiek Albers3:11 2 Apr '02  
GeneralScary PinadminChris Maunder0:23 2 Apr '02  
GeneralRe: Scary PinmemberJosh Knox6:00 4 Apr '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120529.1 | Last Updated 2 Apr 2002
Article Copyright 2002 by Niek Albers
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid