Customizing Context Menus in Office 2010
Summary: The ability to customize context menus in the Microsoft Office Fluent User Interface is a feature frequently requested by developers. Learn more about how to customize context menus and see a sample that updates an existing context menu in Microsoft Word 2010. (6 printed pages)
Applies to: Excel 2010 | Office 2007 | Office 2010 | Open XML | PowerPoint 2010 | SharePoint Server 2010 | VBA | Word 2010
Published: November 2009
Contents
Introducing Context Menus in Microsoft Office 2010
Capabilities and Limitations of Context Menu Customization
Customizing Context Menu Sample
Conclusion
Additional Resources
Introducing Context Menus in Microsoft Office 2010
Prior to Microsoft Office 2010, the only way to customize context (right-click) menus in the Microsoft Office Fluent Ribbon user interface (UI) was by using CommandBars solutions. In Office 2010, you can customize built-in context menus just as you can the other components of the Ribbon UI. This XML-based context menu extensibility model is based on the familiar Ribbon extensibility model. This means that you can use the same XML markup and callbacks that you currently use to customize the Ribbon UI. Additionally, enabling context menu customizations through Ribbon UI extensibility does not "break" previously written command bar solutions. And like the Ribbon UI extensibility scenarios that you are already familiar with, you can customize context menus by updating Office Open XML Format files or by using add-ins create in Microsoft Visual Studio.
Note
For more information about how to customize the Ribbon UI, see the three-part series of articles beginning with Customizing the 2007 Office Fluent Ribbon for Developers.
Capabilities and Limitations of Context Menu Customization
Context menu customization by using Ribbon extensibility offers you many options. Features include the following:
You can add built-in and custom controls (those types currently supported in the Ribbon menu control) to built-in context menus as follows:
Add controls at any position in the menu.
Add controls to any submenu.
Add custom submenus to built-in context menus.
Hide controls in built-in menus.
Add menu separator lines before or after any context menu item.
You can dynamically populate (when the submenu is expanded) custom submenus by using the dynamicMenu control.
You can also dynamically populate custom galleries that are displayed on the context menu.
The following are options not available when customizing the context menu:
Adding control types that are currently not supported in context menus (such as combo boxes and inputs). This is discussed later in the article.
Re-assigning control labels and icons for built-in context menu controls.
Reordering controls within built-in context menus and submenus.
Dynamically populating built-in context menus.
Customizing Context Menu Sample
You use many of the same commands and controls to customize context menus as you do to customize the Ribbon UI. The following lists the controls allowed in context menus:
control
button
checkBox
dynamicMenu
gallery
menu
menuSeparator
splitButton
toggleButton
To see how context menu extensibility works, look at the following example. The example modifies the Text context menu seen in Microsoft Word 2010 and performs the following actions:
Hides the built-in Font button
Adds a toggle button
Inserts a new button before the Hyperlink button
Inserts a separator bar
Adds a menu with a button
Adds a gallery control
Adds a dynamic menu (created at runtime) with one button and a submenu
In the following procedure, you add the XML markup that customizes the Text context menu in Word 2010. You can easily add the customization XML to the document by using the Office 14 Custom UI Editor, but be aware that this markup also works for COM add-ins also. The Custom UI Editor is a free tool created by Trang Luu of the Microsoft Office User Experience team and is available at OPENXMLDeveloper.org. Use this tool in the following steps.
Add XML markup to the Word 2010 document
Start Word 2010.
Add text to the document. In the body of the document, type =rand(5, 5). This statement adds five paragraphs, each with five sentences of random text to the document
Save the document as a macro-enabled file that is named TestDocument.docm and close the file.
Start the Office 2010 Custom UI Editor and on the File menu, click Open.
Navigate to the test document that you created, and then click Open.
Right-click the file name in the left pane, and then click Insert Office 2010 Custom UI Part as shown in Figure 1. This adds a customUI14.xml part to the document.
Figure 1. Using the Custom UI Editor to insert an Office 2010 part into the document
In the right pane, insert the following XML markup:
<customUI xmlns="https://schemas.microsoft.com/office/2009/07/customui"> <contextMenus> <contextMenu idMso="ContextMenuText"> <button idMso="FontDialog" visible="false" /> <toggleButton id="MyToggle" label="My Toggle Button" /> <button id="MyButton" label="My Button" insertBeforeMso="HyperlinkInsert" onAction="GetButtonID" /> <menuSeparator id="MySeparator" /> <menu id="MySubMenu" label="My Submenu" > <button id="MyButton2" label="Button on submenu" /> </menu> <gallery id="galleryOne" label="My Gallery"> <item id="item1" imageMso="HappyFace" /> <item id="item2" imageMso="HappyFace" /> <item id="item3" imageMso="HappyFace" /> <item id="item4" imageMso="HappyFace" /> </gallery> <dynamicMenu id="MyDynamicMenu" label= "My Dynamic Menu" getContent="GetMyContent" /> </contextMenu> </contextMenus> </customUI>
The XML adds controls to the built-in Text context menu as denoted by the idMso="ContextMenuText" attribute setting of the <contextMenu> tag. This first button sets the visible attribute of the built-in Font button to false, hiding the command. After the toggleButton, you insert the second button before the Hyperlink button on the context menu based on the insertBeforeMso="HyperlinkInsert" setting. After the menuSeparator bar, you add a menu control with a single button. Next, you add a gallery control with four items. And finally, when the context menu is displayed, the dynamicMenu control makes a call to the method specified in the getContent attribute. As you will see, this method returns additional controls to the fly-out at runtime.
Click the Validate button on the Custom UI Editor to make sure that the markup contains no errors. Correct any errors, if necessary, until the markup is error free and you receive a message stating that it is well-formed.
Save the file and close the editor.
Insert the following VBA code into the code pane.
Sub GetButtonID(control As IRibbonControl) MsgBox ("You click the " & control.ID & " button.") End Sub Sub btnAction(control As IRibbonControl) MsgBox ("You clicked me!") End Sub
You call these methods by two buttons on the context menu. Notice that in each method, an IRibbonControl object argument is passed representing the control that called the procedure. The IRibbonControl object has an Id property used in the GetButtonID method to determine which button called the procedure. The Id property is useful because it enables multiple controls to call the same method and then perform different tasks based on the control’s identifier.
Next, you add Microsoft Visual Basic for Applications (VBA) code that adds functionality to the controls that you just added.
Add VBA code to the document
Open the TestDocument.docm file that you created in the previous steps.
Click the Developer tab and then click Visual Basic. This opens the Visual Basic Editor.
In the left pane, double-click the ThisDocument node. This displays the code pane.
Add the following method to the code pane.
Sub GetMyContent(control As IRibbonControl, ByRef content) Dim xmlString As String xmlString = "<menu " & _ "https://schemas.microsoft.com/office/2009/07/customui"">" xmlString = xmlString & "<button id=""btn1"" imageMso=""HappyFace"" " & _ " label=""Click Me"" onAction=""btnAction"" />" xmlString = xmlString & "<menu id=""mnu"" label=""My Dynamic Menu"" > " & _ "<button id=""btn2"" imageMso=""RecurrenceEdit"" /> " & _ "<button id=""btn3"" imageMso=""CreateReportFromWizard"" /> " & _ "</menu>" content = xmlString & "</menu>" End Sub
This method is called by the dynamicMenu control from the getContent attribute when the context menu is displayed. Its purpose is to return XML markup that builds a menu. The markup is implemented as if it were hard-coded into the original XML markup.
Looking at the VBA code, notice that you pass the IRibbonControl object, as noted previously. In addition, you pass a content argument in to the method. This argument does not specify a type so defaults to a Variant type. This variable holds the XML that is returned to Microsoft Office when the method finishes. The XML string contains a menu control and must begin with the specific namespace. Every dynamic menu must include this line. The remainder of the code builds a string that contains the controls that make up the menu, which in this instance, include three buttons. And finally, notice that the constructed string is assigned to the content variable which passes it back to Office 2010 for display.
Close the Visual Basic Editor.
Highlight a section of text and then click the right mouse button to display the customized context menu.
As a point of reference, Figure 2 shows what the standard Text context menu resembles before it is customized.
Figure 2. The standard Text context menu
Figure 3 shows the customized Text context menu you created.
Figure 3. The custom Text context menu
Conclusion
Traditionally, developers have relied on customizing the context menu to provide highly contextual and mouse-efficient custom solutions. Customizing these through the Ribbon extensibility model simplifies this task compared to using command bars. You are encouraged to explore using the various combinations of controls to create targeted user interfaces in your Office 2010 solutions.
Additional Resources
To find more information about the subjects discussed in this article, see the following resources.
Customizing the 2007 Office Fluent Ribbon for Developers
Acknowledgment: Thanks to my editor, Linda Cannon, for her help in preparing this article for publication.