M
Wenn ich Dich richtig verstanden habe, möchtest Du nur, daß Dein Programm nur einmal im System geladen und gestartet wurde.
Wenn das so ist, würde ich den folgenden Weg empfehlen, dieser ist auch sehr sicher (keine Zweideutigkeiten bei FindWindow() usw.):
1.) Deine Applikation MyApp1 richtet einen Mutex ein.
2.) Wenn dieser Mutex bereits existiert (also Deine Applikation läuft bereits schon länger als MyApp2 im System), schickt Deine Applikation MyApp1 an ALLE Prozesse eine von Dir selbst definierte Nachricht und beendet sich daraufhin.
3.) Die (bereits laufende) Applikation MyApp2 empfängt diese selbst definierte Nachricht, überprüft sie auf Plausibilität und bringt sein eigenes Fenster in den Vordergrund.
4.) That's all, kein Gehampel mit hWnd oder Namenskonflikte bei FindWindow() usw.
Du solltest bei Punkt 3.) wissen, daß Du bei Bedarf die API-Funktion SetForegroundWindow() über AttachThreadInput() realisieren sollst!
Gruß
Martin
Folgenden Code implementierst Du am besten bei der Initialisierung in WinMain():
uint32 ui32_registered_message_id_UWM_ARE_YOU_ME;
TCHAR tcharsz_255stellen[255 + 1];
HANDLE handle_mutex_multiple_instance;
#define TCHARSZ_APPGUID TEXT( "MyApp AppGUID {7CB1F734-9A34-944e-72AA-AFEFF2370962}" )
//Diese Zeichenfolge ist eine GUID, damit haben wir weltweit eine einigermaßen einmalige Identifikation. (googeln falls mehr Infos nötig!)
//********************************************************
//** Prüfen ob die Applikation mehrfach gestartet wurde **
//********************************************************
strcpy( tcharsz_255stellen, TEXT( "UWM_ARE_YOU_ME " ) );
strcat( tcharsz_255stellen, TCHARSZ_APPGUID );
ui32_registered_message_id_UWM_ARE_YOU_ME = RegisterWindowMessage( tcharsz_255stellen );
//Meine eigene Nachricht selbst definieren.
strcpy( tcharsz_255stellen, TCHARSZ_APPGUID );
handle_mutex_multiple_instance = CreateMutex( NULL, FALSE, tcharsz_255stellen );
//Mutex erzeugen.
if ( ( handle_mutex_multiple_instance == NULL )
|| ( GetLastError() == ERROR_ALREADY_EXISTS ) //Mutex existiert bereits -> Ende.
|| ( GetLastError() == ERROR_ACCESS_DENIED ) ) //In Umgebeung mit mehreren Usern schlägt Aufruf CreateMutex()
//wegen Wert NULL für Parameter lpMutexAttributes fehl!
{
//Eine andere MyApp ist bereits aktiv -> Dieser Applikation eine Nachricht über Broadcast schicken (um z.B. dessen Fenster
//in Vordergrund zu bringen oder wieder sichtbar zu machen). Anschließend werde ich mich selbst beenden.
SendMessageTimeout( HWND_BROADCAST, ui32_registered_message_id_UWM_ARE_YOU_ME,
(WPARAM)0, (LPARAM)0, SMTO_BLOCK | SMTO_ABORTIFHUNG, 200, &dword_result );
Programm_ende_mit_free_memory( -1, NULL ); //Ein Fehler ist aufgetreten, Abbruch
//des Programms ohne Fehlermeldung.
}
//Ab hier Initialisierung fortsetzen, z.B. Fenster definieren ....
Folgenden Code baust Du in die Window-Prozedur ein:
LRESULT CALLBACK Procedure_Window( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
...
if ( message == ui32_registered_message_id_UWM_ARE_YOU_ME )
{
//*******************************************************************
//** Es wurde versucht, die gleiche Appikation mehrfach zu starten **
//*******************************************************************
Bring_Window_To_Top( ptr_hwnd_frame ); //Das eigene Fenster in den Vordergrund bringen.
return( 0 );
}
//Ab hier kommt die klassische Message-Auswertung.
switch ( message )
{
case WM_CREATE:
//*******************************************
//** Das Applikationsfenster wurde erzeugt **
//*******************************************
...
...
break;
case WM_DESTROY:
//*************************************************************
//** Ein Klick auf Schließfeld der Titelleiste oder "Alt+F4" **
//*************************************************************
PostQuitMessage( 0 );
return( 0 );
break;
}
return( DefWindowProc( ptr_hwnd_frame, message, wParam, lParam ) );
//Die Routine DefWindowProc() übernimmt die Bearbeitung
//aller Nachrichten, um die wir uns nicht gekümmert haben.
} //Ende von Procedure_Window().