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 |
|
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);
}
|
|
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 |
|