Adding and Removing Custom Menus and Toolbars

Sometimes your solution requires a set of custom menu commands. Adding a set of custom commands to an existing menu may expand the menu so much that it contains too many items. Introducing a new menu may be a good alternative. The Microsoft Office 9.0 Object Library provides an object model that allows you to manipulate any of the menus or toolbars provided by an Office application and to add custom menus and toolbars.

Creating your own toolbars by using Microsoft Visual Basic allows you to add elements to the user interface that, in turn, allow your customers to access the functionality in your programs. For example, if you develop a wizard that guides a user through the process of creating a specific type of Word document, you'll want to add a toolbar button or menu item that, when clicked, displays the custom wizard.

NOTE
The naming convention used in this chapter and throughout the rest of this book for command bar variables and command bar control variables is the following:

Command bar = cmbX
Command bar control = ctlY

X and Y represent names that indicate what each control variable represents.

The Quick Guide on the next page provides a quick reference to creating the most common elements of a command bar set. These include adding a new menu, a submenu, a shortcut menu, a menu item, and a toolbar. The Quick Guide also describes how to write code to remove a toolbar. The section "Creating a Toolbar, Step by Step" later in this chapter explains the details of adding a new toolbar.

Iterate Through the Command Bars Collection

The following procedure reveals two ways of iterating through a command bar collection. The first uses a For Each…Next loop, and the second uses a regular For…Next loop. In the Visual Basic Editor in any Office application, click Module on the Insert menu, add the following code, and run the procedure. The procedure provides two different For…Next loops to iterate through the CommandBars collection object and print the name of each command bar to the Immediate window. You can use this procedure to determine if a specific command bar exists in the collection.

Sub IterateCommandBarCollection()
    ' For Each...Next loop
    Dim cmbItem As CommandBar
    For Each cmbItem In Application.CommandBars
        Debug.Print cmbItem.Name
    Next cmbItem
' OR
    'For...Next loop
    Dim i As Integer
    For i = 1 To Application.CommandBars.Count
        Debug.Print Application.CommandBars(i).Name
    Next i
End Sub

Add a Menu

To create a custom menu on the menu bar alongside the built-in menus in Word, Excel, PowerPoint, and other programs, you need to add a pop-up command bar control on the menu bar. The following procedure adds a new menu in between the File and Edit menus. But you can add menus to any toolbar, not just the main menu bar. If you change the string "Menu Bar" in the CommandBars property to "Standard," the new menu appears on the Standard toolbar with a drop-down arrow at the side of the caption. The Draw menu on the Drawing toolbar in Word, Excel, or PowerPoint is an example of a menu located on a toolbar.

NOTE
When running the following code in Excel, change the string "Menu Bar" to "Worksheet Menu Bar" in the CommandBars property:

Set cmbNewMenu = Application _
    .CommandBars("Worksheet Menu Bar")

In Outlook, you access the CommandBars collection through an Explorer or Inspector object:

Set cmbNewMenu = Application _
    .ActiveExplorer.CommandBars("Menu Bar")

An Explorer object is the window where you see folders such as the Inbox, Sent Items, and Deleted Items. An Inspector object is a window where you see items such as e-mail messages, meeting requests, and contact information.

In the Visual Basic Editor in any Office application, click Module on the Insert menu, add the following code, and run the procedure. To run the procedure in Excel or Outlook, make sure you change the code as indicated in the previous note. The procedure produces a custom menu with the caption "NewMenu" and two menu items.

Sub InsertMenu()
    Dim cmbNewMenu As CommandBar
    Dim ctlPopup As CommandBarPopup

    Set cmbNewMenu = Application.CommandBars("Menu Bar")
    With cmbNewMenu.Controls
        Set ctlPopup = .Add(Type:=msoControlPopup, _
            Before:=2)
        With ctlPopup
            .Caption = "&NewMenu"
            With .Controls.Add
                .Caption = "&Item 1"
            End With
            With .Controls.Add
                .Caption =  "&Item 2"
            End With
        End With
    End With
End Sub

Your new menu should appear as follows:

The Menu Bar, which is itself represented by a CommandBar object, contains a Controls collection object that represents all of the pop-up menus, including File, Edit, View, Insert, and so on. The Set ctlPopup statement near the bottom of the previous page adds a new pop-up control to the Menu Bar command.

The Before argument of the Add method of the Controls collection object indicates the index position within the Controls collection where the menu is to be placed. In this case, a value of "2" places the new menu to the right of the File menu. To change the position of the new menu, change the integer value set to the Before argument. The Before argument is optional, so if the Before argument isn't specified, the new menu is added to the end of the menu (after the Help menu). In this case, the Set ctlPopup statement on the previous page would appear as:

Set ctlPopup = .Add(Type:=msoControlPopup)

Add a Submenu

Adding a submenu is the same as creating a menu on the main menu bar. Examples of a submenu are the Macro submenu on the Tools menu and the Toolbars submenu on the View menu in all Office applications. To create a submenu, just change the string "Menu Bar" in the CommandBars property to any menu that exists on the menu bar or some other command bar. For example, if you change "Menu Bar" to "Tools," you create a submenu named "New Menu" containing the submenu at the second position of the Tools menu.

Sub InsertSubmenu()
    Dim cmbMenu As CommandBar
    Dim ctlPopup As CommandBarPopup
    
    Set cmbMenu = Application.CommandBars("Tools")
    Set ctlPopup = cmbMenu.Controls _
        .Add(Type:=msoControlPopup)
    With ctlPopup
        .Caption = "&Submenu"
        With .Controls.Add
            .Caption = "Su&bmenuItem 1"
        End With
        With .Controls.Add
            .Caption = "S&ubmenuItem 2"
        End With
    End With
End Sub

Your new submenu should appear as follows:

You should note that you can't create a "tear-off" submenu. An example of a tear-off menu is the AutoText submenu on the Insert menu in Word. It contains a small title bar that you can click and drag to create a floating or docked toolbar.

Click to view at full size.

Add a Shortcut Menu

The following procedure inserts a new shortcut menu named NewShortcut. Like any menu, you can add any number of menu items that are of the command bar control type msoControlButton. In the Visual Basic Editor in any Office application, click Module on the Insert menu, add the following code, and run the procedure.

Sub InsertShortcutMenu()
    Dim cmbNewShortcut As CommandBar

    Set cmbNewShortcut = Application.CommandBars.Add( _
         Name:="NewShortcut", Position:=msoBarPopup)
    With cmbNewShortcut.Controls
        With .Add
            .Caption = "&ShortcutItem 1"
        End With
        With .Add
            .Caption = "&ShortcutItem 2"
        End With
    End With
End Sub

You use the ShowPopup method to display shortcut menus. In the same code module where you typed the InsertShortcutMenu procedure, add the following code and run the DisplayPopup procedure. The shortcut menu NewShortcut, containing two items, is displayed wherever the mouse pointer is located on screen. If you switch back to the Office application, press ALT+F8 to display the Macros dialog box, and click DisplayPopup, the shortcut menu appears on top of the Office application window.

Sub DisplayPopup()
    Application.CommandBars("NewShortcut").ShowPopup
End Sub

You can display a shortcut menu in response to a right-click event in Word, Excel, or PowerPoint. Word, Excel, and PowerPoint all support assigning an event procedure to the user action of right-clicking in any document. Chapter 10 describes how to set up the right-click event in Word, Excel, and PowerPoint.

To quickly delete the shortcut menu created by the procedure InsertShortcutMenu, type the following line of code in the Immediate window and press ENTER. Because the following line of code executes a method, the question mark (?) is not required before the beginning of the line.

Application.CommandBars("NewShortcut").Delete

Add a Menu Item

Although adding a menu item is discussed at the beginning of this chapter, the procedure below is given for the sake of completeness to explain how to insert a new menu item at the top of the Tools menu. You'll set the menu item's style to display both the icon and caption—although not all menu items have or require an icon. The FaceId property sets the icon, and the value of 2950 isn't used by any built-in controls in Office, but reserved for custom use. In most cases, a FaceId value won't be set and an icon image won't be added to the control. The section later in this chapter entitled "Add an Image to a Control" describes more details and issues about adding images to command bar controls.

Sub InsertMenuItem()
    With Application.CommandBars("Tools") _
        .Controls.Add(Type:=msoControlButton, _
           Before:=1)
        .FaceId = 2950
        .Caption = "&MenuItem"
        .Tag = "MyCustomTag"
        .Style = msoButtonIconAndCaption
    End With
End Sub

Add a Toolbar

To create a custom toolbar like the Standard or Formatting toolbar in Word, Excel, PowerPoint, or Outlook, you need to add a command bar to the CommandBars collection. The following procedure adds a new custom command bar and positions (or docks) the command bar below the Standard and Formatting toolbars. You add only one control, as specified in the With…End With block. You can add any number of controls to the new command bar by adding more Set statements that add controls to the command bar, and adding a With…End With block that sets the properties of the new controls.

Sub InsertToolBar()
    Dim cmbNewBar As CommandBar
    Dim ctlBtn As CommandBarButton

    Set cmbNewBar = CommandBars.Add(Name:="NewBar")
    With cmbNewBar
        Set ctlBtn = .Controls.Add
        With ctlBtn
            .Style = msoButtonIconAndCaption
            .BeginGroup = True
            .Caption = "&Button"
            .TooltipText = "ToolTip"
            .FaceId = 59
        End With
        .Protection = msoBarNoCustomize
        .Position = msoBarTop
        .Visible = True
    End With
End Sub

Your new toolbar should appear as follows:

Remove a Command Bar

The easiest way to remove your toolbar with Visual Basic code is to add this line of code to a procedure: Application.CommandBars("NewBar").Delete, and then execute the procedure. However, if the toolbar doesn't exist, an error results when the line is executed. In order to ensure that the toolbar is deleted if it exists and that no error arises if it does not, you can write code in one of two ways. (You can also include both methods.)

Remove a Command Bar by Trapping Errors

The following procedure traps the error that's generated when a line of code attempts to delete a command bar that doesn't exist. The first line in the procedure indicates that if an error occurs, execution of the procedure should skip to the line starting with the word "Error_Handler." (You can change the text "Error_Handler" to anything you want, as long as the colon (:) appears at the end of the line. If you do change the text, make sure to do so in both places in the procedure.) If no error occurs when the Delete method is executed, the procedure is exited. If the Exit Sub line didn't exist, execution of the procedure's lines of code would continue into the Error_Handler, even if no error occurred.

Sub DeleteCommandBarByErrorTrapping()
    On Error GoTo Error_Handler
    Application.CommandBars("NewBar").Delete
    Exit Sub

Error_Handler:
    ' command bar does not exist
    ' Debug.Print Err.Description
End Sub

Remove a Command Bar by Iteration

To delete a command bar if it exists and ensure that no error arises if it doesn't exist, you can use a For Each…Next loop to iterate through the command bars in the CommandBars collection. In the procedure below, the If…Then statement within the For Each…Next loop evaluates the name of each existing command bar. If the name of any command bar in the collection matches the name of your new command bar, the procedure deletes the first command bar and exits the loop.

Because the name of a command bar is unique within the CommandBars collection, only one command bar with the name you want to delete will exist. Exiting the loop after the command bar is deleted improves the performance of your code, because the loop doesn't need to continue looping through the collection. The only exception is in Word, where two command bars with the same name can exist; thus, you should remove the Exit For line from the procedure.

Sub DeleteCommandBarByIteration()
    Dim cmbItem As CommandBar
    For Each cmbItem In Application.CommandBars
        If cmbItem.Name = "NewBar" Then
            cmbItem.Delete
            Exit For
        End If
    Next cmbItem
End Sub

Creating a Toolbar, Step by Step

Each Office application provides a collection of toolbars, and each toolbar helps you perform a set of common functions. For example, the Formatting toolbar consists of a set of buttons and drop-down lists that help you format text in your document, worksheet, or slide. You'll see the list of toolbars available in any particular Office application in the Toolbars tab of the Customize dialog box.

To access the Customize dialog box, on the Tools menu in any Office application, click Customize; or, on the View menu in Word, Excel, PowerPoint, or Access, point to Toolbars and then click Customize on the submenu. You can also right-click any toolbar and then click Customize on the shortcut menu. The Toolbars list displays all available toolbars, and the check box beside each item indicates whether or not that toolbar is visible.

Customize a Toolbar

  1. Start Word, Excel, or PowerPoint, open the Visual Basic Editor, and insert a new, standard code module.
  2. In the code module, type Sub InsertToolbarStepByStep and press ENTER.
  3. Type the following declaration lines in the procedure:
  4. Dim cmbNewBar As CommandBar
    Dim ctlBtn As CommandBarButton
    

    You're declaring the object variable cmbNewBar as the object type CommandBar. (Every toolbar and menu bar available to you in an Office application is considered a CommandBar object. Depending on what items you place on the command bar, it may appear as a menu bar, a toolbar, or a hybrid.) The second declaration is for a button control you're going to add to the newly created command bar.

  5. Add a command bar by typing the following line after the declaration of cmbNewBar and ctlBtn:
  6. Set cmbNewBar = Application.CommandBars.Add
    

    Each Application object in any Office application except Outlook provides access to the CommandBars collection object. The CommandBars collection object allows you to add a command bar to, or access an individual command bar from, the collection. In this case, the Add method of the CommandBars collection object returns a CommandBar object, which you assign to the object variable cmbNewBar.

  7. Below the Set statement in which you added a new CommandBar object to the collection, add the following line to name the newly created command bar:
  8. cmbNewBar.Name = "My CommandBar"
    

    Each newly created CommandBar object is given a default name. Before you assign a name to a new command bar, the name appears with the syntax "Custom number," where number represents the next available integer. (The name of a floating command bar is the name that appears on its title bar; a floating command bar isn't docked to any side of an application window.) The name of a command bar also appears in the Toolbars list in the Toolbars tab of the Customize dialog box.

  9. To add a button to your custom command bar, add the following With…End block below the name assignment line:
  10. With cmbNewBar 
        Set ctlBtn = .Controls.Add(msoControlButton)
    End With
    

    Each CommandBar object contains a Controls collection object that represents all of the buttons, drop-down lists, pop-up menus, and other controls available on the command bar. When you create a command bar, however, no controls yet exist in the Controls collection: the Set statement above adds a button control. Note that the Add method of the Controls collection object accepts up to five parameters, with the first one representing the type of control to add. You can specify the types of parameter to be msoControlButton, msoControlEdit, msoControlDropdown, msoControlComboBox, or msoControlPopup.

  11. Set the properties of the newly created button by adding the following With…End block just after the Set statement that adds a new button control to the Controls collection object:
  12. With ctlBtn
        .Style = msoButtonIconAndCaption
        .BeginGroup = True
        .Caption = "&Button"
        .FaceId = 59
        .TooltipText = "ToolTip"
    End With
    

    You can set a number of properties for a button on a command bar, but you have already set five of the main ones. The first is the button style, which allows you to represent a button as a combination of an icon and a caption (to the right of the icon), or an icon or a caption alone. To change the style of either of the latter choices, assign to the Style property the value msoButtonIcon or msoButtonCaption, respectively.

    Because you've specified both an icon and a caption in the above procedure, both the Caption property and the FaceId property are set. More than 1,000 face Ids are built into Office. Most of them are the buttons on the toolbars that you see in the application window (such as New, Save, or Print). You use the TooltipText property to set the text of the ToolTip that appears when the mouse is over the button on the command bar.

  13. Add the following lines to the procedure, just after the End With line of the With…End block added in the previous step:
  14. .Protection = msoBarNoCustomize
    .Position = msoBarTop
    .Visible = True
    

    The Protection property is set to the constant msoBarNoCustomize, indicating that the command bar is protected from user customization. The Protection property can be set to be one or more of the MsoBarProtection constants. When the constant msoBarNoCustomize is assigned to the command bar, the user can neither add nor remove a command bar control to or from the command bar.

    You can explicitly set the position of a command bar by using the Position property. You can set the Position property to one of the five values in the enumeration MsoBarPosition. Setting the property to msoBarTop docks the command bar at the top of the document window, while msoBarLeft, msoBarRight, and msoBarBottom dock the command bar at the left, right, and bottom, respectively. The Position property is set to the enumeration value msoBarFloating by default.

    When you add a new command bar, you can also set its position. Note that the Add method of the CommandBars collection contains the optional Position parameter. However, if you don't specify the Position parameter in the Add method or explicitly set the Position property, a newly added command bar floats. Also note you can't use the enumeration value msoBarPopup to set the Position property. You can use it only when you add a command bar first. (If you specify the Position parameter in the Add method of the CommandBars collection as msoBarPopup, the command bar is added as a context menu.)

    When you add a command bar, it's not visible by default; you have to explicitly set the command bar to Visible. The last line in the procedure above does so. The complete procedure for adding a command bar is as follows:

    Sub InsertToolBarStepByStep()
        Dim cmbNewBar As CommandBar
        Dim ctlBtn As CommandBarButton
    
        Set cmbNewBar = Application.CommandBars.Add
        cmbNewBar.Name = "My CommandBar"
        With cmbNewBar
            Set ctlBtn = .Controls.Add(msoControlButton)
            With ctlBtn
                .Style = msoButtonIconAndCaption
                .BeginGroup = True
                .Caption = "&Button"
                .TooltipText = "ToolTip"
                .FaceId = 59
            End With
            .Protection = msoBarNoCustomize
            .Position = msoBarTop
            .Visible = True
        End With
    End Sub
    

  15. Place the cursor in the procedure and press F5.
  16. The final toolbar should look like the following graphic, containing just one button displaying an icon and a caption. When you move the cursor over the button, you see the ToolTip.