Letting Only One Instance Run

Date: 28 January 1997
Author: Avery Andrews, Andreas Nolte, Ron Reynolds
Note: original & code by Nolte, from David Foringers' OWL FAQ, classname stuff by Andrews, TSingleApp by Reynolds

This method is not bullet-proof; it will fail if the two instances are opened within an extremely short time-period of each other, for example by some other program. But it's easy to understand, works under plain Win16 and Win32s (I haven't personally tested it with the full 32bit platforms), and is adequate to forestall blunders by mere human users. It also brings the original instance to the top.

First, override GetClassName() for the app's frame window to set the class name of your app's main (frame) window to something distinctive (by default, it will be something useless like OwlMain) e.g.:

// this can go just about anywhere
  const char appclassname[] = "MyCoolApp";
     .
     .
     .
// part of the frame window.
  char far *appFrame::GetClassName(){return(appclassname);};

Then put the following code into OwlMain:

  int OwlMain (int , char* argv[])
  {
   mycoolApp     App;

// This is to allow only one instance of the program to run,

   HWND firsthWnd, firstChildhWnd;

   if (firsthWnd = ::FindWindow(appclassname,NULL))
   {
     firstChildhWnd = ::GetLastActivePopup(firsthWnd);
     ::BringWindowToTop(firsthWnd);

     if (firsthWnd != firstChildhWnd)
      ::BringWindowToTop(firstChildhWnd);
     return FALSE;
   }
   else 
     return App.Run();
  }

If you are writing a 32-bit-only application...

The following 32-bit application class allows only one instance of itself with a given name to run. It uses a mutex that has the same name as the instance of the application object (so that multiple children of TSingleApp, as long as they have different names, can co-exist).

#include <owl/pch.h>
#include <owl/applicat.h>
#pragma hdrstop

class TSingleApp : public TApplication
{
public:

  TSingleApp(const char* AppName = "SingleApp")
  : TApplication(AppName)
  {
    SingleMutex = ::CreateMutex(NULL, TRUE, AppName);

    // check - did we aquire the mutex?
    if (::GetLastError() == ERROR_ALREADY_EXISTS) {
      ::MessageBox(0"An instance of this app is already running.",
                   "Too many apps", MB_OK);
      BreakMessageLoop = true;  // shut down app ASAP
    }
  }

  virtual ~TSingleApp()
  {
    ::CloseHandle(SingleMutex);  // destroy the mutex
  }

protected// (or private, depending on your paranoia level)
  HANDLE SingleMutex;
};

Since Mutexs are a 32-bit thing this class won't work on 16-bit systems (not even Win32s).