Überprüfung auf mehrere Instanzen eines Spiels

Aus Spieleprogrammierer-Wiki
(Unterschied zwischen Versionen)
Wechseln zu: Navigation, Suche
[unmarkierte Version][gesichtete Version]
K (Implementierung)
(C++/Windows)
 
(9 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 2: Zeile 2:
 
[[Kategorie:C++]]
 
[[Kategorie:C++]]
  
== Einführung ==
+
Wie du wahrscheinlich selbst austesten kannst: Viele Spiele der heutigen Zeit kann man (versehentlich) mehrfach starten, aber dennoch öffnet sich nur eine Instanz des Spieles, nicht etwa zwei, drei, vier, sieben oder sogar mehr. Dem Mechanismen dahinter werden wir auf den Grund gehen.
Was wollen wir hier eigentlich machen? Nun, wie du wahrscheinlich selbst austesten kannst: Wenn man bei vielen Spielen der heutigen Zeit aus dem Versehen mehrere Instanzen öffnet, durch ein hohes Quantum an Mausklicks, dann öffnet sich trotz dessen nur eine Instanz des Spieles, nicht etwa Zwei, Drei, Vier, Sieben oder sogar mehr. Wie wird dies bewerkstelligt? Dieser Frage gehen wir auf den Grund. Doch wozu eigentlich? Nun wir benötigen dies zum Beispiel bei Spielen oder Programmen, wo das Fenster seine zeit benötigt bis es offen ist oder eben wenn der Benutzer mehrfach den linken Mausbutton betätigt. Dadurch öffnen sich mehr Instanzen und es dauert noch länger bis sich überhaupt eine öffnet. Dann klickt der Nutzer womöglich nochmals darauf und nochmal und nochmal! Fast ein kleiner Teufelskreis.
+
  
== Implementierung ==
+
== Verwendung ==
Benötigt wird Windows.h!
+
Ein Verfahren zur Verhinderung des mehfachen Startens einer Anwendung benötigen wir zum Beispiel bei Spielen oder Programmen, bei denen es eine Weile dauert, bis der Benutzer nach dessen Start eine Rückmeldung in Form eines Fensters oder Ladebildschirms erhält. Dann kann es passieren, dass der Benutzer durch erneutes Klicken versucht das Programm noch einmal zu starten, weil er denkt, dass sein vorheriger Startversuch nicht erfolgreich war. Dadurch öffnen sich, wenn dies nicht verhindert wird, mehrere Instanzen, und der Start aller Instanzen zieht sich in die Länge oder führt sogar zu Fehlern. Deshalb sollen neue Instanzen des Spiels prüfen, ob bereits eine Instanz geöffnet wurde und sich dann ggf. beenden.
  
 +
== Implementierung ==
 +
=== C++/Windows ===
 
<sourcecode lang=cpp tab=4>
 
<sourcecode lang=cpp tab=4>
bool IsOnlyInstance(LPCTSTR name)
+
bool IsOnlyInstance()
 
{
 
{
HANDLE handle = CreateMutex(NULL, TRUE, name); //Mutex für jetziges Fenster erstellen
+
// Versuche einen Mutex mit dem Namen des Prozesses (.EXE-Dateiname) zu erzeugen.
+
// Wenn ein solcher schon existiert, läuft die Anwendung bereits.
if(GetLastError() != ERROR_SUCCESS)
+
TCHAR path[MAX_PATH];
 +
GetModuleFileName(NULL, path, MAX_PATH);
 +
 
 +
//Weil CreateMutex keine \ erlaubt, müssen wir diese rausnehmen. Das tun wir einfach durch ersetzen mit einem Leerzeichen
 +
for(int i = 0; i < MAX_PATH; i++)
 
{
 
{
HWND hWnd = FindWindow(name, NULL); //Nach Fenstern mit dem gleichen Titel suchen
+
if(path[i] == 0)
if(hWnd)
+
break;
{
+
if(path[i] == '\\')
ShowWindow(hWnd, SW_SHOWNORMAL); // Fenster in einen Zustand versetzen (Zustände: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx)
+
path[i] = ' ';
SetFocus(hWnd); // Fokus auf dieses Fenster
+
};
SetForegroundWindow(hWnd); // Fenster in den Vordergrund rücken
+
SetActiveWindow(hWnd); // Fenster als aktives Fenster auswählen
+
HANDLE mutex = CreateMutex(0, true, path);
return false;
+
 
}
+
if(mutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS) // Wenn NULL Pointer oder ERROR_ALREADY_EXISTS als Fehler geworfen wird existiert bereits eine Instanz
}
+
return false;
 
return true;
 
return true;
 
}
 
}
 
</sourcecode>
 
</sourcecode>
 
Dieser Code bewirkt also, dass wenn ein Fenster schon offen ist kein weiteres mehr geöffnet werden kann.
 
Nicht wie eventuell angenommen wurde, dass die anderen Instanzen geschlossen werden. Wir packen das Problem gleich an der Wurzel.
 

Aktuelle Version vom 26. März 2012, 17:58 Uhr

Klicke hier, um diese Version anzusehen.

Meine Werkzeuge
Namensräume
Varianten
Aktionen
Navigation
Werkzeuge