1

I'm developing an MS Word add-in. In newer MS Word editions, there is the "FILE" option in the menu bar which opens an interface where you can select a recent document to open, open a new one, or an existing one. I am trying to find a way, through which I can know WHEN the user "leaves" the current document he is editing clicking on the FILE menu of Word. I cannot seem to find such an event. Is there a way to achieve this ?

The WindowDeactivate does not fulfill this purpose.

The reason I want to do this, is because for a custom spellchecker I'm writing, I'm highlighting the wrong words in an transparent (click through as well) form. So when the user in a recent version of Word clicks the FILE menu, the highlights are still there, as seen in the screenshot

TL:DR; is there a way to detect in MS Word when the user clicks the FILE option in the menu and the current document is not visible? I'm using add-in-express, so all the relevant word object model API is available.

I wonder how can I solve this, any help is appreciated.

edit: screenshot enter image description here

MirrorMirror
  • 186
  • 8
  • 36
  • 70

2 Answers2

2

Yes, you can detect and then execute code both when the File menu is clicked (displaying the Backstage View) and when the View's return arrow is clicked to remove the Backstage View and display the document. To do this use the onShow and onHide attributes with callbacks via a custom XML ribbon in your VSTO project (this will not work with a ribbon made with the Visual Designer).

Reference material can be found here:

Performing Actions When the Backstage View is First Displayed or Hidden

As this article uses VBA to expand on the concepts involved, I built a sample project demonstrating how onShow works using C# and Word 2016 (the documentation was written for Office 2010, but onShow and onHide will work in later versions of Word).

Solution Tree

enter image description here

Custom XML Ribbon (BackstageRibbon.xml)

Note that the <backstage> node, which activates the onShow attribute for the callback, follows the <ribbon> node in the XML.

<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" 
onLoad="Ribbon_Load">
  <ribbon>
    <!--Ribbon XML goes here-->
  </ribbon>
  <backstage onShow="onShow">
  </backstage>
</customUI>

Ribbon Code (BackstageRibbon.cs)

A bunch of this code is boilerplate, however public void onShow is the callback that executes your code based on the onShow attribute in the ribbon's custom XML. Also, public string GetCustomUI is where the C# is told to find the XML.

namespace Backstage_Events
{
    [ComVisible(true)]
    public class BackstageRibbon : Office.IRibbonExtensibility
    {
        private Office.IRibbonUI ribbon;

        public BackstageRibbon()
        {
        }

        #region IRibbonExtensibility Members

        public string GetCustomUI(string ribbonID)
        {
            return GetResourceText("Backstage_Events.BackstageRibbon.xml");
        }

        #endregion

        #region Ribbon Callbacks
        //Create callback methods here. For more information about adding callback methods, visit https://go.microsoft.com/fwlink/?LinkID=271226

        public void Ribbon_Load(Office.IRibbonUI ribbonUI)
        {
            this.ribbon = ribbonUI;
        }

        public void onShow(object contextObject)
        {
            //Code to be executed before Backstage View displays goes here
            MessageBox.Show("Backstage Display Event Triggered!");
        }

        #endregion

        Helpers //Region
    }
}

ThisAddin.cs

You will also need to add:

protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
    {
        return new BackstageRibbon();
    }

after the ThisAddIn_Startup and ThisAddIn_Shutdown private voids in the ThisAddin.cs class to instantiate the custom ribbon.

joeschwa
  • 3,083
  • 1
  • 21
  • 41
  • did you get the bounty? – MirrorMirror Mar 29 '21 at 12:37
  • @MirrorMirror no, I did not. – joeschwa Mar 29 '21 at 14:15
  • @MirrorMirror When bounties are posted, there are [defined rules that govern how they are awarded](https://stackoverflow.com/help/bounty). When you marked my answer correct, it was after the bounty period and grace period had both expired. I thought it was interesting that your intent to award me the bounty was not aligned with these rules so I created [a post in Meta](https://meta.stackexchange.com/q/362668/393327). – joeschwa Mar 29 '21 at 20:00
  • Acceptance of an answer and awarding of a bounty don’t and are not always linked. However, an accepted answer submitted after a bounty is started automatically receives the bounty regardless if it doesn’t receive more than 2 votes. – Security Hound Mar 29 '21 at 23:13
  • @SecurityHound I believe what you wrote is true if the answer is accepted during the bounty period. Even though the answer was submitted during the bounty period, it was not accepted until a number of hours after the both the bounty and grace periods had expired. As such, the bounty was not awarded. – joeschwa Mar 30 '21 at 03:03
  • @SecurityHound I'm sorry for causing this trouble, is there a way to fix it? – MirrorMirror Mar 30 '21 at 14:50
  • @MirrorMirror I do not believe there is a way to change this outcome. I raised this issue on Meta and the idea of altering the bounty rules was rejected by those who participated in the discussion. – joeschwa Mar 30 '21 at 19:36
  • @MirrorMirror - You did absolutely nothing wrong. You are under no obligation to accept an answer or award a bounty. If at any point you feel pressured to do that report that comment. – Security Hound Mar 30 '21 at 21:15
  • @SecurityHound There was no pressure exerted. I responded to MirrorMirror's question "is there a way to fix it?" and simply said I raised the issue and this is not possible. That is the opposite of exerting pressure. That is saying there is no issue here. However, if there is still any remote perception that I am exerting pressure to change this outcome, please rest assured that I do not wish to do so. I simply thought it was worth exploring the bounty rules on Meta. Both MirrorMirror and I were unaware of them. – joeschwa Mar 30 '21 at 21:29
  • @joeschwa - My comment wasn’t directed at you nor was it about you. It was a comment directed towards the author. – Security Hound Mar 30 '21 at 22:19
1

Word will fire the Application.DocumentOpen event - you can see it live in OfficeSpy (I am its author - click Application button, go to the Events tab, look at the log at the bottom of the window).

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
  • That event only fires when the user opens a document, not when users clicks the "FILE" option in the menu bar. Check the screenshot – MirrorMirror Mar 19 '21 at 11:30
  • That is not what I am seeing. I see the following Application events fire in OfficeSpy when I open a recent file through the File ribbon: WindowDeactivate, WindowActivate, DocumentChange , DocumentOpen, WindowDeactivate, WindowSize, – Dmitry Streblechenko Mar 19 '21 at 15:35
  • I do not open a new file yet. When you click the "FILE" button on MS Word (2007+) the page you see on the screenshot appears, from which then you can open a new file, so this happens before that – MirrorMirror Mar 20 '21 at 18:47
  • That is backstage. It is considered part of the ribbon. – Dmitry Streblechenko Mar 20 '21 at 19:04
  • Yes I did not know how it is called. So I want for that case to detect it, when the backstage opens. – MirrorMirror Mar 21 '21 at 18:46
  • I don't think any events fire. I can only think of adding a control to the backstage and providing a getLabel callback for it. When it fires, you know the backstage is being displayed. You might have to invalidate the ribbon afterwards to make sure Word does not cache it. – Dmitry Streblechenko Mar 21 '21 at 19:08