Microsoft Word Add-In - Add to Contextual Menu

Viewed 1406

I've built an Add-In for Word and would now like to add an option to call a function from it when a user highlights a word and right clicks on it. I've found documentation here on how to modify the manifest.xml file but it doesn't seem to show a full example of how to add to the contextual menu, only how to add buttons and drop down menus.

The documentation also points me to a github page show examples but again lacks one for contextual menus. It also points to this video which seems to show what I want at about 1:20 but also doesn't show how to implement it.

So far I have this (added below the <FunctionFile>):

<ExtensionPoint xsi:type="ContextMenu">
  <OfficeMenu id="ContextMenuText">
    <Control xsi:type="Menu" id="TestMenu">
      <Label resid="ContextMenuLabel" />
      <Supertip>
          <Title resid="ContextualMenuTitle" />
          <Description resid="ContextualMenuTitleDesc" />
      </Supertip>
    </Control>         
  </OfficeMenu>
</ExtensionPoint>

When I try and validate the manifest file with this tool it tells me that I'm missing an Icon element, but I don't need an image for a context menu?

Is what I'm trying to do possible and if so could someone point me to an example?


Edit:

I've updated my code to reflect what @Mavi Domates wrote

<ExtensionPoint xsi:type="ContextMenu">
  <OfficeMenu id="ContextMenuText">
    <Control xsi:type="Button" id="openSearchButton">
      <Label resid="openSearchButtonLabel" />
      <Supertip>
        <Title resid="openSearchButtonTitle" />
        <Description resid="openSearchButtonDescription" />
      </Supertip>
      <Icon>
        <bt:Image size="16" resid="Contoso.tpicon_16x16" />
        <bt:Image size="32" resid="Contoso.tpicon_32x32" />
        <bt:Image size="80" resid="Contoso.tpicon_80x80" />
      </Icon>
      <Action xsi:type="ExecuteFunction">
        <FunctionName>getData</FunctionName>
      </Action>
    </Control>
  </OfficeMenu>
</ExtensionPoint>

When I add this code (right below the default <ExtensionPoint xsi:type="PrimaryCommandSurface"> My add-in no longer shows up in the "My Add-ins" menu. I downloaded Microsoft's manifest validator and it tells me my manifest is fine.

I've narrowed it down to the Control node causing the problem. If I just add:

<ExtensionPoint xsi:type="ContextMenu">
  <OfficeMenu id="ContextMenuText">
  </OfficeMenu>
</ExtensionPoint>

my add-in still shows in the menu. I've also added the relevant strings in my resources under <bt:ShortStrings>:

<bt:String id="openSearchButtonLabel" DefaultValue="Check it out!" />
<bt:String id="openSearchButtonTitle" DefaultValue="Hover over me" />
<bt:String id="openSearchButtonDescription" DefaultValue="For more info go here" />

My code seems to be exactly the same as the documentation. I'm not sure where to go from here. I'm on a mac if that changes things.

2 Answers

What you're trying to do is possible and you're very very close to it :)

You have selected your ContextMenu control to be a Menu type and not a Button. That means you want some sub-menu controls.

From documentation here: https://docs.microsoft.com/en-us/office/dev/add-ins/develop/create-addin-commands#step-7-add-the-resources-element

Each group requires at least one control. A Control element can be either a Button or a Menu. Use Menu to specify a drop-down list of button controls. Currently, only buttons and menus are supported. See the Button controls and Menu controls sections for more information.

That means if you want to have nested menus, your manifest is correct and you just need to add items + icons to it. Below you can see example code which is opening a taskpane / or executing a function depending on which sub-menu you click.

<ExtensionPoint xsi:type="ContextMenu">
  <OfficeMenu id="ContextMenuText">
    <Control xsi:type="Menu" id="TestMenu">
      <Label resid="ContextMenuLabel" />
      <Supertip>
          <Title resid="ContextualMenuTitle" />
          <Description resid="ContextualMenuTitleDesc" />
      </Supertip>
      <Icon>
         <bt:Image size="16" resid="your_icon_16"/>
         <bt:Image size="32" resid="your_icon_32"/>
         <bt:Image size="64" resid="your_icon_64"/>
         <bt:Image size="80" resid="_icon_80"/>
      </Icon>
      <!-- Add your context sub-menu items -->
      <Items>
         <Item id="contextitem1">
            <Label resid="somecontextlabel1"/>
            <Supertip>
                <Title resid="somecontexttitle1"/>
                <Description resid="somedescription1"/>
            </Supertip>
            <Icon>
                <bt:Image size="16" resid="someimage16"/>
                <bt:Image size="32" resid="someimage32"/>
                <bt:Image size="64" resid="someimage64"/>
                <bt:Image size="80" resid="someimage80"/>
            </Icon>
            <Action xsi:type="ShowTaskpane">
                <TaskpaneId>Mysupertaskpane1</TaskpaneId>
                <SourceLocation resid="TaskPaneSourceLocation1"/>
            </Action>
        </Item>

        <Item id="contextitem2">
            <Label resid="somecontextlabel2"/>
            <Supertip>
                <Title resid="somecontexttitle2"/>
                <Description resid="somedescription2"/>
            </Supertip>
            <Icon>
                <bt:Image size="16" resid="someimage16"/>
                <bt:Image size="32" resid="someimage32"/>
                <bt:Image size="64" resid="someimage64"/>
                <bt:Image size="80" resid="someimage80"/>
            </Icon>
            <Action xsi:type="ExecuteFunction">
                <FunctionName>dosomejsmagic</FunctionName>
            </Action>
        </Item>
      </Items>
    </Control>         
  </OfficeMenu>
</ExtensionPoint>

If that's not the case and you're only looking for a Button (so no sub menus) - then you can use this as an example see the control type is now set to be a Button

<ExtensionPoint xsi:type="ContextMenu">
    <OfficeMenu id="ContextMenuText">
        <Control xsi:type="Button" id="Button1Id1">
            <Label resid="residLabel" />
            <Tooltip resid="residToolTip" />
            <Supertip>
                <Title resid="residLabel" />
                <Description resid="residToolTip" />
            </Supertip>
            <Icon>
                <bt:Image size="16" resid="icon1_32x32" />
                <bt:Image size="32" resid="icon1_32x32" />
                <bt:Image size="80" resid="icon1_32x32" />
            </Icon>
            <Action xsi:type="ExecuteFunction">
                <FunctionName>getData</FunctionName>
            </Action>
        </Control>
    </OfficeMenu>
</ExtensionPoint>

I was having the same problem. Solved Now. Your code is just perfect. Its just that you need to start the server before sideloading. If you have created your add in using office-generator. Then 1. start your add-in by running "npm start" 2. now sideload it running "npm run sideload" in a seperate terminal. This solved my problem and hopefully will solve yours too.

Related