Die Community zu .NET und Classic VB.
Menü

Addin-Programmierung - Seite 2

 von 

Die Entwicklungsumgebung
Nächste Seite >>
Übersicht
<< Vorherige Seite

Das Grundgerüst  

Das Grundgerüst eines AddIn

Glücklicherweise ist bei VB schon ein fast fertiges AddIn-Template, das nur noch entsprechend angepasst werden muss, dabei. Hierzu erstellen wir ein neues Projekt und wählen aus der Projektliste den Projekttyp "AddIn" aus. Nun wird das AddIn-Template geladen und im Projektexplorer wird ein neues Projekt "MeinAddIn" angezeigt.

Der Vorteil diese Templates ist, dass man sich nicht um die Verweise kümmern muss und es schon fertigen Code für ein AddIn enthält. Die wichtigsten Verweise sind die "Microsoft Office x.x Object Library" für das Erstellen von Menüeinträgen und die "Microsoft Visual Basic x.x Extensibility" für den Zugriff auf die VB-IDE. Bei VB6 kommt noch der Verweis "Microsoft Add-In Designer" hinzu. Dieser Verweis bildet das eigentliche Interface zwischen VB und einem AddIn. Bei VB5 wird diese Schnittstelle per Code im Modul "Connect" Implementiert.

Ein AddIn-Projekt besteht bei VB6 zumindest aus einer Form (frmAddIn) und einem Designer-Modul (Connect). Bei VB5 besteht das AddIn-Projekt aus einer Form (frmAddIn), einem Modul (AddIn) und einem Klassenmodul (Connect). Die wichtigste Komponente ist bei beiden VB-Versionen das Modul "Connect". Hier wird der Menüeintrag in VB für das AddIn erstellt und die Verbindung zur VBIDE hergestellt.

Der Code im Modul "Connect" ist, bis auf kleine Unterschiede, für beide VB-Versionen fast identisch. Die Funktionsweise des Moduls "Connect" ist aber die gleiche und aus diesem Grund möchte ich hier nur den Code vom VB6-AddIn erläutern.

Das Modul 'Connect'

Das Einbinden eines AddIn in VB geschieht im wesentlichen in 2 Schritten.
1. Instanzieren bzw. Implementieren der Verweise und Events
2. Verbinden des AddIn und Menüeintrag erzeugen

Hier nun der Code des Moduls "Connect" mit etwas ausführlicherer Beschreibung.

Option Explicit

'------------------------------------------------------
' Instanzieren bzw. Implementieren der Verweise und Events
'------------------------------------------------------

' Variable zum Zwischenspeichern ob Form gerade
' sichtbar ist oder nicht
Public FormDisplayed As Boolean

' Variable zum Verweis auf die VBIDE-Schnittstelle
' (Microsoft Visual Basic x.x Extensibility)
Public VBInstance As VBIDE.VBE

' Variable zum Verweis auf die Menü-Schnittstelle
' (Microsoft Office x.x Object Library)
Dim mcbMenuCommandBar As Office.CommandBarControl

' Variable auf Form (frmAddIn)
Dim mfrmAddIn As New frmAddIn

' Implementierung der Menü-Events Schnittstelle
' Ereignisbehandlungsroutine für die Befehlsleiste
Public WithEvents MenuHandler As CommandBarEvents

'------------------------------------------------------
' Diese Methode versteckt die Form.
'------------------------------------------------------
Sub Hide()

    ' Fehlerbehandlung
    On Error Resume Next
    
    'Formstatus setzen
    FormDisplayed = False
    
    'Form verstecken
    mfrmAddIn.Hide

End Sub

'------------------------------------------------------
' Diese Methode zeigt die Form in VB an.
'------------------------------------------------------
Sub Show()
    
    ' Fehlerbehandlung
    On Error Resume Next
    
    If mfrmAddIn Is Nothing Then
        Set mfrmAddIn = New frmAddIn
    End If
    
    'Instanzen an die Form übergeben
    Set mfrmAddIn.VBInstance = VBInstance
    Set mfrmAddIn.Connect = Me
    
    'Formstatus setzen
    FormDisplayed = True
    
    'Form anzeigen
    mfrmAddIn.Show

End Sub

'------------------------------------------------------
' Diese Methode fügt das Add-In in VB ein. Dieses Ereignis
' wird von der Entwicklungsumgebung beim Verbinden
' eines Add-Ins aufgerufen.
'------------------------------------------------------
Private Sub AddinInstance_OnConnection(ByVal Application As Object, _
ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, _
ByVal AddInInst As Object, custom() As Variant)
    
    ' Bei Fehler zur Fehlerbehandlung
    On Error Goto error_handler
    
    ' Speichern der VB-Instance
    Set VBInstance = Application
    
    ' Dieser Stelle eignet sich gut für einen Haltepunkt,
    ' um verschiedene AddIn-Objekte, -Eigenschaften und
    ' -Methoden zu testen.
    'Debug.Print VBInstance.FullName

    ' AddIn wird extern verbunden
    If ConnectMode = ext_cm_External Then
        ' Wird von der Assistenten-Symbolleiste zum
        ' Starten dieses Assistenten verwendet.
        Me.Show
    Else
        ' Erzeugen des Menüeintrages
        ' Übergabeparamter für AddToAddInCommandBar = Caption
        ' im Menüeintrag
        Set mcbMenuCommandBar = AddToAddInCommandBar("Mein AddIn")
        ' Übergeben des Ereignisses an die Behandlungsroutine.
        Set Me.MenuHandler = VBInstance.Events.CommandBarEvents(mcbMenuCommandBar)
    End If
  
    ' Das AddIn wird nach dem Starten der Entwicklungsumgebung verbunden
    If ConnectMode = ext_cm_AfterStartup Then
        
        ' Registry auslesen, ob die Form beim letztem Trennen angezeigt wurde.
        If GetSetting(App.Title, "Settings", "DisplayOnConnect", "0") = "1" Then
            ' Wenn ja, dann anzeigen des Formulars beim Verbinden.
            Me.Show
        End If
    
    End If
  
    ' Wenn alles ok, dann Methode verlassen
    Exit Sub
    

' Fehlerbehandlung
error_handler:
    
    ' Fehler anzeigen
    MsgBox Err.Description
End Sub

'------------------------------------------------------
' Diese Methode entfernt das Add-In aus VB. Dieses Ereignis
' wird von der Entwicklungsumgebung beim Trennen
' eines Add-Ins aufgerufen.
'------------------------------------------------------
Private Sub AddinInstance_OnDisconnection(ByVal RemoveMode As _
AddInDesignerObjects.ext_DisconnectMode, custom() As Variant)
    
    ' Fehlerbehandlung
    On Error Resume Next
    
    ' Löschen des Befehlsleisteneintrags.
    mcbMenuCommandBar.Delete
        
    ' In Registry speichern, ob Form beim Trennen angezeigt wurde.
    If FormDisplayed Then 'True
        SaveSetting App.Title, "Settings", "DisplayOnConnect", "1"
        FormDisplayed = False
    Else
        SaveSetting App.Title, "Settings", "DisplayOnConnect", "0"
    End If
    
    ' Beenden des Add-Ins.
    Unload mfrmAddIn
    Set mfrmAddIn = Nothing

End Sub

'------------------------------------------------------
' Dieses Ereignis wird von der Entwicklungsumgebung aufgerufen,
' wenn das Starten der Entwicklungsumgebung abgeschlossen ist.
'------------------------------------------------------
Private Sub IDTExtensibility_OnStartupComplete(custom() As Variant)
    
    ' Registry auslesen, ob die Form beim letztem Trennen angezeigt wurde.
    If GetSetting(App.Title, "Settings", "DisplayOnConnect", "0") = "1" Then
        ' Wenn ja, dann anzeigen des Formulars beim Verbinden.
        Me.Show
    End If

End Sub

'------------------------------------------------------
' Dieses Ereignis wird ausgelöst, wenn auf das erstellte Menü
' in der IDE (Intgrierte Entwicklungsumgebung) geklickt wird.
'------------------------------------------------------
Private Sub MenuHandler_Click(ByVal CommandBarControl As Object, _
handled As Boolean, CancelDefault As Boolean)
    
    ' Anzeigen der Form
    Me.Show

End Sub

'------------------------------------------------------
' Diese Funktion fügt einen Eintrag im Menü "Add-Ins" hinzu.
'------------------------------------------------------
Function AddToAddInCommandBar(sCaption As String) _
As Office.CommandBarControl
'Übergabeparameter sCaption = Caption im Menüeintrag

    'Befehlsleistenobjekt
    Dim cbMenuCommandBar As Office.CommandBarControl
    Dim cbMenu As Object
  
    ' Bei Fehler zur Fehlerbehandlung
    On Error Goto AddToAddInCommandBarErr
    
    'Suchen des Menüs "Add-Ins".
    Set cbMenu = VBInstance.CommandBars("Add-Ins")
    If cbMenu Is Nothing Then
        'Nicht verfügbar. Fehler.
        Exit Function
    End If
    
    'Hinzufügen zur Befehlsleiste.
    Set cbMenuCommandBar = cbMenu.Controls.Add(1)
    
    'Festlegen der Beschriftung.
    cbMenuCommandBar.Caption = sCaption
    
    Set AddToAddInCommandBar = cbMenuCommandBar
    
    ' Wenn alles ok, dann Methode verlassen
    Exit Function
    
' Fehlerbehandlung
AddToAddInCommandBarErr:

End Function

Die Form 'frmAddin'

Die Form selber enthält im Grundgerüst bisher nur wenig Code und zwei Buttons.

'------------------------------------------------------
' Instanzieren bzw. Implementieren der Verweise
'------------------------------------------------------

' Variable zum Verweis auf die VBIDE-Schnittstelle
' (Microsoft Visual Basic x.x Extensibility)
Public VBInstance As VBIDE.VBE

' Variable auf den Designer bzw. Klassenmodul "Connect"
Public Connect As Connect

Option Explicit

Private Sub CancelButton_Click()
    ' Verstecken der Form
    ' Ruft im Modul "Connect" die Sub "Hide" auf
    Connect.Hide
End Sub

Private Sub OKButton_Click()
    ' Gibt den vollständigen Pfad zur
    'Visual Basic-Anwendung zurück.
    MsgBox "AddIn operation on: " & VBInstance.FullName
End Sub

Der kleine Unterschied zu VB5

Die Implementierung der AddIn-Schnittstelle erfolgt hier nicht über den Verweis "Microsoft Add-In Designer", sondern durch Implementierung direkt im Code des Klassenmoduls "Connect".

Option Explicit

' Implementierung der AddIn-Schnittstelle
Implements IDTExtensibility

Der restliche Code im Klassenmodul ist im wesentlichen der gleiche wie bei VB6. Außerdem ist im VB5 AddIn-Projekt noch ein weiteres Modul (AddIn) vorhanden. Bei VB5 muss, bevor man das AddIn testen kann, noch ein Schlüssel in der "vbaddin.ini" eingetragen werden. Die "vbaddin.ini" befindet sich im Windows-Ordner. Der Schlüssel lautet in diesem Fall "MeinAddIn.Connect=0" und setzt sich aus AddInProjektName.KlassenmodulName=Anzeigestatus zusammen. Diesen Schlüssel könnte man per Hand eintragen oder über das im VB5 AddIn-Projekt enthaltene Modul "AddIn" erledigen lassen. Dazu muss im Direktfenster der Befehl "AddToIni" eingegeben und mit Enter bestätigt werden. Hierdurch wird in dem Modul "AddIn" die Sub "AddToIni" ausgeführt, der den Eintrag in der "vbaddin.ini" automatisch vornimmt. Hier der Code zum Modul "AddIn".

Option Explicit

Declare Function WritePrivateProfileString& Lib "Kernel32" _
Alias "WritePrivateProfileStringA" (ByVal AppName$, _
ByVal KeyName$, ByVal keydefault$, ByVal FileName$)

'====================================================================
' Diese Prozedur sollte vom Direktfenster aus ausgeführt werden
' damit diese Anwendung korrekt zu VBADDIN.INI hinzugefügt wird,
' müssen Sie den Namen im zweiten Argument entsprechend dem
' Projektnamen anpassen.
'====================================================================
Sub AddToINI()
    Dim ErrCode As Long
    ErrCode = WritePrivateProfileString("Add-Ins32", _
    "MeinAddIn.Connect", "0", "vbaddin.ini")
End Sub

Dieses Eintragen des Schlüssels in der "vbaddin.ini" muss nur einmal vorgenommen werden.

Der erste Test des AddIn-Template

Leider kann man das AddIn nicht direkt in der Entwicklungsumgebung testen in der es gerade erstellt wird, wie man es von normalen Anwendungen her kennt (z.B. Standard-EXE). Um ein fertiges AddIn zu testen, müsste es erst kompiliert werden. Dann muss in der Entwicklungsumgebung ein neues Projekt geladen werden. Erst dann kann man das AddIn über den AddIn-Manager laden und ausführen. Wenn man dann noch einen Fehler im AddIn entdeckt, so müsste man diesen wieder über den AddIn-Manager entladen und das AddIn-Projekt wieder laden. Nach dem Beseitigen des Fehlers wieder kompilieren, wieder ein neues Projekt laden und so weiter.

Es geht aber auch etwas einfacher. Dazu benötigen man zwei Instanzen der VB-Entwicklungsumgebung. In der ersten Instanz haben wir unser AddIn-Projekt und in der zweiten Instanz laden wir ein Standard-Exe Projekt. In der ersten Instanz wird das AddIn ausgeführt (F5). Nach dem Starten des AddIn, wechseln wir in die zweite Instanz von VB und können nun das AddIn über den AddIn-Manager laden und testen. Wenn man nun am AddIn weiter arbeiten möchte, muss man das AddIn in der zweiten Instanz von VB über den AddIn-Manager nur wieder entladen und in der ersten Instanz von VB das AddIn-Projekt beenden. Wir umgehen so das ständige Neukompilieren und das Laden eines anderen Projektes zum Testen.

Nachdem das AddIn über den AddIn-Manager geladen wurde, wird im Menü "Add-Ins" ein neuer Menüeintrag "Mein AddIn" angezeigt. Wenn man nun auf diesen Menüeintrag klickt, dann wird das AddIn angezeigt. Klickt man nun auf den "OK"-Button in der Form, wird in einer Messagebox der Pfad zur VB-Entwicklungsumgebung angezeigt. Wenn man auf den Button "Cancel" klickt, wird das AddIn versteckt.

Hinzufügen eines Bildes vor den Menüeintrag

Schauen wir uns mal die Einträge im Menü "Add-Ins" mal genauer an. Bei allen anderen AddIns ist ein Picture vor der Caption, nur bei unserem AddIn nicht. Beim AddIn-Template wurde einfach die Möglichkeit des Anzeigens eines Pictures vor der Caption vergessen. Damit auch wir ein Picture vor die Caption bekommen, müssen wir unser AddIn durch zwei Zeilen Code im Modul "Connect" erweitern und eine Ressourcendatei erstellen. Dazu gehen wir wieder in den Bearbeitungsmodus des AddIn und erstellen über den Ressourceneditor eine Ressourcendatei mit einem 16x16 Pixel Picture und fügen diese Ressourcendatei in unser AddIn-Projekt hinzu. Danach erweitert man im Modul "Connect" die Funktion "AddToAddInCommandBar" um zwei Zeilen Code. Unter der Zeile

' Festlegen der Beschriftung.
    cbMenuCommandBar.Caption = sCaption

fügen wir folgende Zeilen hinzu.

' Kopieren des Picture in die Zwischenablage
' Das zuladende Picture muss eine Bitmap mit 16*16 Pixel sein
Clipboard.SetData LoadResPicture(101, 0)
' Einfügen des Picture aus der Zwischenablage in den
' Menüeintrag
cbMenuCommandBar.PasteFace

Wenn wir jetzt wieder das AddIn testen, wird auch ein Picture vor der Caption angezeigt.

Abschließend zum AddIn-Template

Das AddIn-Template ist wie gesagt ja nur das Grundgerüst zu einem AddIn und enthält bisher nur wenig Funktionen. Außer den Pfad zur VB-Entwicklungsumgebung anzuzeigen, kann das AddIn noch nicht sehr viel. Das werden wir aber in den nächsten Kapiteln ändern und ich möchte zeigen, welche Möglichkeiten die VBIDE-Schnittstelle dazu bietet.

Die VBIDE-Schnittstelle

Da wir direkt über die VBIDE-Schnittstelle programmieren, auf der die VB-Entwicklungsumgebung ja auch aufgebaut, muss folgendes beachtet werden. Jeder kleine Programmierfehler mit der VBIDE-Schnittstelle kann die Entwicklungsumgebung zum Absturz bringen, Einstellungen verändern und sogar Quellcode eines geladenen Projektes zerschießen. Daher sollte man bei der Programmierung eines AddIns, die Fehlerbehandlungsroutinen nicht vergessen und auf genaue Schreibweisen achten.

Die VBIDE-Schnittstelle stellt alle Objekte, Klassen, Funktionen und Events bereit, um auf die gesamte VB-Entwicklungsumgebung zugreifen zu können. Um mal einen groben Überblick über die VBIDE zu erhalten, öffnen wir den Objekt-Browser und wählen die Bibliothek "VBIDE" aus. Im unterem Teil des Objekt-Browsers werden nun alle Objekte der VBIDE-Schnittstelle angezeigt. Jedes Objekt enthält weitere Klassen, Funktionen, Subs, Propertys oder Konstanten. Da die VBIDE-Schnittstelle doch sehr umfangreich ist, möchte ich hier nur einige Objekte und deren Verwendung vorstellen.

ObjektName Verwendung und Funktion
AddIns AddIn-Collection Objekt / Liste alle geladenen Addins
AddIn Ermöglicht den Zugriff auf ein AddIn in der VB-Entwicklungsumgebung
Windows Fenster-Collection Objekt / Liste aller Fenster
Window Ermöglicht den Zugriff auf ein Fenster in der VB-Entwicklungsumgebung
VBProjects Projekt-Collection Objekt / Liste aller geladenen Projekte
VBProject Ermöglicht den Zugriff auf ein Projekte in der VB-Entwicklungsumgebung
VBComponents Komponent-Collection Objekt / Liste aller Komponenten in einem Projekt
VBComponent Ermöglicht den Zugriff auf eine Komponente in einem Projekt
CodeModule Ermöglicht den Zugriff auf den Code in einer Komponente
Members Member-Collection Objekt / Liste aller Member-Objekte
Member Ermöglicht den Zugriff auf ein Member-Objekt in einer Komponente
Nächste Seite >>
Die Entwicklungsumgebung
<< Vorherige Seite
Übersicht