trouble adding buttons to popup menu in outlook context menu

Add-in Express™ Support Service
That's what is more important than anything else

trouble adding buttons to popup menu in outlook context menu
 
Ryan Taylor




Posts: 46
Joined: 2008-04-08
Hello,

I am currently having trouble adding items to the Outlook 2003 Context menu with Add-in Express and I was hoping someone could help me.

I have seen the examples of how to add a button directly to the context menu and that works perfectly when using the same code in the sample. What I would like to do, however, is add a Menu to the context menu and in that new menu, add 3 buttons. I was able to implement this and everything shows up correctly, however, right clicking, on an email 2 or 3 times causes Outlook to freeze until I kill the process. If I only add the menu (no buttons on the new menu), outlook doesn't freeze.

If anyone could give me a hand I would greatly appreciate it!

Here is the code I am currently using, it is broken up into a few methods and most of the code was taken from the samples. HandleContextMenu is called from the adxOutlookEvents_CommandBarsUpdate event:

==============================================================
public override void HandleContextMenu(object sender, object commandBar, object target)
{
Selection sel = null;
NameSpace nameSpace = null;
Explorer activeExplorer = null;
MAPIFolder currentFolder = null;

try
{
nameSpace = _outlookApp.GetNamespace("MAPI");
activeExplorer = _outlookApp.ActiveExplorer();
try
{
currentFolder = activeExplorer.CurrentFolder;
try
{
sel = activeExplorer.Selection;
}
catch { }
Office.CommandBar contextBar = null;
if (!AreAllSelectedItemsMail(sel))
return;
_module.CommandBarsObj = activeExplorer.CommandBars;
try
{
contextBar = _module.FindCommandBarObj("Context Menu") as Office.CommandBar;
if (contextBar == null || contextBar.Controls.Count < 1)
return;
try
{
try
{
const string irMenuTag = "My Menu";
const string caption = "New Menu";
AddContextMenu(contextBar, caption, irMenuTag);
}
catch (Exception err)
{
MessageBox.Show(err.Message, err.Source);
}
}
catch
{
}
}
finally
{
if (contextBar != null)
Marshal.ReleaseComObject(contextBar);
}
_module.CommandBarsObj = null;

}
finally
{
if (sel != null)
Marshal.ReleaseComObject(sel);
if (currentFolder != null)
Marshal.ReleaseComObject(currentFolder);
}
}
finally
{
if (nameSpace != null)
Marshal.ReleaseComObject(nameSpace);
if (activeExplorer != null)
Marshal.ReleaseComObject(activeExplorer);
}
}

private void AddContextMenu(Office.CommandBar contextBar, string caption, string controlTag)
{

// Try to find the New Menu on the context menu
Office.CommandBarControl irMenu =
contextBar.FindControl(Office.MsoControlType.msoControlPopup, Type.Missing, controlTag, Type.Missing, Type.Missing);
ADXCommandBarPopup barPopup;
if (irMenu == null)
{
contextBar.Protection = Office.MsoBarProtection.msoBarNoProtection;
if (_adxCommandBar == null)
{
_adxCommandBar = new ADXCommandBar();
_adxCommandBar.CommandBarObj = contextBar;
}
else
{

barPopup = _adxCommandBar.Controls.GetControlByControlTag(controlTag, false) as ADXCommandBarPopup;
if (barPopup != null)
{
barPopup.ControlObj = null;
_adxCommandBar.Controls.RemoveAt(_adxCommandBar.Controls.IndexOf(barPopup));
}
}
barPopup = new ADXCommandBarPopup();
barPopup.ControlTag = controlTag;
barPopup.Caption = caption;

if (_adxCommandBar.Controls.Add(barPopup) != null)
{
barPopup.ControlObj = contextBar.Controls.Add(Office.MsoControlType.msoControlPopup,
Type.Missing, Type.Missing,
(barPopup.Before > 0
? barPopup.Before
: Type.Missing), true);
barPopup.Temporary = true;
AddControl(barPopup, "Button 1", "Button Context Button", _clickHandler.DoClick, ImageIcons.Button1);
AddControl(barPopup, "Button 2", "Button 2 Context Button", _clickHandler.DoClick,
ImageIcons.Button2);
AddControl(barPopup, "Button 3", "Button 3 Context Button", _clickHandler.DoClick,
ImageIcons.Button3);
barPopup.UpdateControlObj(_module);
}
}
else
{
Marshal.ReleaseComObject(irMenu);
}
}


private ADXCommandBarControl AddControl(ADXCommandBarPopup popup, string caption, string controlTag, ADXClick_EventHandler clickHandler, ImageIcons imageIcon)
{
ADXCommandBarControl control = popup.Controls.Add(typeof (ADXCommandBarButton), controlTag, 1, 1, false);

ADXCommandBarButton button = control.AsButton;
button.ControlTag = controlTag;
button.Caption = caption;
button.Click -= clickHandler;
button.Click += clickHandler;
button.ImageList = _imageList;
button.Style = ADXMsoButtonStyle.adxMsoButtonIconAndCaption;
if (imageIcon != ImageIcons.None)
{
button.ImageTransparentColor = Color.Fuchsia;
if (_imageList.Images.Count > (int)imageIcon)
button.Image = (int)imageIcon;
}
return button;
}
==============================================================

Thanks,
Ryan
Posted 16 Jul, 2008 21:47:19 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Ryan,

Below I post the code that works fine for me. There are moments I'd like to point to:

1. In AddContextMenu and in HandleContextMenu, I introduced new variables to keep contextBar.Controls. Your code doesn't release these COM objects. The same mistake exists in the original sample for VS 2003 (http://www.add-in-express.com/files/projects_pub/olitemscontextmenu.zip) which adds a custom toolbar button or two to the Context Menu in Outlook, is this correct? Another version of this sample (VS 2005-2008) is also available as http://www.add-in-express.com/files/projects_pub/olitemscontextmenu-vs2005.zip

2. What I really do is removing custom buttons from the popup correctly. See RemoveControlFromPopup.

3. Note that the custom popup is also shown when you right-click navigation pane shortcuts in Outlook 2003. To prevent this, you need to check if the Navigation Pane Options built-in button exists in the Context Menu. Its Office ID is 7887. This also applies to Outlook 2007.


Andrei Smolin
Add-in Express Team Leader


private void adxOutlookEvents_CommandBarsUpdate(object sender, EventArgs e)
        {
            HandleContextMenu();
        }
        public void HandleContextMenu()
        {
            Outlook.Selection sel = null;
            Outlook.NameSpace nameSpace = null;
            Outlook.Explorer activeExplorer = null;
            Outlook.MAPIFolder currentFolder = null;

            try
            {
                nameSpace = OutlookApp.GetNamespace("MAPI");
                activeExplorer = OutlookApp.ActiveExplorer();
                try
                {
                    currentFolder = activeExplorer.CurrentFolder;
                    try
                    {
                        sel = activeExplorer.Selection;
                    }
                    catch { }
                    Office.CommandBar contextBar = null;
                    //if (!AreAllSelectedItemsMail(sel))
                    //    return;
                    this.CommandBarsObj = activeExplorer.CommandBars;
                    try
                    {
                        contextBar = this.FindCommandBarObj("Context Menu") as Office.CommandBar;
                        if (contextBar == null) return;
                        Office.CommandBarControls contextBarControlsObj = contextBar.Controls;
                        int contextBarControlsCount = contextBarControlsObj.Count;
                        Marshal.ReleaseComObject(contextBarControlsObj);
                        if (contextBarControlsCount < 1)
                            return;
                        try
                        {
                            try
                            {
                                const string irMenuTag = "My Menu";
                                const string caption = "New Menu";
                                AddContextMenu(contextBar, caption, irMenuTag);
                            }
                            catch (Exception err)
                            {
                                MessageBox.Show(err.Message, err.Source);
                            }
                        }
                        catch
                        {
                        }
                    }
                    finally
                    {
                        if (contextBar != null)
                            Marshal.ReleaseComObject(contextBar);
                    }
                    this.CommandBarsObj = null;

                }
                finally
                {
                    if (sel != null)
                        Marshal.ReleaseComObject(sel);
                    if (currentFolder != null)
                        Marshal.ReleaseComObject(currentFolder);
                }
            }
            finally
            {
                if (nameSpace != null)
                    Marshal.ReleaseComObject(nameSpace);
                if (activeExplorer != null)
                    Marshal.ReleaseComObject(activeExplorer);
            }
        }

        private void AddContextMenu(Office.CommandBar contextBar, string caption, string controlTag)
        {

            // Try to find the New Menu on the context menu 
            Office.CommandBarControl irMenu =
                contextBar.FindControl(Office.MsoControlType.msoControlPopup, Type.Missing, controlTag, Type.Missing, Type.Missing);
            ADXCommandBarPopup barPopup;
            if (irMenu == null)
            {
                contextBar.Protection = Office.MsoBarProtection.msoBarNoProtection;
                if (_adxCommandBar == null)
                {
                    _adxCommandBar = new ADXCommandBar();
                    _adxCommandBar.CommandBarObj = contextBar;
                }
                else
                {
                    barPopup = _adxCommandBar.Controls.GetControlByControlTag(controlTag, false) as ADXCommandBarPopup;
                    if (barPopup != null)
                    {
                        RemoveControlFromPopup(barPopup, "Button Context Button", My_Click);
                        RemoveControlFromPopup(barPopup, "Button 2 Context Button", My_Click);
                        RemoveControlFromPopup(barPopup, "Button 3 Context Button", My_Click);
                        barPopup.ControlObj = null;
                        _adxCommandBar.Controls.Remove(barPopup);
                    }
                }
                barPopup = new ADXCommandBarPopup();
                barPopup.ControlTag = controlTag;
                barPopup.Caption = caption;

                if (_adxCommandBar.Controls.Add(barPopup) != null)
                {
                    Office.CommandBarControls contextBarControlsObj = contextBar.Controls;
                    barPopup.ControlObj = contextBarControlsObj.Add(Office.MsoControlType.msoControlPopup,
                                                                  Type.Missing, Type.Missing,
                                                                  (barPopup.Before > 0
                                                                       ? barPopup.Before
                                                                       : Type.Missing), true);
                    Marshal.ReleaseComObject(contextBarControlsObj);
                    contextBarControlsObj = null;
                    barPopup.Temporary = true;
                    barPopup.UpdateControlObj(this);
                    AddControl(barPopup, "Button 1", "Button Context Button", My_Click, -1);
                    AddControl(barPopup, "Button 2", "Button 2 Context Button", My_Click, -1);
                    AddControl(barPopup, "Button 3", "Button 3 Context Button", My_Click, -1);
                }
            }
            else
            {
                Marshal.ReleaseComObject(irMenu);
            }
        }


        //private ADXCommandBarControl AddControl(ADXCommandBarPopup popup, string caption, string controlTag, ADXClick_EventHandler clickHandler, ImageIcons imageIcon)
        private ADXCommandBarControl AddControl(ADXCommandBarPopup popup, string caption, string controlTag, ADXClick_EventHandler clickHandler, int imageIcon)
        {
            ADXCommandBarControl control = popup.Controls.Add(typeof(ADXCommandBarButton), controlTag, 1, 1, false);

            ADXCommandBarButton button = control.AsButton;
            button.ControlTag = controlTag;
            button.Caption = caption;
            //button.Click -= clickHandler;
            button.Click += clickHandler;
            button.Temporary = true;
            //button.ImageList = _imageList;
            button.Style = ADXMsoButtonStyle.adxMsoButtonIconAndCaption;
            //if (imageIcon != -1)
            //{
            //    button.ImageTransparentColor = Color.Fuchsia;
            //    if (_imageList.Images.Count > imageIcon)
            //        button.Image = imageIcon;
            //}
            return button;
        }

        private void RemoveControlFromPopup(ADXCommandBarPopup popup, string controlTag, ADXClick_EventHandler clickHandler)
        {
            ADXCommandBarControl control = popup.Controls.GetControlByControlTag(controlTag, true);
            ADXCommandBarButton button = control.AsButton;
            button.Click -= clickHandler;
            button.ControlObj = null;
            popup.Controls.Remove(button);

        }
        private void My_Click(object sender)
        {
            MessageBox.Show((sender as AddinExpress.MSO.ADXCommandBarControl).Caption, AddinName);
        }

Posted 17 Jul, 2008 05:56:42 Top
Ryan Taylor




Posts: 46
Joined: 2008-04-08
Hi Andrei,

Thank you very much for your help with this, it worked perfectly! I guess properly removing the buttons along with the COM object references was the key. I also didn't realize about the Navigation pane options, good to know.

Again, thanks!

Ryan
Posted 17 Jul, 2008 16:02:34 Top