Service: Visual-Basic 6.0 Tipps:

ActiveX-Server zur Laufzeit - und trotzdem früh - binden


Zugegeben diese Überschrift klingt möglicherweise nach völligem Unsinn, und die Aussage an sich ist ja auch ein Widerspruch in sich selbst: Laufzeitbindung kann per Definition keine frühe Bindung sein.

Worum es dabei eigentlich geht, ist ja letzt endlich folgendes:

  • Ich möchte die Art der Klassen, die ich in einem Projekt verwende, erst zur Laufzeit bestimmen
  • Ich möchte trotzdem von den Vorteilen der frühen Bindung profitieren: Syntax-Unterstützung während der Entwicklung und schnelle Codeausführung während der Laufzeit

Beide Anforderungen können mit Visual Basic-Bordmitteln leicht erreicht werden.

Der Schlüssel ist die Technik der Schnittstellen (Interfaces). Ich habe einige kleine VB-Projekte erstellt, die das Konzept an einem Beispiel kompakt verdeutlichen.

Um das Beispiel nachvollziehen zu können, laden Sie die Beispielprojekte herunter, entpacken Sie das Archiv und registrieren Sie drei DLL's mit Hilfe von regsvr32.exe.

Das Beispiel zeigt die Technik an einem sehr einfachen Fall anhand von Personendaten und besteht aus folgenden Projekten:

  Projekt   Beschreibung
  PersonalDataInterface.vbp   Dieses Projekt ist ein ActiveX-Server und besteht aus nur einem einzigen Klassenmodul: 'IPersonalData'.
Bei diesem Klassenmodul handelt es sich um die Schnittstelle(nbeschreibung) - also um unser Interface.
Anders gesagt: In diesem Klassenmodul ist festgelegt, wie Personendaten-Klassen beschaffen sind, die diese Schnittstelle unterstützen.
Wie Sie feststellen werden, wenn Sie sich das Klassenmodul in der VB-Entwicklungsumgebung ansehen, besteht die Klasse ausschließlich aus leeren Prozedur-Rümpfen. Dies ist die VB-Art, Schnittstellen zu definieren. Das ist - zugegeben - wahrscheinlich etwas irritierend, weil sich die Schnittstellendefinition formal nicht von einem normalen (VB-) Klassenmodul unterscheidet (wenn man davon absieht, dass wir in der Schnittstelle ausschließlich leere Prozedur-Rümpfe vorfinden).

  PersonKunsmannRalf.vbp   Dieses Projekt ist ebenfalls ein ActiveX-Server und besteht ebenfalls aus nur einem einzigen Klassenmodul: 'CPersonKunsmannRalf'. Bitte beachten Sie folgende Punkte:
  • Das Projekt hat einen Verweis auf die 'PersonDataInterface'-Schnittstelle (Menü 'Projekt', Befehl 'Verweise')
  • Die Klasse enthält eine 'Implements'-Anweisung für die 'IPersonDataInterface'-Schnittstelle
  • Die Klasse hat keine öffentlichen (Public) Prozeduren sondern ausschließlich die 'Private' deklarierten Methoden der 'PersonDataInterface'-Schnittstelle (Interface)
  PersonMarxGaucho.vbp   Dieses Projekt ist mit den vorhergehend beschriebenen absolut identisch, bis auf die Tatsache, dass die Eigenschaften Prozeduren andere Werte zurückliefern.
  UsingDifferentServers.vbp   Dieses Projekt veranschaulicht die Verwendung der beiden vorhergehenden ActiveX-Server und damit die Möglichkeit, frühe Bindung für unterschiedliche ActiveX-Server zu verwenden.
Das Projekt hat ebenfalls - wie die beiden anderen - einen Verweis auf die 'PersonDataInterface'-Schnittstelle (Interface) - dies ist unbedingt erforderlich, damit die Klassen 'CPersonKunsmannRalf' und 'CPersonMarxGaucho' verwendet werden können.
Darüber hinaus hat das Projekt auch Verweise auf die ActiveX-Server 'PersonKunsmannRalf' und 'PersonMarxGaucho'.

Bitte beachten Sie in diesem Zusammenhang die Routine 'optPerson_Click'. Wie Sie erkennen, können Sie Objekte von den Klassentypen 'CPersonKunsmannRalf' und 'CPersonMarxGaucho' unter Verwendung der 'Set - New'-Syntax oder mit Hilfe der 'CreateObjekt'-Methode erstellen.

Dabei kommt Ihnen die 'CreateObjekt'-Methode hinsichtlich der Flexibilität noch weiter entgegen: Sie benötigen in Ihrem Projekt keine Verweise auf die ActiveX-Server 'PersonKunsmannRalf' oder 'PersonMarxGaucho', um die Server ansprechen zu können. Probieren Sie das aus, in dem Sie die Verweise entfernen und nur den Codeteil mit der 'CreateObjekt'-Methode verwenden.

Das bedeutet für Sie, dass Sie zur Laufzeit die Art der verwendeten ActiveX-Server mit Hilfe von Zeichenketten-Variablen bestimmen können. Sie könnten z.B. eine Datenbanktabelle führen, in die Bezeichnungen von ActiveX-Servern abgelegt werden. Wohlgemerkt: Das alles funktioniert mit früher Bindung.
Die einzige Voraussetzung besteht darin, dass alle ActiveX-Server die von Ihnen definierte Schnittstelle implementieren.

Ergänzende Hinweise:
1. Die oben erwähnte Einbindung des ActiveX-Servers 'PersonalDataInterface' - der ja die Schnittstelle darstellt - erfolgt dadurch, dass ein Verweis auf PersonalDataInterface.dll in das Projekt eingebunden wird. Sie können zu Recht argumentieren, dass es einen völligen Unsinn darstellt, eine DLL zu erzeugen (und ggf. an den Kunden auszuliefern), nur um eine Schnittstelle ansprechen zu können.

Sie könnten statt dessen die Schnittstelle z.B. mit Hilfe der C++ Entwicklungsumgebung schreiben und eine TypeLib (TLB) erzeugen lassen (mehr ist nämlich nicht erforderlich).

Eine andere Möglichkeit haben Sie, wenn Sie über die Enterprise-Edition von VB verfügen: Aktivieren Sie in der Projekteinstellung auf der Karte 'Komponente' die Einstellung 'Remote-Server'. VB erzeugt beim Kompilieren dann neben der DLL eine TLB.

2. Ein grundsätzliches Problem bei der Programmierung von ActiveX-Server mit VB besteht in der Sicherstellung der sog. Binär-Kompatibilität. Ich kann an dieser Stelle nicht auf die Hintergründe eingehen. Nur so viel an dieser Stelle:

Nachdem Sie Ihr ActiveX-Projekt zum ersten Mal kompiliert haben, müssen Sie unbedingt in den Projekteigenschaften auf der Karte 'Komponente' unter 'Versionkompatibilität' die Einstellung 'Binär-Kompatibel' wählen und dabei auf die soeben erstellte Binärdatei (EXE oder DLL) verweisen. Stellen Sie hundertprozentig sicher, dass diese Einstellung getroffen ist und nicht verloren geht (z.B. weil VB beendet wird, ohne dass Sie die Projektdatei gespeichert haben).

Dies gilt genau so und erst recht für ActiveX-Server, die 'nur' eine Schnittstellendefinition beinhalten.

3. Interfaces erhalten per Konvention das Prefix 'I'. Wenn Sie Schnittstellen definieren, sollten Sie sich unbedingt daran halten - auch wenn Sie nicht vor- haben, Ihre Schnittstellen anderen Programmierern zur Verfügung zu stellen. Erstens in Ihrem eigenen Interesse, weil Sie selbst von einer eindeutigen Syntax profitieren und zweitens: Sie können nie wissen - auch wenn Sie nicht vorhaben, Ihre Schnittstellen anderen Programmierern zur Verfügung zu stellen - irgend wann passiert es vielleicht doch.

4. Jede Prozedur der Schnittstelle muss in der Klasse, die sie implementiert, vorhanden sein - auch wenn sie in der konkreten Implementierung nicht erforderlich ist, d.h. es muss mindestens der leere Prozedur-Rumpf vorhanden sein.

Seitenanfang

Kontaktaufnahme- und Terminvereinbarung:

Bei Fragen und für Terminvereinbarungen erreichen Sie uns unter:

0 63 49 99 07 38

0 151 51 95 34 00

Oder nutzen Sie das Kontaktformular




Ihr Ansprechpartner:


Hier sollte das Fahnungsfoto zu sehen sein.

Ralf Kunsmann

Spezialist für VBA-Programmierung
(alle Office-Anwendungen)
Entwickler der
VBA-Extension-Tools