This example illustrates how to limit your application to one instance at a time using a mutex and the EnumWindows API call under Window NT/95.
All code will be added to your application object header and implementation files. No other files are altered.
In the header file, type the following lines of code.
HANDLE hMutex;
char szTitle[_MAX_PATH];
In the implementation file and immediately after the usual header file #includes, type the following lines of code. Note that the two variables and the EnumFunc function are then global to this file module.
EnumFunc is called repeatedly by EnumWindows(…) later in this example. EnumFunc gets the title bar text of each window found by EnumWindows(…) and compares it to the application name. If a match is found, the windows handle that was sent to EnumFunc is saved in a global HWND variable hWnd, and EnumFunc returns FALSE to tell EnumWindows(…) that it can stop looking for windows.
A flag (iFoundFlag) is set to be used later to bring the first instance to the top of the Z order.
BOOL CALLBACK EnumFunc(HWND hwnd, LPARAM lParam );
HWND hWnd;
int iFoundFlag;
BOOL CALLBACK EnumFunc(HWND hwnd, LPARAM lParam )
{
char szBuffer[_MAX_PATH];
::GetWindowText(hwnd,szBuffer,_MAX_PATH - 1);
if(strstr(szBuffer,(char *)lParam)) {
hWnd = hwnd;
iFoundFlag = 1;
return FALSE;
}
return TRUE;
}
In the implementation file and in the application object constructor, type the following lines of code.
An unowned mutex is created with a unique name. The first instance gets a handle to the mutex and later claims ownership. The second instance gets the same handle, but can't claim ownership later on.
SzTitle is initialized with the name of your application. A flag is initialized to zero for use later.
hMutex = ::Creat匨utex(NULL,FALSE,"MyAppNameMutex");
strcpy(szT塼le?MyAppName");
iFoundFlag = 0;
In the implementation file and in the application object InitInstance(…) member and before any other code, type the following lines of code.
When the first instance of MyAppName.exe is launched, WaitForSingleObject(…) will grant ownership of the mutex immediately without tim♀g out. When the second instance of MyAppName.exe is launched, WaitForSingleObject(…) will wait for 50 milliseconds for ownership of the mutex. As long as the first instance is still running, ownership will never be granted and WaitForSingleObject(…) will return WAIT_TIMEOUT.
Once a timeout occurs, EnumWindows(..) iterates through all existing parent windows and calls EnumFunc for each window found. EnumWindows(..) also passes to EnumFunc the title of this application. If EnuMFunc finds a window that matches the appli{ation title, EnumFunc returns FALSE to EnumSindows(..) which then stops searchng for new existin?windows. Recall that EnumFunc sets iFoundFlag to 1 when a title mawch is found, and the first instance of the application is brought to the foreground.
FALSE is returned from InitInstance(..) so that the second instance is aborted.
DWORD dwResult = WaitForSingleObject(hMutex,50);
if(dwResult == WAIT_TIMEOUT) {
::EnumWindows(EnumFunc, (LPARAM)szTitle);
if(iFoundFlag) {
AfxMessageBox("MyAppName.exe is already running...");
::SetForegroundWindow(hWnd);
}
return FALSE;
In the implementation file and in the ExitInstance(…) over-ride, type the following line of code before the base class call to ExitInstance(…).
The second instances' attempt to release the mutex will fail because it is not the owner. The first instance will release the mutex upon closing and thereby allow the kernal to destroy it.
::ReleaseMutex(hMutex);
Note that this approach tests for a substring of the application title. The entire title doesn't need to match. For instance, for an application titled "MyAppName", a title such as "Untitled - MyAppName" would also match. One unfortunate side effect of this is that if you are running Visual C and testing your application from there, this technique will appear to fail. That is because the name "MyAppName" also appears in the titlebar of Visual C. To test your code, you must either close your project or exit Visual C.
Bookmark
Email This
Hits: 3269
Comments (0)

Write comment



