Here is a Way to Get the ID of a Built-in Outlook Command Bar Menu (Norm Estabrook)

Published 30 April 09 02:09 PM

Recently, a forum poster asked us how he could add a submenu item to a built-in menu item in Outlook.  Note that these are not controls that appear on the Ribbon of an Outlook item, but rather the menus that drop down from the top of the Outlook Explorer such as the View menu and the Tools menu.

So one way to do this (In fact the only way that I know of) is to use the example shown in the following MSDN topic - How to: Add Custom Menus and Menu Items to Outlook.

You can’t just use the example as is. You will need to add a line of code to get a handle to a built-in menu. The following example gets a handle to the Junk E-Mail menu that appears off of the Actions menu of the Outlook Explorer window.

Office.CommandBarPopup junkEmailMenu = (Office.CommandBarPopup)
    this.Application.ActiveExplorer().CommandBars.FindControl
    (Office.MsoControlType.msoControlPopup, 31353, missing, missing);

Note the ID number shown in the second parameter to the FindControl method. How on earth did I know that the Junk E-Mail menu is the 31353 menu?  The answer is … Not very easily. In fact to obtain that ID, I wrote a small Outlook add-in that iterates through all menus in Outlook and prints out their corresponding codes.  I figured that I would share this with you in case you ever have a similar scenario.

Two notes about the sample below: First - this is a C# example, so my apologies to VB’ers. Second - this example is meant to be used in a Visual Studio 2008 Outlook (2007 or 2003) add-in project.  These projects automatically include the appropriate using statements that enable you to use the prefix “Office” in place of “Microsoft.Office.Core” when referring to some objects etc.

Ok. Here is the code:

public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        Outlook.Application app = this.Application;
        //Create a new txt file to record controls' list

        System.IO.StreamWriter sw = System.IO.File.CreateText
            (@"C:\Outlook Menus.txt");

        //loop through Outlook ActiveExplorer CommandBars to get all CommandBars

        foreach (Office.CommandBarControl cb in app.ActiveExplorer().CommandBars.ActiveMenuBar.Controls)
        {
            PrintMenuItems(cb, sw);
        }

        sw.Close();

    }

    // Recursive method for printing menus and nested menus.
    // Either the menu is a commandbarpopup (contains submenus)
    // Or it is a commandbarbutton (contains no submenus)

    private void PrintMenuItems(object menuItem, System.IO.StreamWriter sw)
    {
        if (menuItem as Office.CommandBarButton == null)
        {
            // This is a menu bar popup control.
            sw.WriteLine((menuItem as Office.CommandBarPopup).Caption +
                "\t" + (menuItem as Office.CommandBarPopup).Id.ToString());

            if ((menuItem as Office.CommandBarPopup).accChildCount > 0)
            {
                for (int j = 1; j <= (menuItem as Office.CommandBarPopup).accChildCount; j++)
                {
                    PrintMenuItems((menuItem as Office.CommandBarPopup).get_accChild(j), sw);
                }
            }
        }
        else
        {
            // Must be a command
            sw.WriteLine("\t" + (menuItem as Office.CommandBarControl).Caption +
                "\t" + (menuItem as Office.CommandBarControl).Id.ToString());
        }

    }

Enjoy!

Norm E.

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Here is a Way to Get the ID of a Built-in Outlook Command Bar Menu (Norm Estabrook) | ASP NET Hosting said on April 30, 2009 5:34 PM:

PingBack from http://asp-net-hosting.simplynetdev.com/here-is-a-way-to-get-the-id-of-a-built-in-outlook-command-bar-menu-norm-estabrook/

# VBDOTNETMAN said on May 1, 2009 9:08 AM:

Norm,

Below is a VB.NET version of the above....

Imports Microsoft.Office.Interop.Outlook

Imports System.Collections

Imports System.Reflection

Public Class ThisAddIn

   Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup

       ' AddHandler Application.ItemContextMenuDisplay, AddressOf Application_ItemContextMenuDisplay

       Dim app As Outlook.Application = Me.Application

       'Create a new txt file to record controls' list

       Dim sw As System.IO.StreamWriter = System.IO.File.CreateText("C:\Outlook Menus.txt")

       'loop through Outlook ActiveExplorer CommandBars to get all CommandBars

       For Each cb As Office.CommandBarControl In app.ActiveExplorer().CommandBars.ActiveMenuBar.Controls

           PrintMenuItems(cb, sw)

       Next

       sw.Close()

   End Sub

' Recursive method for printing menus and nested menus.

   ' Either the menu is a commandbarpopup (contains submenus)

   ' Or it is a commandbarbutton (contains no submenus)

   Private Sub PrintMenuItems(ByVal menuItem As Object, ByVal sw As System.IO.StreamWriter)

       If TryCast(menuItem, Office.CommandBarButton) Is Nothing Then

           ' This is a menu bar popup control.

           sw.WriteLine((TryCast(menuItem, Office.CommandBarPopup).Caption & vbTab) + TryCast(menuItem, Office.CommandBarPopup).Id.ToString())

           If TryCast(menuItem, Office.CommandBarPopup).accChildCount > 0 Then

               For j As Integer = 1 To TryCast(menuItem, Office.CommandBarPopup).accChildCount

                   Dim x As Office.CommandBarPopup = TryCast(menuItem, Office.CommandBarPopup)

                   PrintMenuItems(TryCast(menuItem, Office.CommandBarPopup).accChild(j), sw)

               Next

           End If

       Else

           ' Must be a command

           sw.WriteLine((vbTab & TryCast(menuItem, Office.CommandBarControl).Caption & vbTab) + TryCast(menuItem, Office.CommandBarControl).Id.ToString())

       End If

   End Sub

# Dwight said on July 10, 2009 5:08 PM:

Hi,

Thanks in advance for the solution.

I'm coding in C# VS2008, Framework 2.0, on XP platform, using Outlook 2003 sp3.

I've created a COMAdd-in, with the task of hiding at best or disabling the send button which to my understanding resides on the Standard CommandBar.

I've run two different third party scripts, and my code against the Outlook Object model. They all have listed every Commandbar object, and their associated Controls . All except the send button ('&Send') or control.ID = 2617.

I can see the send button on the Inspector window and it works fine, but I can't reference it.

My question are the following:

1 - is this by design (introduced with SP3)?

2 - Assuming it's not, is there a configuration setting I need to check?

3 - Assuming it's not the above two, is this a bug?

Any responses again would greatly be appreciated.

Thanks

# Norm Estabrook said on July 10, 2009 5:37 PM:

Hello,

Try handling the new inspector event. In the event handler for the new inspector, reference the command bar collection of the Inspector window instead of the active explorer.  I tried this for an Outlook 2007 add-in (as that is what I am running on my dev box) and I was able to get codes for the Send button.  Here is an example (Using a 2007 add-in - you might have to modify it slightly for Outlook 2003)

       private Outlook.Inspectors inspectors;

       private void ThisAddIn_Startup(object sender, System.EventArgs e)

       {

           inspectors = this.Application.Inspectors;

           inspectors.NewInspector +=

               new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler

                   (Inspectors_NewInspector);

       }

       void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)

       {

           System.IO.StreamWriter sw = System.IO.File.CreateText(@"C:\Outlook Menus.txt");

           Outlook.MailItem tmpMailItem = (Outlook.MailItem)Inspector.CurrentItem;

           if (tmpMailItem != null)

           {

               //loop through Outlook Inspector CommandBars to get all CommandBars

               foreach (Office.CommandBarControl cb in Inspector.CommandBars.ActiveMenuBar.Controls)

               {

                   PrintMenuItems(cb, sw);

               }

               sw.Close();

           }

       }

       private void PrintMenuItems(object menuItem, System.IO.StreamWriter sw)

       {

           if (menuItem as Office.CommandBarButton == null)

           {

               // This is a menu bar popup control.

               sw.WriteLine((menuItem as Office.CommandBarPopup).Caption +

                   "\t" + (menuItem as Office.CommandBarPopup).Id.ToString());

               if ((menuItem as Office.CommandBarPopup).accChildCount > 0)

               {

                   for (int j = 1; j <= (menuItem as Office.CommandBarPopup).accChildCount; j++)

                   {

                       PrintMenuItems((menuItem as Office.CommandBarPopup).get_accChild(j), sw);

                   }

               }

           }

           else

           {

               // Must be a command

               sw.WriteLine("\t" + (menuItem as Office.CommandBarControl).Caption +

                   "\t" + (menuItem as Office.CommandBarControl).Id.ToString());

           }

# VSTO Team said on July 10, 2009 5:39 PM:

Dwight -

Sue Mosher answered a similar question on her web page here:

http://www.outlookcode.com/threads.aspx?forumid=3&messageid=16801

-Christin Boyd, Program Manager

# Dwight said on July 15, 2009 11:38 AM:

Thanks guys for the feed back.

Norm, yes I did something similar to your solution, let me explain.

I’ve iterated through a number of command bars for the inspector object (via new Inspector event). I’ve managed to tag every id (even the send/receive button) for just about every object on any given command bar (standard being the obvious choice) in respect to the Inspector object, and wrote it out to a text file.  

However for the life of me I could find the id for the send button!  So to double check my suspicions (and to make sure my sanity was still intact) I’ve decided to ask the pro’s just in case I was missing something in the translation.

Christin, I have read Sue’s response, and thanks for the link….

I appreciate the time and effort you guys went through to assist me…

Dwight

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

About VSTO Team

This login represents the Visual Studio Tools for Office team. Many members of the team us this account for publishing technical blog posts.

This Blog

Syndication

Page view tracker