Rubrik: Verschiedenes / Sonstiges | VB-Versionen: VB4, VB5, VB6 | 24.11.01 |
Mehrfachstart der eigenen Anwendung verhindern Dieses Beispiel zeigt, wie sich prüfen lässt, ob die eigene Anwendung bereits ausgeführt wird. Und wenn ja, wird diese aktiviert. | ||
Autor: Dieter Otter | Bewertung: | Views: 49.981 |
www.tools4vb.de | System: Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Manchmal ist es sinnvoll zu verhindern, dass die eigene Anwendung mehrfach gestartet und gleichzeitig ausgeführt wird. Wie man prüfen kann, ob bereits eine Instanz "läuft", wissen wahrscheinlich die meisten. Hierzu fragt man einfach die Eigenschaft PrevInstance (Previous Instance) des App-Objekts ab. Ist diese True, so wird zum aktuellen Zeitpunkt die eigene Anwendung bereits ausgeführt. In diesem Fall könnte man ja dann einfach einen Hinweis anzeigen, dass ein mehrfaches gleichzeitiges Ausführen der Anwendung nicht möglich ist, und beendet dann anschliessend die aktuelle "Sitzung". Das ganze würde so aussehen:
Public Sub Main() ' Prüfen, ob Anwendunng bereits gestartet If App.PrevInstance Then MsgBox "Achtung!" & vbCrf & _ "Es läuft bereits eine Instanz dieser Anwendung." & _ vbCrLf & vbCrLf & _ "Ein mehrfaches gleichzeitiges Ausführen ist " & _ "nicht möglich!" ' Anwendung beenden End End if ... End Sub
So, das ganze funktioniert auch schon.
Aber: Wäre es nicht eleganter, im Falle, dass bereits eine Instanz ausgeführt wird, diese sofort zu aktivieren und in den Vordergrund zu bringen - ohne den lästigen Hinweis anzuzeigen?
Ja?
Also gut. Was ist zu tun?
- App.PrevInstance abfragen
- Falls True, das Fenster-Handle der bereits gestarteten Instanz finden (anhand des Fenster-Titels)
- Falls gefunden, Fenster in den Vordergrund bringen
- Anwendung beenden (die zweite Instanz)
Für das Ermitteln des Fenster-Handles greifen wir (wieder einmal) auf das Windows API zurück. Hier gibt es die Funktion FindWindow. Dieser Funktion übergeben wir den Fenster-Titel unserer bereits gestarteten Anwendung, und erhalten zurück - das Handle des Fensters. Eine weitere API-Funktion (SetForegroundWindow) bringt unsere Anwendung dann in den Vordergrund.
Und hier der Code:
' benötigte API-Deklarationen Private Declare Function FindWindow Lib "user32" _ Alias "FindWindowA" ( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long Private Declare Function SetForegroundWindow Lib "user32" ( _ ByVal hWnd As Long) As Long
' Start-Prozedur Public Sub Main() ' Prüfen, ob Anwendunng bereits gestartet If App.PrevInstance Then ' Ja! Jetzt Fenster-Handle ermitteln Dim RetVal As Long RetVal = FindWindow(vbNullString, _ "Fenster-Titel Ihrer Anwendung") If RetVal <> 0 Then ' Anwendung gefunden - jetzt aktivieren Call SetForegroundWindow(RetVal) End If ' zweite Instanz beenden End End If ... End Sub
Beispiel
Kennen Sie das Menüprogramm unserer vb@rchiv CDROM Vol.1? Hier haben wir es für absolut notwendig gefunden, obigen Code einzubauen - denn: Startet man das Menürprogramm und klickt irgendwann auf Minimieren, so "verschwindet" der Eintrag in der Taskleiste und es wird nur noch ein Symbol im Tray-Bereich der Taskbar angezeigt. Gerade jetzt kommt es unseres Erachtens sehr oft vor, dass man das Menüprogramm mehrfach startet, weil man das kleine Symbol im Systemtray gar nicht richtig wahrnimmt.
Wir haben den obigen Code für unser Menüprogramm sogar noch ein klein wenig ausgebaut. Da die Anwendung evtl. minimiert ist, benötigen wir eine Funktion, um die zu aktivierende Anwendung maximiert (oder normal) darzustellen. Auch hier hilft das Windows API wieder mit einer entsprechenden Funktion - ShowWindow.
Und hier der Code, wie wir ihn für das CD-Menüprogramm verwendet haben:
' benötigte API-Deklarationen Private Declare Function FindWindow Lib "user32" _ Alias "FindWindowA" ( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long Private Declare Function ShowWindow Lib "user32" ( _ ByVal hWnd As Long, _ ByVal nCmdShow As Long) As Long Private Declare Function SetForegroundWindow Lib "user32" ( _ ByVal hWnd As Long) As Long Private Const SW_NORMAL = &H1 Private Const SW_MAXIMIZE = &H3
' Start-Prozedur Public Sub Main() ' Prüfen, ob Anwendunng bereits gestartet If App.PrevInstance Then ' Ja! Jetzt Fenster-Handle ermitteln Dim RetVal As Long RetVal = FindWindow(vbNullString, _ "vb@rchiv CD Vol.1 - Das große Visual-Basic " & _ "Archiv - www.vbarchiv.de") If RetVal <> 0 Then ' Anwendung gefunden - jetzt aktivieren Call SetForegroundWindow(RetVal) ' Anwendung maximieren! Call ShowWindow(RetVal, SW_MAXIMIZE) End If ' zweite Instanz beenden End End If ... End Sub
Hinweis zur FindWindow Funktion
Die FindWindow-Funktion ermittelt das Handle des ersten gefundenen Top-Level-Fensters, dessen Fenster-Titel mit dem im 2. Parameter angegebenen String exakt übereinstimmt.