In den Office-Anwendungen Word, Excel oder Access passen wir vorhandene Kontextmenüs per VBA über das Objektmodell von Office an. Auch das Hinzufügen und die Anzeige benutzerdefinierter Kontextmenüs erledigen wir auf diese Weise. Unter Outlook sieht die Situation anders aus: Hier wurde die Definition von Kontextmenüs bereits in die Ribbondefinition integriert. Wir haben dort einen eigenen Abschnitt namens “contextMenu” mit dem wir vorhandene Kontextmenüs anpassen und erweitern können. In diesem Artikel schauen wir uns an, wie wir solche Anpassungen vornehmen und welche Möglichkeiten sich daraus ergeben.
Kontextmenüs in Outlook
Outlook bietet genau wie die übrigen Office-Anwendungen eine Reihe von Kontextmenüs, die für die verschiedensten Elemente oder Bereiche aufgerufen werden können. In Bild 1 sehen wir beispielsweise das Kontextmenü für eine E-Mail.
Bild 1: Ein Kontextmenü in Outlook
Technik zum Anpassen
Die schlechte Nachricht ist: Kontextmenüs unter Outlook lassen sich nur per COM-Add-In anpassen. Die gute ist: Die Basis dafür haben wir bereits in einem weiteren Artikel namens Outlook: Ribbon per COM-Add-In anpassen (www.vbentwickler.de/376) gelegt. Dort haben wir mit dem Tool twinBASIC bereits ein COM-Add-In erstellt, mit dem wir die normalen Ribbonelemente anpassen können, also die tab-, group– oder button-Elemente im Ribbon von Outlook. Dort haben wir auch bereits die Besonderheit hervorgehoben, dass Outlook als einzige Office-Anwendung mehrere Fenster mit jeweils einem eigenen Ribbon hat. Auch dies ist beim Anpassen von Kontextmenüs zu berücksichtigen.
Anpassen oder auch neue Kontextmenüs definieren?
Die nächste Frage, die wir uns stellen müssen: Können wir nur bestehende Kontextmenüs erweitern oder auch neue Kontextmenüs erstellen? Unter Access beispielsweise kann man auf das Betätigen der rechten Maustaste per Ereignisprozedur reagieren und per VBA ein neues Kontextmenü zusammenstellen und dieses auch anzeigen. Probieren wir also aus, ob wir auch in Outlook benutzerdefinierte Kontextmenüs per VBA erstellen können. Dazu fügen wir die folgende Prozedur in ein neues Modul im VBA-Editor von Outlook ein und führen sie aus:
Public Sub KontextmenueAnlegen() Dim cbr As CommandBar Dim cbb As CommandBarButton Set cbr = Application.CommandBars.Add( _ "Benutzerdefiniert", msoBarPopup, , True) ... cbr.ShowPopup End Sub
Die Prozedur scheitert bereits bei Verwendung der CommandBars-Auflistung. Diese liefert den Fehler Objekt unterstützt diese Eigenschaft oder Methode nicht.
Kontextmenü anpassen
Wir müssen uns beim Anpassen des Kontextmenüs also offensichtlich auf das Erweitern oder Ändern von eingebauten Elementen beschränken. Wir schauen uns an einem Beispiel an, wie das grundsätzlich funktioniert. Dabei gehen wir davon aus, dass wir schon ein COM-Add-In wie im Artikel Outlook: Ribbon per COM-Add-In anpassen (www.vbentwickler.de/376) beschrieben erstellt haben.
Für dieses brauchen wir zunächst nur die Funktion GetCustomUI anzupassen, die den Code für die Ribbondefinition zusammenstellt. In diesem Fall fügen wir statt des ribbon-Elements das Element contextMenus zur Ribbondefinition hinzu (siehe Listing 1). Wir können natürlich auch beide gleichzeitig verwenden. Unterhalb dieses Elements legen wir für jedes Kontextmenü, das wir anpassen wollen, ein contextMenu-Element an.
Private Function GetCustomUI(ByVal RibbonID As String) As String Implements IRibbonExtensibility.GetCustomUI Dim strXML As String strXML &= "<customUI xmlns=""http://schemas.microsoft.com/office/2009/07/customui"" loadImage=""LoadImage"">" _ & vbCrLf strXML &= " <contextMenus>" & vbCrLf strXML &= " <contextMenu idMso=""ContextMenuText"">" & vbCrLf strXML &= " <button id=""btn"" label=""Beispielbutton"" onAction=""onAction"" image=""add.ico""/>" & vbCrLf strXML &= " </contextMenu>" & vbCrLf strXML &= " </contextMenus>" & vbCrLf strXML &= "</customUI>" & vbCrLf Return strXML End Function
Listing 1: Zusammenstellen einer Ribbondefinition zur Erweiterung eines Kontextmenüs
Um festzulegen, welches Kontextmenü wir anpassen wollen, benötigen wir die idMso des Elements. In diesem Fall nutzen wir den Wert ContextMenuText. Dieses Kontextmenü erscheint beispielsweise, wenn wir mit der rechten Maustaste in den Entwurf einer E-Mail klicken (wie wir an den Namen der idMso für ein Kontextmenü kommen, beschreiben wir weiter unten).
Wenn wir nun noch ein button-Element wie in hinzufügen und das COM-Add-In erstellen, sieht das entsprechende Kontextmenü wie in Bild 2 aus. Das Icon haben wir wie ebenfalls in dem oben genannten Artikel beschrieben hinzugefügt. Für das button-Element haben wir mit dem onAction-Attribut festgelegt, welche Prozedur beim Anklicken des Buttons aufgerufen werden soll. Diese sieht so aus:
Bild 2: Benutzerdefinierter Button im Kontextmenü
Public Sub OnAction(control As IRibbonControl) MsgBox "Steuerelement: " & control.Id End Sub
Dies zeigt beim Betätigen des Kontextmenüs die angegebene Meldung an und gibt den Namen des angeklickten Steuerelements aus.
Kontextmenüs identifizieren
Wenn wir ein Kontextmenü erweitern wollen, wissen wir erst einmal nicht, wie die idMso für das entsprechende Element heißt. Dazu können wir die Excel-Dateien mit idMso-Werten nutzen, die Microsoft bereitgestellt hat und die wir dem Download zu diesem Artikel beigefügt haben. Diese sind nicht aktuell – Miccrosoft stellt nicht regelmäßig neue Versionen dieser Dateien bereit. Da sich jedoch auch die Ribbons keinen umfangreichen Änderungen unterliegen, ist das erst einmal kein Problem.
Die Namen der meisten Kontextmenüs finden wir in der Datei outlookexplorercontrols.xlsx. Hier haben wir für das Feld ControlType einen Filter mit dem Wert contextMenu definiert und erhalten so die Bezeichnungen aller in der Tabelle enthaltenen Kontextmenüs (siehe Bild 3).
Bild 3: Namen der ContextMenu-Elemente
Wie können wir nun, abgesehen von der intuitiven Zuordnung der Bezeichnungen zu den Bereichen, herausfinden, welches contextMenu-Element in welchem Kontext angezeigt wird?
Dazu fügen wir einfach einem COM-Add-In allen contextMenu-Elementen einen button hinzu, der den Namen des jeweiligen contextMenu-Elements enthält. Dazu nutzen wir unsere Kenntnisse der Excel-VBA-Programmierung und durchlaufen in einer Schleife alle Zeilen des Excel-Dokuments (siehe Listing 2).
Public Sub AlleKontextmenues() Dim i As Long Dim lngLetzteZeile As Long Dim strXML As String Dim strKontextmenue As String lngLetzteZeile = Sheets(1).UsedRange.SpecialCells(xlCellTypeLastCell).Row For i = 1 To lngLetzteZeile If Cells(i, 2) = "contextMenu" Then strKontextmenue = Cells(i, 1) If Not Len(strKontextmenue) = 0 Then strXML = strXML & " strXML &= "" <contextMenu idMso=""""" & strKontextmenue & """"">"" _ & vbcrlf" & vbCrLf strXML = strXML & " strXML &= "" <button id=""""btn" & strKontextmenue _ & """"" label=""""" & strKontextmenue & """"" onAction=""""onAction"""" image=""""add.ico""""/>"" _ & vbcrlf" & vbCrLf strXML = strXML & " strXML &= "" </contextMenu>"" & vbcrlf" & vbCrLf End If End If Next i Inzwischenablage strXML End Sub
Listing 2: Zusammenstellen von contextMenu-Elementen
Dabei prüfen wir jeweils, ob die zweite Spalte den Eintrag contextMenu enthält. In diesem Fall stellen wir drei Codezeilen für das COM-Add-In zusammen, die im Ergebnis beispielsweise wie folgt aussehen (jeweils in einer Zeile):
strXML &= " <contextMenu idMso=""ContextMenuFolder"">" & vbcrlf strXML &= " <button id=""btnContextMenuFolder"" label=""ContextMenuFolder"" onAction=""onAction"" image=""add.ico""/>" & vbcrlf strXML &= " </contextMenu>" & vbcrlf
Solch ein Konstrukt erstellen wir für alle contextMenu-Elemente und fügen diese dann der obigen getCustomUI-Funktion hinzu. Wenn wir das COM-Add-In nun erstellen und danach Outlook erneut öffnen, finden wir in annähernd jedem Kontextmenü einen Eintrag vor, der den Namen des jeweiligen Kontextmenüs enthält (siehe Bild 4).
Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Visual Basic Entwickler:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 200 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein: