Environment:
VC++, Win32
Limiting an
application to a
single instance is very
problematic. There are dozens of solutions available; most
of them work most of the time. The problem is that solutions
that use ProcessIDs or Window Handles fail occasionally due
to Windows sloppy internal handling.
Here is a quick and
dirty solution for keeping a single
instance of a window.
It uses shared memory to maintain a linked list of open
windows. An application
checks the list on startup, and if the application is on the
list, it is exited.
Here is the header:
#if !defined(AFX_SingleInstance_H__INCLUDED_)
#define AFX_SingleInstance_H__INCLUDED_
void RegisterSiblingWindowHandle(LPCTSTR lpLabel, HWND hWnd);
HWND GetSiblingWindowHandle(LPCTSTR lpLabel);
void RemoveSiblingWindowHandle(LPCTSTR lpLabel);
void RemoveSiblingWindowHandle(HWND hWnd);
void OpenSiblingWindowHandles(void);
void CloseSiblingWindowHandles(void);
#endif
To use the code, you
need to activate the link to the shared list. The easiest
way to do that is to insert the function
OpenSiblingWindowHandles();
into the constructor of
CWinApp() if you are
using MFC, or right after the RegisterClass() in your
WinMain() in a standard Windows application.
You need to release the
list at the end of the application as well with
CloseSiblingWindowHandles();
This works from the
CWinApp() destructor in
MFC or after the message loop in a
Windows application.
When an application
starts, before the main window is created (either via
ProcessShellCommand(),
DoModal(), or
CreateWindow()), insert
this code:
HWND hWndOther = GetSiblingWindowHandle(_T("My Unique ID"));
if( hWndOther != NULL )
{
::SetWindowPos(hWndOther, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE|SWP_NOSIZE);
::SetFocus(hWndOther);
return FALSE;
}
When a new window is
opened (like in CMainFrame or after
CreateWindow()):
RegisterSiblingWindowHandle(_T("My Unique ID"), m_hWnd);
To unregister a window
(in ExitInstance() or just before the
CloseSiblingWindowHandles()):
RemoveSiblingWindowHandle(_T("My Unique ID"));
Of course, replace all
the _T("My Unique ID") tags with a unique ID for your app.
About the Author
I have worked as a Software Engineer for 22 years. I work
with Windows, Unix/Linux, DSP, and Microcontrollers.
Downloads