add ArchHooks::CheckForMultipleInstances

This commit is contained in:
Glenn Maynard
2005-11-11 21:10:10 +00:00
parent cbc31d637b
commit f0bb643e11
3 changed files with 69 additions and 0 deletions
+6
View File
@@ -21,6 +21,12 @@ public:
*/
virtual CString GetPreferredLanguage() { return "EN"; }
/*
* If this is a second instance, return true. Optionally, give focus to the existing
* window.
*/
virtual bool CheckForMultipleInstances() { return false; }
/* Call this to temporarily enter a high-priority or realtime scheduling (depending
* on the implementation) mode. This is used to improve timestamp accuracy. Do as
* little as possible in this mode; hanging in it might hang the system entirely. */
@@ -19,6 +19,10 @@
#pragma comment(lib, "winmm.lib") // for timeGetTime
#endif
static HANDLE g_hInstanceMutex;
static bool g_bIsMultipleInstance = false;
ArchHooks_Win32::ArchHooks_Win32()
{
SetUnhandledExceptionFilter(CrashHandler);
@@ -31,10 +35,17 @@ ArchHooks_Win32::ArchHooks_Win32()
/* Windows boosts priority on keyboard input, among other things. Disable that for
* the main thread. */
SetThreadPriorityBoost( GetCurrentThread(), TRUE );
g_hInstanceMutex = CreateMutex( NULL, TRUE, PRODUCT_NAME );
g_bIsMultipleInstance = false;
if( GetLastError() == ERROR_ALREADY_EXISTS )
g_bIsMultipleInstance = true;
}
ArchHooks_Win32::~ArchHooks_Win32()
{
CloseHandle( g_hInstanceMutex );
delete TimeCritMutex;
}
@@ -47,6 +58,57 @@ void ArchHooks_Win32::DumpDebugInfo()
CheckVideoDriver();
}
struct CallbackData
{
HWND hParent;
HWND hResult;
};
// Like GW_ENABLEDPOPUP:
static BOOL CALLBACK GetEnabledPopup( HWND hWnd, LPARAM lParam )
{
CallbackData *pData = (CallbackData *) lParam;
if( GetParent(hWnd) != pData->hParent )
return TRUE;
if( (GetWindowLong(hWnd, GWL_STYLE) & WS_POPUP) != WS_POPUP )
return TRUE;
if( !IsWindowEnabled(hWnd) )
return TRUE;
pData->hResult = hWnd;
return FALSE;
}
bool ArchHooks_Win32::CheckForMultipleInstances()
{
if( !g_bIsMultipleInstance )
return false;
/* Search for the existing window. Prefer to use the class name, which is less likely to
* have a false match, and will match the gameplay window. If that fails, try the window
* name, which should match the loading window. */
HWND hWnd = FindWindow( PRODUCT_NAME, NULL );
if( hWnd == NULL )
hWnd = FindWindow( NULL, PRODUCT_NAME );
if( hWnd != NULL )
{
/* If the application has a model dialog box open, we want to be sure to give focus to it,
* not the main window. */
CallbackData data;
data.hParent = hWnd;
data.hResult = NULL;
EnumWindows( GetEnabledPopup, (LPARAM) &data );
if( data.hResult != NULL )
SetForegroundWindow( data.hResult );
else
SetForegroundWindow( hWnd );
}
return true;
}
static CString g_sDriverVersion, g_sURL;
static bool g_Hush;
static BOOL CALLBACK DriverWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
@@ -12,6 +12,7 @@ public:
void DumpDebugInfo();
void RestartProgram();
CString GetPreferredLanguage();
bool CheckForMultipleInstances();
int OldThreadPriority;
RageMutex *TimeCritMutex;