Simple Single Instance Windows
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_
// SingleInstance.h : header file
//
void RegisterSiblingWindowHandle(LPCTSTR lpLabel, HWND hWnd);
HWND GetSiblingWindowHandle(LPCTSTR lpLabel);
void RemoveSiblingWindowHandle(LPCTSTR lpLabel);
void RemoveSiblingWindowHandle(HWND hWnd);
void OpenSiblingWindowHandles(void);
void CloseSiblingWindowHandles(void);
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations
// immediately before the previous line.
#endif // !defined(AFX_SingleInstance_H__INCLUDED_)
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.

Comments
There are no comments yet. Be the first to comment!