To limit your application to a single instance, the most common way is creating a named Mutex using CreateMutex, and checking to see if that Mutex already existed or not. If that Mutex already existed, it means that your application is the second instance on the system, so you can kill it right away.
Some applications do more than this, when you attempt to open a second instance, not only they don't let you do that, but also they bring the older instance to front. How do they do it? It's simple. They register a WNDCLASS with a specific name, and every time they call FindWindow to find windows of that class. Once they found such windows, they simply call SetForegroundWindow to bring the other window to front, and exit themselves.
To simplify things a bit, I wrote a C++ class named CSingleInstance (found in singinst.h and singinst.cpp files in the ZIP file at the bottom of the article). To use this class, you add it to your CWinApp-derived class's base class list as public, like this:
class CSingleInstanceApp : public CWinApp, public CSingleInstance
{
// ...
}
Then, you call the constructor with appropriate parameters:
CSingleInstanceApp::CSingleInstanceApp()
: CSingleInstance( false, _T("SingleInstanceApplication") )
{
// ...
}
The first parameter is a bool indicating whether you want to activate the older instances of the class if you're being the second instance. Passing true to this parameter causes the second instance to bring the previous instance to front. The second parameter is an optional string, which specifies the name of the Mutex and window class. This string should not be longer than MAX_PATH. If you don't specify this parameter, or pass NULL to it, a default name would be used (“Single Instance Application – ExeFileName.exe”).
The next step is overriding CWinApp::InitInstance (if it's not already overridden) and adding the following lines at the beginning of the code for that function:
BOOL CSingleInstanceApp::InitInstance()
{
if (!IsFirstInstance())
return FALSE;
// ...
}
That's it if you don't want to bring the older instance of the application to front. If you wish to do so, you would need to make two changes. First, you should change the first parameter passed to the CSingleInstance's constructor to true, and also you need to override the PreCreateWindow in your CMainFrame class, and change it like this:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
cs.lpszClass = ((CSingleInstanceApp *) ::AfxGetApp())->GetWndClassName();
return CMDIFrameWnd::PreCreateWindow( cs );
}
This will make the main frame window be created with the window class that CSingleInstance has registered.
Download source code for this article
This article originally appeared on BeginThread.com. It's been republished here, and may contain modifications from the original article.