Möchtest Du den gesamten Artikel lesen? Und vielleicht sogar den Artikel im PDF-Format und die Beispieldateien herunterladen? Dann hole Dir den Artikel gleich hier - völlig kostenlos!
Wir haben bereits in einigen weiteren Artikel beschrieben, wie wir unseren Anwendungen in Word, Excel oder Access benutzerdefinierte Kontextmenü-Einträge oder sogar vollständige Kontextmenüs hinzufügen können. Was wird dort noch nicht berücksichtigt haben: Manchmal möchte man vielleicht ein eingebautes Element in einem benutzerdefinierten Kontextmenü oder gar ein vollständiges Menü nachbauen, um dann selbst genauer zu steuern, wann dieses angezeigt werden soll. Ein gutes Beispiel sind die Befehle für die Verwendung der Zwischenablage, also Ausschneiden, Kopieren und Einfügen. Es kann sinnvoll sein, diese einem benutzerdefinierten Kontextmenü hinzuzufügen. In diesem Artikel beschreiben wir, wie Du herausfindest, welche Informationen über das eingebaute Kontextmenü-Element benötigst und wie Du dieses in einem benutzerdefinierten Kontextmenü abbildest.
In den vorherigen Ausgaben haben wir bereits in einigen Artikeln die Programmierung von Kontextmenüs beschrieben:
- Menüs im VBA-Editor anpassen (www.vbentwickler.de/434)
- Menüs per VBA programmieren (www.vbentwickler.de/435)
- Kontextmenüs per VBA programmieren (www.vbentwickler.de/368)
Auch auf die Anpassung von Kontextmenüs in Outlook sind wir bereits eingegangen – siehe Outlook: Kontextmenüs anpassen (www.vbentwickler.de/369).
In diesem Artikel nun schauen wir uns im Detail an, wie wir die eingebauten Kontextmenü-Befehle in benutzerdefinierte Kontextmenüs einbauen können – zum Beispiel die aus Bild 1.
Bild 1: Beispiel für ein eingebautes Kontextmenü
Dazu sind die folgenden Schritte nötig:
- Ermitteln von Informationen, mit denen wir die eingebauten Kontextmenü-Einträge identifizieren können
- Einbau der Einträge in ein benutzerdefiniertes Kontextmenü
Identifizieren der eingebauten Kontextmenü-Befehle
Der erste Schritt ist relativ aufwendig. Wir können nicht einfach ein Kontextmenü öffnen und dieses beispielsweise anhand des Namens identifizieren. Stattdessen benötigen wir einen anderen Wert, nämlich die ID dieses Eintrags.
An diesen kommen wir jedoch auch nicht so leicht. Es gibt keine Möglichkeit, diese ID direkt auszulesen.
Daher bauen wir uns eine Tabelle und eine Prozedur, um diese Tabelle mit den Informationen zu den Kontextmenü-Einträgen zu füllen.
Tabelle zum Speichern der Kontextmenü-Einträge
Die Tabelle heißt tblControls und sieht in der Entwurfsansicht wie in Bild 2 aus.
Bild 2: Entwurf der Tabelle zum Speichern der Kontextmenü-Einträge mit Eigenschaften
Nachdem wir die Tabelle per Code gefüllt haben, sollte diese etwa wie in Bild 3 aussehen.
Bild 3: Datenblattansicht der Tabelle zum Speichern der Kontextmenü-Einträge mit Eigenschaften
Hauptprozedur zum Einlesen der Kontextmenü-Elemente
Die Prozedur KontextmenuesEinlesen aus Listing 1 ist die Hauptprozedur zum Einlesen der Steuerelemente der Kontextmenüs.
Public Sub KontextmenuesEinlesen() Dim cbr As CommandBar Dim cbc As CommandBarControl Dim db As dao.Database Dim lngID As Long Set db = CurrentDb db.Execute "DELETE FROM tblControls", dbFailOnError For Each cbr In Application.CommandBars If cbr.BuiltIn = True Then Select Case cbr.Type Case msoBarTypePopup For Each cbc In cbr.Controls If cbc.BuiltIn = True Then On Error Resume Next db.Execute "INSERT INTO tblControls(ControlID, ControlCaption, CommandBar, Index, " _ "ControlTypeID, ControlType) VALUES(" & cbc.Id & ", ''" & cbc.Caption & "'', ''" _ & cbr.Name & "'', " & cbc.Index & ", " & cbc.Type & ", ''" _ & ControlTypeString(cbc.Type) & "'')", dbFailOnError lngID = db.OpenRecordset("SELECT @@IDENTITY").Fields(0) On Error GoTo 0 End If Select Case cbc.Type Case msoControlButton, msoControlComboBox, msoControlExpandingGrid, msoControlEdit, _ msoControlGrid Case msoControlPopup, msoControlButtonPopup, msoControlSplitButtonMRUPopup, _ msoControlSplitButtonPopup Call UntermenuesEinlesen(db, cbc, lngID, cbr.Name) Case Else Debug.Print cbc.Type End Select Next cbc End Select End If Next cbr End Sub
Listing 1: Die Prozedur KontextmenuesEinlesen liest die Elemente der ersten Ebene in die Tabelle tblControls ein.
Um diese zu nutzen, müssen wir zuvor einen Verweis auf die Bibliothek Microsoft Office 16.0 Object Library setzen (siehe Bild 4). Diese enthält das Objektmodell für den Zugriff auf die CommandBar-Elemente, also die Menüs.
Bild 4: Verweis auf die Office-Bibliothek
Die Prozedur KontextmenuesEinlesen startet damit, die Tabelle tblControls vollständig zu leeren. Das erledigt sie durch den Aufruf einer DELETE-Anweisung.
Danach durchläuft sie in einer äußeren For Each-Schleife alle Elemente der CommandBars-Auflistung. Diese Auflistung enthält alle Menüleisten der jeweiligen Anwendung. Dazu gehören auch alle benutzerdefinierten Elemente und auch die in den moderneren Office-Versionen (ab 2007) nicht mehr sichtbaren Menü- und Symbolleisten.
Da wir weder an den Steuerelementen der benutzerdefinierten Menüleisten interessiert sind noch an denen, die in früheren Menü- und Symbolleisten angezeigt wurden, schließen wir diese aus.
Die benutzerdefinierten Elemente ignorieren wir in einer If…Then-Bedingung, in der wir die Eigenschaft BuiltIn des jeweiligen CommandBar-Elements untersuchen. Hat diese den Wert True, sind wir an der richtigen Stelle.
Den Typ des Menüs prüfen wir in einer Select Case-Bedingung, in der wir den Wert der Eigenschaft Type des CommandBar-Elements mit dem Wert der Konstanten msoBarTypePopup vergleichen, was dem Typ für die Kontextmenüs entspricht.
Stoßen wir auf ein solches Kontextmenü, durchlaufen wir in einer weiteren Schleife alle Steuerelemente dieses Menüs. Das erledigen wir in einer For Each-Schleife, die alle Elemente von cbr.Controls durchläuft und das aktuelle Element jeweils mit der Variablen cbc referenziert. cbc hat den Datentyp CommandBarControl, was erst einmal alle möglichen Steuerelementtypen umfasst.
In dieser Schleife prüfen wir wiederum in einer If…Then-Bedingung auf die Eigenschaft BuiltIn, denn auch bei den Kontextmenü-Befehlen können sich benutzerdefinierte Elemente eingeschlichen haben. Diese wollen wir jedoch ignorieren.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo