问题
I tried to create a right-click menu item in Microsoft Word based on this post.
Here is my code:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
try
{
eventHandler = new _CommandBarButtonEvents_ClickEventHandler(MyButton_Click);
Word.Application applicationObject = Globals.ThisAddIn.Application as Word.Application;
applicationObject.WindowBeforeRightClick += new Microsoft.Office.Interop.Word.ApplicationEvents4_WindowBeforeRightClickEventHandler(App_WindowBeforeRightClick);
}
catch (Exception exception)
{
MessageBox.Show("Error: " + exception.Message);
}
}
void App_WindowBeforeRightClick(Microsoft.Office.Interop.Word.Selection Sel, ref bool Cancel)
{
try
{
this.AddItem();
}
catch (Exception exception)
{
MessageBox.Show("Error: " + exception.Message);
}
}
private void AddItem()
{
Word.Application applicationObject = Globals.ThisAddIn.Application as Word.Application;
CommandBarButton commandBarButton = applicationObject.CommandBars.FindControl(MsoControlType.msoControlButton, missing, "HELLO_TAG", missing) as CommandBarButton;
if (commandBarButton != null)
{
System.Diagnostics.Debug.WriteLine("Found button, attaching handler");
commandBarButton.Click += eventHandler;
return;
}
CommandBar popupCommandBar = applicationObject.CommandBars["Text"];
bool isFound = false;
foreach (object _object in popupCommandBar.Controls)
{
CommandBarButton _commandBarButton = _object as CommandBarButton;
if (_commandBarButton == null) continue;
if (_commandBarButton.Tag.Equals("HELLO_TAG"))
{
isFound = true;
System.Diagnostics.Debug.WriteLine("Found existing button. Will attach a handler.");
commandBarButton.Click += eventHandler;
break;
}
}
if (!isFound)
{
commandBarButton = (CommandBarButton)popupCommandBar.Controls.Add(MsoControlType.msoControlButton, missing, missing, missing, true);
System.Diagnostics.Debug.WriteLine("Created new button, adding handler");
commandBarButton.Click += eventHandler;
commandBarButton.Caption = "h5";
commandBarButton.FaceId = 356;
commandBarButton.Tag = "HELLO_TAG";
commandBarButton.BeginGroup = true;
}
}
private void RemoveItem()
{
Word.Application applicationObject = Globals.ThisAddIn.Application as Word.Application;
CommandBar popupCommandBar = applicationObject.CommandBars["Text"];
foreach (object _object in popupCommandBar.Controls)
{
CommandBarButton commandBarButton = _object as CommandBarButton;
if (commandBarButton == null) continue;
if (commandBarButton.Tag.Equals("HELLO_TAG"))
{
popupCommandBar.Reset();
}
}
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
Word.Application App = Globals.ThisAddIn.Application as Word.Application;
App.WindowBeforeRightClick -= new Microsoft.Office.Interop.Word.ApplicationEvents4_WindowBeforeRightClickEventHandler(App_WindowBeforeRightClick);
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
//Event Handler for the button click
private void MyButton_Click(CommandBarButton cmdBarbutton, ref bool cancel)
{
System.Windows.Forms.MessageBox.Show("Hello !!! Happy Programming", "l19 !!!");
RemoveItem();
}
}
}
and the result when i right click on a letter :
But with a table I cannot do it. Check out the screenshot to see what I mean:
I can not add the item menu when i right click on a table of ms word. Please help me. Thank!!
sorry about my english,...
回答1:
OK, Finally I have successed to fix it.
first of all, there are more than 200 different contextmenu for RightClick
but the common type of word.application.CommandBars are base on under Indexes { 105, 120, 127, 117, 108, 99, 134 }; these are contains the indexes of text, table, heading, textBox and ...
so, you must update your code by foreach to iterate the create new commandBarButtons on each type of ContextMenu someting like under code use this on your Startup Function
try
{
List<int> mindex = new List<int>() { 105, 120, 127, 117, 108, 99, 134 };
foreach (var item in mindex)
{
AddItemGeneral(applicationObject.CommandBars[item], youreventHandler, "yourTagLabelplusaDiffNumber" + item.ToString(), "your Caption");
}
}
catch (Exception exception)
{
MessageBox.Show("Error: " + exception.Message);
}
Finally,
private void AddItemGeneral(CommandBar popupCommandBar, _CommandBarButtonEvents_ClickEventHandler MyEvent, string MyTag,string MyCaption)
{
CommandBarButton commandBarButton = popupCommandBar.CommandBars.FindControl(MsoControlType.msoControlButton, missing, MyTag, missing) as CommandBarButton;
if (commandBarButton == null)
{
commandBarButton = (CommandBarButton)popupCommandBar.Controls.Add(MsoControlType.msoControlButton, Missing.Value, Missing.Value, popupCommandBar.Controls.Count + 1, true);
commandBarButton.Caption = MyCaption;
commandBarButton.BeginGroup = true;
commandBarButton.Tag = MyTag;
commandBarButton.Click += MyEvent;
}
else
{
commandBarButton.Click += MyEvent;
}
}
I hope it helps you guys. ;->
回答2:
Word maintains more than one context menu. You can see all of them by enumerating all CommandBar
objects in Application.CommandBars
whose position is msoBarPopup
:
foreach (var commandBar in applicationObject.CommandBars.OfType<CommandBar>()
.Where(cb => cb.Position == MsoBarPosition.msoBarPopup))
{
Debug.WriteLine(commandBar.Name);
}
The command bar that is used in the linked sample is the one named "Text" and this one is related to the context menu that pops up when you right-click somewhere in the text of a paragraph.
However, to add something to the context menu of a table you have to add your button to the appropriate table-related context menu. Tables have a different context menus depending on what is selected when you click:
- applicationObject.CommandBars["Tables"]
- applicationObject.CommandBars["Table Text"]
- applicationObject.CommandBars["Table Cells"]
- applicationObject.CommandBars["Table Headings"]
- applicationObject.CommandBars["Table Lists"]
- applicationObject.CommandBars["Table Pictures"]
So I would suggest that you extract a method that adds a button to a CommandBar
and then you call that method with all the command bars where you want to add your button to. Something like the following:
private void AddButton(CommandBar popupCommandBar)
{
bool isFound = false;
foreach (var commandBarButton in popupCommandBar.Controls.OfType<CommandBarButton>())
{
if (commandBarButton.Tag.Equals("HELLO_TAG"))
{
isFound = true;
Debug.WriteLine("Found existing button. Will attach a handler.");
commandBarButton.Click += eventHandler;
break;
}
}
if (!isFound)
{
var commandBarButton = (CommandBarButton)popupCommandBar.Controls.Add
(MsoControlType.msoControlButton, missing, missing, missing, true);
Debug.WriteLine("Created new button, adding handler");
commandBarButton.Click += eventHandler;
commandBarButton.Caption = "Hello !!!";
commandBarButton.FaceId = 356;
commandBarButton.Tag = "HELLO_TAG";
commandBarButton.BeginGroup = true;
}
}
// add the button to the context menus that you need to support
AddButton(applicationObject.CommandBars["Text"]);
AddButton(applicationObject.CommandBars["Table Text"]);
AddButton(applicationObject.CommandBars["Table Cells"]);
回答3:
As Dirk indicated, you need to click the EDIT link under your original question, paste the information in your "answer" at the end of it, then delete the "answer" - it's not an answer...
My Answer bases on the additional information you've provided. This is obviously a VSTO application-level add-in. As such, for Office 2013 you need to create the customization menus using Ribbon XML. This cannot be done with the Ribbon Designer, so if you already have a Ribbon Designer you need to convert it to Ribbon XML. You'll find an article on how to do so in the VSTO documentation: https://msdn.microsoft.com/en-us/library/aa942866.aspx
Information on how to use Ribbon XML to customize the context menus can be found in this MSDN article: https://msdn.microsoft.com/en-us/library/ee691832(v=office.14)
To summarize: you need to add a <contextMenus> element to the Ribbon XML with a <contextMenu> element for each menu item you want to add or change. The idMso attribute of the element specifies WHICH context menu. You can find a list of the ControlIds (values for idMso) in the Downloads on Microsoft's site: https://www.microsoft.com/en-us/download/details.aspx?id=36798
FWIW the ControlId for that context menu is probably ContextMenuTextTable.
来源:https://stackoverflow.com/questions/34280329/how-to-add-a-menu-item-in-microsoft-office-word