OL: How to Use CommandBars in Outlook Solutions
Outlook CommandBar ArchitectureOther Office applications support one set of CommandBars, but Outlook supports two: one set at the main application window, and a second set in each individual item.
From a developer's point of view, the main window in Outlook (theapplication window) is referred to as an "explorer."
IMPORTANT: These windows can also be considered folder-level windows because you can right-click any folder, and then click Open in New Window to open different windows to work with different folders.
In addition to these explorer windows, each Outlook item has a form window that is referred to as an "inspector." These inspector windows also have a set of CommandBars because items have menus and toolbars.
Use the different objects as follows:
- Use the Explorer objects (ActiveExplorer/GetExplorer) to refer to the main application window in Outlook.
- Use the Inspector objects (ActiveInspector/GetInspector) to refer to an Outlook item's window.
| To refer to the | To refer to a folder Window type | "active" window | or item's window --------------------------------------------------------------------------------- Application | Use the ActiveExplorer method. | Use the GetExplorer method. | | Item or Form | Use the ActiveInspector method. | Use the GetInspector method.
Considerations When You Use Microsoft Word as the E-Mail EditorWhen you are designing an Outlook CommandBar solution for mail items, it is important that you understand that different CommandBars are used when Microsoft Word is set as the e-mail editor. Some key points that you must consider when you use Word as the e-mail editor are:
- CommandBars are part of Word, not Outlook.
- Different CommandBars are available based on the message editor and format.
- Custom buttons may disappear when you change message editor or format.
- The special Envelope CommandBar is not designed to be customized.
- There is no Inspector object for the HTML and Plain Text formats with Office 2000 if Word is set as the e-mail editor.
Word also provides two different sets of CommandBar technologies based on the format of the e-mail message. In Office 2002, all of the message formats use the specialized Envelope CommandBar by default, but in Office 2000, only HTML and Plain Text messages use the Envelope CommandBar. The Envelope CommandBar contains features that are specific to e-mail, such as the Send button and message fields (To, Cc, and Subject). The Envelope CommandBar is not displayed in the Word Toolbars list and is not designed to be customized. Therefore, you must make any modifications to other CommandBars. Office 2000 handles Rich Text Format messages differently and uses the Outlook Send Mail and Outlook Read Mail CommandBars for composing and reading messages. Although Office 2002 message formats do not use the Outlook Send Mail and Outlook Read Mail CommandBars by default, you can design a custom Outlook form that uses these CommandBars. To configure the form so that it uses Word as the e-mail editor, in form design mode, click the Properties tab of the form, and then click to select Always use Microsoft Word as the e-mail editor.
A History of Outlook Support for Customizable Menus and ToolbarsCommandBars were originally designed for document-centric applications, such as Word and Microsoft Excel, which support a single set of application-level CommandBars. The other applications fully support all of the features of the CommandBars design, and in Microsoft Office 97 and later, the other applications fully support many aspects of customizing CommandBars. However, Outlook has continued to support CommandBars is various ways:
- In Microsoft Outlook 97, you cannot customize toolbars and menus by using the Outlook user interface. Outlook 97 is not designed to store changes to CommandBars. Although the CommandBars object model is exposed in the Outlook object model, you cannot use the CommandBars object model to modify the menus or toolbars because they are in a "read-only" state. However, you can use the Execute method to programmatically run a built-in Outlook command. The only way to create additional toolbar buttons or menu commands in Outlook 97 is to create a Microsoft Exchange Client Extension in C or C++.
- In Microsoft Outlook 98, Microsoft recommends that you do not programmatically make changes to the CommandBars object model. Toolbars and menus are customizable in the Outlook user interface. Customizations are stored in a file called Outcmd.dat. However, although the CommandBars object model is exposed in the Outlook object model, and you can programmatically add new toolbar buttons and menu commands, this feature was not designed or tested to actually work. As a result, you may experience issues if you use the CommandBars object model in Outlook 98. Outlook 98 does not support Microsoft Visual Basic for Applications (VBA), or application-level code. Therefore, if you programmatically add a custom command to an application-level window, or explorer, there is no way to attach custom code to the button. If you programmatically add a custom command to an item-level window, or inspector, you can have the button run custom Microsoft Visual Basic Scripting Edition (VBScript) script in the form, but issues will occur that cause the button to be displayed on other types of items, and there may be differences between opening new items and existing items.
- Outlook 2000 is the first version of Outlook that is designed to support programmatically customizable toolbars and menus. This coincides with the addition of support for VBA and Component Object Model (COM) add-ins.
CommandBars and the Outlook Object ModelIn the object models of other Office applications, the CommandBars collection is located off the Application object because those applications support only one set of application-level CommandBars. However, the Outlook object model is designed to support the two sets of CommandBars that Outlook supports (Inspector and Explorer).
In the Outlook object model, the CommandBars collection is located off Explorer and Inspector objects, not the Outlook Application object. Many code examples are available that illustrate how to programmatically make changes to CommandBars; however, most of these examples are designed for other Office applications. To use these examples in Outlook, you must modify the code appropriately to reflect the difference in the Outlook object model.
Custom Form SolutionsIn a custom form solution that uses VBScript, you typically access the form-level CommandBars by using code that is similar to:
Set objCBs = Item.GetInspector.CommandBars
A VBScript Sample to Run an Outlook CommandYou can use the following sample code with a CommandButton control on a contact form to easily create a new letter for a Contact:
Sub CommandButton1_Click() Set MyCB = Item.GetInspector.CommandBars.Item("Menu Bar") Set MyMenu = MyCB.Controls("Actions") Set MyMenuItem = MyMenu.Controls("New Letter to Contact") MyMenuItem.Execute()End Sub
A VBScript Sample That Uses the "FindControl" MethodIf you know the internal value that Outlook has assigned for each command, you can use the FindControl method to reference any Outlook commands (or controls, in relation to the CommandBars object model). If you use the internal ID, you can use more concise syntax when running CommandBar commands, and you can access commands that may not be on the menu or toolbar that is displayed.
For example, consider a custom Outlook form that uses a custom command button to print the form. Assuming that the command button is named cmdPrint, either of the following two VBScript code examples displays the File Print dialog box:
Sub cmdPrint_Click() Item.GetInspector.CommandBars.FindControl(,4).ExecuteEnd SubSub cmdPrint_Click() Item.GetInspector.CommandBars.Item("Menu Bar").Controls("File") _ .Controls("Print...").ExecuteEnd Sub
Application-Level SolutionsIn an application-level solution, such as Outlook VBA or a COM add-in, the typical method to access the application-level CommandBars is to use code that is similar to:
Set objCBs = Application.ActiveExplorer.CommandBars
Visual Basic for ApplicationsOutlook VBA is designed to be a personal development tool; these types of solutions are not designed to be deployed. Therefore, typically, you would not programmatically customize CommandBars from Outlook VBA. Instead, manually create the custom CommandBar button:
- On the Tools menu, click Customize.
- Click the Commands tab, and then click Macros in the list of categories.
- Drag a macro to the menu or toolbar.
- To modify the appearance of the toolbar or menu command, in the Customize window, click Modify Selection, and then make any modifications to the custom toolbar or menu command.
- Click Close.
A VBA Sample to Add a CommandBar ControlTo add a CommandBar control:
- Create a sample custom Outlook Post form, and then publish it to your Inbox. Name it TestForm.
- On the Tools menu, point to Macro, and then click Visual Basic Editor.
- Under Project - Project1, double-click Project1, double-click Microsoft Outlook Objects, and then double-click ThisOutlookSession.
- In the code window, enter the following code:
Dim WithEvents myControl As CommandBarButtonPrivate Sub Application_Startup() Dim oExp As Outlook.Explorer Dim oBar As Office.CommandBar Set oExp = Outlook.ActiveExplorer Set oBar = oExp.CommandBars.Item("Standard") ' See if button already exists based on Tag value Set myControl = oBar.FindControl(, , "OpenForm") ' If not found then create button If myControl Is Nothing Then Set myControl = oBar.Controls.Add(, , , 2, True) With myControl .Caption = "Open Form" .FaceId = 59 .Style = msoButtonIconAndCaption .Tag = "OpenForm" .Visible = True End With End IfEnd SubPrivate Sub myControl_Click(ByVal Ctrl As _ Office.CommandBarButton, CancelDefault As Boolean) Dim myFolder As MAPIFolder Set myFolder = Session.GetDefaultFolder(olFolderInbox) Set MyItem = myFolder.Items.Add("IPM.Post.TestForm") MyItem.Display Set MyItem = Nothing Set myFolder = NothingEnd Sub
- Close the Visual Basic Editor.
- Close Outlook. When you are prompted to save changes to the VBA project, click Yes.
- Start Outlook.
A COM Add-In Sample to Add a CommandBar ControlThe supported way to distribute application-level code to Outlook users is by creating a COM add-in. The following COM add-in code sample demonstrates how to add a new button to the first position on the Standard Outlook CommandBar (you can also set the OnAction property of the button to load the COM add-in if it is not already loaded):
Dim OL As Outlook.ApplicationDim WithEvents objButton As Office.CommandBarButtonPrivate Sub AddinInstance_OnConnection(ByVal Application As Object, _ ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, _ ByVal AddInInst As Object, custom() As Variant) Dim objBar As Office.CommandBar Set OL = Application Set objBar = OL.ActiveExplorer.CommandBars.Item("Standard") Set objButton = objBar.Controls.Add(, , , 1, True) With objButton .FaceId = 59 .Caption = "My Button" .Style = msoButtonIconAndCaption ' The OnAction property is optional but recommended. ' It should be set to the ProgID of the add-in, such that if ' the add-in is not loaded when a user presses the button, ' Outlook loads the add-in automatically and then raises ' the Click event for the add-in to handle. .OnAction = "!<" & AddInInst.ProgId & ">" End WithEnd SubPrivate Sub objButton_Click(ByVal Ctrl As Office.CommandBarButton, _ CancelDefault As Boolean) MsgBox "Hello World"End Sub
Using a Microsoft Excel Utility to Generate a List of Outlook CommandBar IDsYou can use the following Microsoft Excel VBA sample code to generate a spreadsheet that contains a list of Outlook commands and their corresponding CommandBar control IDs. The code adds an Excel AutoFilter to the spreadsheet so that you can easily find the ID that you are looking for.
To set up this utility:
- Start Excel. Make sure that you are in a new Excel workbook.
- On the Tools menu, point to Macro, and then click Visual Basic Editor.
- In the editor's Project Explorer window, double-click ThisWorkbook to open a code window.
- In the code window, enter the following code:
Option ExplicitDim oOutApp As Outlook.ApplicationDim I As LongDim iRowCount As LongDim oItm As Object ' so it'll handle varying item typesDim oSheet As Excel.WorksheetDim oNS As Outlook.NameSpaceDim oFld As Outlook.MAPIFolderSub GetOutlookCommandBarIDs()If MsgBox("This will clear the current worksheet, OK to continue?", vbOKCancel) = 1 Then Cells.Select Selection.ClearContents iRowCount = 0 Set oSheet = ActiveSheet Set oOutApp = New Outlook.Application Set oNS = oOutApp.Session Set oItm = oOutApp.CreateItem(olMailItem) GetInspectorIDs oItm, "Mail Message" Set oItm = oOutApp.CreateItem(olPostItem) GetInspectorIDs oItm, "Post" Set oItm = oOutApp.CreateItem(olContactItem) GetInspectorIDs oItm, "Contact" Set oItm = oOutApp.CreateItem(olDistributionListItem) GetInspectorIDs oItm, "Distribution List" Set oItm = oOutApp.CreateItem(olAppointmentItem) GetInspectorIDs oItm, "Appointment" Set oItm = oOutApp.CreateItem(olTaskItem) GetInspectorIDs oItm, "Task" Set oItm = oOutApp.CreateItem(olJournalItem) GetInspectorIDs oItm, "Journal Entry" Set oFld = oNS.GetDefaultFolder(olFolderInbox) GetExplorerIDs oFld, "Mail Folder" Set oFld = oNS.GetDefaultFolder(olFolderContacts) GetExplorerIDs oFld, "Contact Folder" Set oFld = oNS.GetDefaultFolder(olFolderCalendar) GetExplorerIDs oFld, "Calendar Folder" Set oFld = oNS.GetDefaultFolder(olFolderTasks) GetExplorerIDs oFld, "Task Folder" Set oFld = oNS.GetDefaultFolder(olFolderJournal) GetExplorerIDs oFld, "Journal Folder" Set oFld = oNS.GetDefaultFolder(olFolderNotes) GetExplorerIDs oFld, "Notes Folder" Selection.AutoFilter Cells.Select Cells.EntireColumn.AutoFit Range("A1").Select MsgBox "The spreadsheet is complete." End IfEnd SubSub GetInspectorIDs(oItm, sType As String) Dim oCBs As Office.CommandBars Dim oCtl As Office.CommandBarControl Set oCBs = oItm.GetInspector.CommandBars For I = 1 To 35000 Set oCtl = oCBs.FindControl(, I) If Not (oCtl Is Nothing) Then iRowCount = iRowCount + 1 oSheet.Cells(iRowCount, 1) = "Inspector" oSheet.Cells(iRowCount, 2) = sType oSheet.Cells(iRowCount, 3) = oCtl.Parent.Name oSheet.Cells(iRowCount, 4) = oCtl.Caption oSheet.Cells(iRowCount, 5) = CStr(I) End If NextEnd SubSub GetExplorerIDs(oFld As Outlook.MAPIFolder, sType As String) Dim oCBs As Office.CommandBars Dim sFilter As String Dim oCtl As Office.CommandBarControl Set oCBs = oFld.GetExplorer.CommandBars For I = 1 To 35000 Set oCtl = oCBs.FindControl(, I) If Not (oCtl Is Nothing) Then iRowCount = iRowCount + 1 oSheet.Cells(iRowCount, 1) = "Explorer" oSheet.Cells(iRowCount, 2) = sType oSheet.Cells(iRowCount, 3) = oCtl.Parent.Name oSheet.Cells(iRowCount, 4) = oCtl.Caption oSheet.Cells(iRowCount, 5) = CStr(I) End If NextEnd Sub
- On the Tools menu, click References. In the list of available object libraries, click Microsoft Outlook 10.0 Object Library, and then click OK.
- Close the Visual Basic Editor.
- Save the Excel workbook so that you have it for future use.
- Make sure that the Excel security settings allow the macro to run. On the Tools menu, click Security, and then make sure that your settings are set to Medium or Low, at least temporarily. If you change the settings from High, you must restart Excel.
- Open the workbook that you created when you set up the Excel utility.
- On the Tools menu, point to Macro, and then click Macros. Click the GetOutlookCommandBarIDs macro, and then click Run.
- Wait while the spreadsheet is generated. This will take at least a couple of minutes. After the macro finishes runnning, you receive a message that states, "The spreadsheet is complete."
- After the spreadsheet is generated, save the workbook so that you do not have to run the macro again.
Article ID: 201095 - Last Review: 12/05/2015 10:31:05 - Revision: 2.5
- kbnosurvey kbarchive kbinfo KB201095