ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 04.01.2001

Diese Seite wurde zuletzt aktualisiert am 04.01.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Es kann nur eine geben...

Zurück...


Anzeige

(-hg) mailto:hg_previnstanceax@aboutvb.de

Die Eigenschaft PrevInstance des App-Objekts teilt Ihnen mit, ob bereits eine andere Instanz Ihrer Anwendung läuft. Wenn Sie nun bei einem erneuten Start Ihrer Anwendung eine solche vorhergehende Instanz lediglich aktivieren möchten, anstatt die Anwendung zum zweiten Mal auszuführen, bedarf es einiger Kunstgriffe. Visual Basic hält dazu unverständlicherweise leider keine eigenen Bordmittel bereit.

Eine relativ bekannte Möglichkeit ist, über eine Reihe von API-Funktionen ein Fenster (Form) der vorhergehenden Instanz ausfindig zu machen und zu aktivieren, und es gegebenenfalls wiederherzustellen, falls es minimiert sein sollte. In der Regel funktioniert dies auch ganz gut. Allzu sicher ist das Verfahren jedoch nicht, da zwischen der bereits laufenden Instanz und der sich um die Reaktivierung derselben bemühenden neuen Instanz keinerlei direkte Beziehung besteht. Zum einen könnten Sie unabsichtlich eine völlig andere Anwendung reaktivieren, falls zufällig verschiedene Namensübereinstimmungen zu Ihrer Anwendung bestehen sollten. Zum anderen kann die neue Instanz nichts über den Zustand der laufenden Anwendung wissen. Sie kann vielleicht vergeblich nach dem zu reaktivierenden Form suchen, während dieses gar nicht geladen ist. Oder dieses Form ist zufällig gesperrt, weil der Anwender gerade ein anderes Form Ihrer Anwendung modal geöffnet hat. Je nach Komplexität Ihrer Anwendung können weitere Unwägbarkeiten hinzukommen, über die sich die neu startende Instanz nur mit (für VB-Verhältnisse) recht hohem Aufwand über API-Mechanismen informieren könnte. Auch ist eine gezielte Kommunikation zwischen den beiden Instanzen, etwa Übergabe der Kommandozeilen-Parameter der neuen Instanz an die alte und dergleichen, nicht so einfach zu erreichen. Ich will daher auf diesen Weg gar nicht erst weiter eingehen.

Mit nur minimalem Aufwand können Sie hingegen über ActiveX einen sicheren und sehr flexiblen Mechanismus etablieren, mit direkter Verständigung zwischen der laufenden und jeder neu hinzukommenden Instanz. Und natürlich mit problemloser Übergabe der Kommandozeilen-Parameter von der neuen an die laufende Instanz.

Dazu verwandeln Sie Ihre eigentliche Anwendung einfach in eine ActiveX-EXE und schalten eine kleine Starter-Anwendung (weiterhin eine gewöhnliche Standard-EXE) vor. Diese Starter-EXE erweckt die ActiveX-EXE beim ihrem ersten Aufruf zum Leben. Bei jedem weiteren Aufruf reaktiviert sie nur noch die bereits laufende Instanz der ActiveX-EXE, und kann mit ihr beliebig Informationen austauschen oder Anweisungen an sie absetzen.

Schauen wir uns zunächst einmal das einfachste Modell einer solchen Konstruktion an. Ihre zur ActiveX-EXE mutierte Anwendung benötigt zusätzlich nichts weiter, als eine öffentliche und instanzierbare Klasse - wie jede andere ActiveX-EXE. Diese Klasse, nennen wir sie "Instance", braucht noch nicht einmal über Methoden und Eigenschaften zu verfügen. Lediglich ihre Class_Initialize-Prozedur wird benötigt. In dieser laden Sie das Hauptform (Form1, oder wie Sie es auch immer genannt haben mögen) der Anwendung, falls es noch nicht geladen sein sollte. Und hier reaktivieren sie es gegebenenfalls und stellen es wieder her, falls es minimiert sein sollte.

Private Sub Class_Initialize()
  If Forms.Count = 0 Then
    Load Form1
  End If
  
  With Form1
    If .WindowState = vbMinimized Then
      .WindowState = vbNormal
    End If
    .Show
  End With
End Sub

Die Starter-EXE besteht nur aus einem Standard-Modul mit einer Sub Main-Prozedur. Dazu nehmen Sie einen Verweis auf Ihre ActiveX-EXE-Anwendung auf. Beachten Sie, dass die Klasse Instance separat deklariert und instanziert werden muss. Bei einer Deklaration wie

Dim nInstance As New Instance

würde nämlich nicht sofort deren Class_Initialize-Prozedur aufgerufen, sondern erst bei einem Zugriff auf eine Methode oder Eigenschaft der Klasse - über die diese ja gar nicht verfügt.

Public Sub Main()
  Dim nInstance As Instance

  Set nInstance = New Instance
End Sub

Das war nun auch schon alles. Der einzige Unterschied zu Ihrer früher "normalen" Anwendung besteht darin, dass Sie bzw. die Anwender diese nicht mehr direkt starten, sondern statt dessen nur noch die Starter-EXE. Natürlich sollte sich diese auch mit dem eigentlichen Icon Ihrer Anwendung darstellen - wie das ohne ein Form in der Starter-EXE zu bewerkstelligen ist, können Sie in Icon aus dem Nichts"Icon aus dem Nichts" nachlesen.

Falls es jedoch weiterhin möglich sein soll, trotzdem ganz bewusst eine zweite Instanz Ihrer Anwendung zu starten, rufen Sie die Starter-EXE mit einem Kommandozeilen-Parameter (beispielsweise "/X") auf. In ihrer Sub Main-Prozedur rufen Sie in diesem Fall die ActiveX-EXE als Standalone-Anwendung auf (beide EXEs sollten sich der Einfachheit halber im gleichen Verzeichnis befinden).

Public Sub Main()
  Dim nInstance As Instance

  If UCase$(Command$) = "/X" Then
    Shell "Anwendung.exe", vbNormalFocus
  Else
    Set nInstance = New Instance
  End If
End Sub

Damit auch dann das Hauptform der Anwendung geladen und angezeigt wird, braucht nun auch die ActiveX-EXE ein Standard-Modul mit einer Sub Main-Prozedur.

Public Sub Main()
  If App.StartMode = vbSModeStandalone Then
    Form1.Show
  End If
End Sub

Bis jetzt fehlt allerdings noch die Möglichkeit des Informationsaustauschs zwischen Ihrer als ActiveX-EXE laufenden Anwendung und einer später gestarteten Starter-EXE.

Eine wie bisher sozusagen "stumme" Verbindungsklasse braucht ja schließlich nicht zu sein. Sie können die Klasse Instances mit einer Methode versehen, der sie die Kommandozeile als Parameter übergeben. In dieser Methode haben Sie den vollen Zugriff auf Ihre Anwendung - über die Forms-Collection auf alle geladenen Forms und auf globale Variablen. Hier können Sie nach Herzenslust die Kommandozeile auswerten und anstellen, was immer Sie wollen.

Public Function Start(Params As String) As Variant
'...
End Sub

Sie können auch den bisherigen Inhalt der Class_Initialize-Prozedur hierher verschieben und so etwa gegebenenfalls anhand der übergebenen Kommandozeile entscheiden, welches Form (re)aktiviert werden soll. So können Sie auch schon beim ersten Start die Kommandozeile nach Belieben auswerten.

In der Sub Main-Prozedur rufen Sie dann eben noch zusätzlich diese Methode auf:

Public Sub Main()
  If UCase$(Command$) = "/X" Then
    Shell "Anwendung.exe", vbNormalFocus
  Else
    With New Instance
      .Start Command$
    End With
  End If
End Sub

Die Methode Start der Instance-Klasse ist hier einfach rein vorsorglich als Funktion ausgelegt. Sie können Sie natürlich auch schlicht als Sub-Prozedur anlegen, wenn Sie keinen Bedarf dafür haben, der Starter-EXE irgendwelche Informationen zurückzugeben, die dort nachträglich noch ausgewertet werden und zu weiteren Aktionen (etwa einer Meldung für den Anwender) führen könnten.


Beispiel-Projekt PrevInstanceStarter/App (previnstanceax.zip - ca. 15,1 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer