Version-neutral invoking of overridden FileSave and FileSaveAs commands

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

Version-neutral invoking of overridden FileSave and FileSaveAs commands
 
Mike McGavin




Posts: 38
Joined: 2011-05-31
Hello.

I have a Word add-in which needs to operate in both Word 2003 and Word 2007. It's mostly going well, but I've struck a problem with trying to invoke the Save As command.

The specific problem is that there's an independent 3rd party addin, for a records management product, which has overridden the Save and Save As commands, and when operating properly Word needs to display the Records product save dialog instead of the native Word Save As dialog.

I can get Word 2007 to work with the following lines of code (which I've simplified).


 object oCommandBars = _application.CommandBars;
 oCommandBars.GetType().InvokeMember("ExecuteMso", System.Reflection.BindingFlags.InvokeMethod, null, oCommandBars, new string[] { "FileSaveAs" });


(I'd rather not use .InvokeMember() here but I think the version-neutral interops make it necessary.) When executed, the above lines just do whatever would happen if the user invoked the FileSaveAs command.

Frustratingly I can't get the same effect in O2003, though. The ExecuteMso method was only introduced in 2007, so isn't available.

I've tried the following ideas, without success:

* Calling document.SaveAs() on my active Word.Document object -- this seems to bypass the other addin's override, and gives me a local SaveAs dialog.

* Looping through everything returned by this line, and calling .Execute() if it has anything to do with saving in the caption:


 _application.CommandBars.FindControls(MsoControlType.msoControlButton, Type.Missing, Type.Missing, Type.Missing)


Of about 1000 results, I tried experimentally calling .Execute() on all CommandBarControl objects in the result set that contained "Save" in the caption. There were about 10, and all caused the native local Save As dialog to pop up (for my unsaved document).

I think some were the same command and had been included multiple times in the result set, because they had identical values for .Id.


Right now I'm out of ideas. Every method I can find for invoking the SaveAs command in Word 2003 causes the native Save As command to be executed instead of the overridden version of it from the 3rd party addin.

Is there something especially obvious anyone can see that I'm missing?

Thanks.
Mike.
Posted 31 May, 2011 03:40:04 Top
Eugene Astafiev


Add-in Express team


Posts: 8540
Joined: 2007-07-25
Hi Mike,

Please try to find the required control and then use the Execute method. You can use the Built-in Control Scanner component to find the required ID which should be passed to the FindControl function of the CommandBar class in Office.
.NET, Extended MAPI, Windows Phone & RT
Posted 31 May, 2011 08:12:45 Top
Mike M




Posts: 38
Joined: 2011-05-31
Hi Eugene.

Thanks for the speedy response. I downloaded the scanner as you suggested and it's confirmed that the command ID I should be using for the Save button on the Standard toolbar is 3. Sadly if run the following code, I'm still getting the native local save dialog.


cbc = _document.Application.CommandBars;
control = cbc.FindControl(MsoControlType.msoControlButton, 3, Type.Missing, Type.Missing);
control.Execute();


It seems weird because if I interactively click the Save button on the standard toolbar, I get the replacement dialog from the third party addin. I don't have a clue what method that 3rd party addin is using to override the Save command. All I know is that it's a COM addin, and somehow it's catching every Save event that Word goes through (except the ones I try to invoke programmatically!)

If I run the following code, the controls collection ends up containing 7 commands that all have the same ID of 3. I'm not sure if this is normal or if they're all the same command object being repeated, but the end result is that I get 7 local save dialogs in a row.


cbc = _document.Application.CommandBars;
controls = cbc.FindControls(MsoControlType.msoControlButton, 3, Type.Missing, Type.Missing);
foreach (CommandBarControl control in controls)
{
    control.Execute();
}
Posted 31 May, 2011 18:34:16 Top
Eugene Astafiev


Add-in Express team


Posts: 8540
Joined: 2007-07-25
Hi Mike,

Did you try to use the SaveAs (ID=748) button instead? Does it help?
.NET, Extended MAPI, Windows Phone & RT
Posted 01 Jun, 2011 02:11:24 Top
Mike McGavin




Posts: 38
Joined: 2011-05-31
Hello Eugene.

Thanks for the idea but unfortunately that's having the same issue.

I've noticed that despite the menu items and toolbar buttons going to the record management dialogs, the Ctrl+S shortcut also only displays a local disk save dialog, so I guess that shortcut's still hitting the same internal commands that my own code is, which they've not properly overridden. :(

I don't know enough about Word's internals to have much of a clue about how they've designed their integration, but if they'd gone through the BeforeSave event and put in their own dialog, the CommandBarControl objects should definitely be working shouldn't they?

Mike.
Posted 02 Jun, 2011 01:20:54 Top
Eugene Astafiev


Add-in Express team


Posts: 8540
Joined: 2007-07-25
Hi Mike,

Yes. You are on the right avenue. Unfortunately I don't have any other thoughts right now.

FYI To get assistance with host applications’ objects, their properties, and methods as well as help info, use the Object Browser. Go to the VBA environment (in the host application, choose menu Tools | Macro | Visual Basic Editor or just press {Alt+F11}), press {F2}, select the host application in the topmost combo and/or specify a search string in the search combo. Select a class /property /method and press {F1} to get the help topic that relates to the object.
.NET, Extended MAPI, Windows Phone & RT
Posted 02 Jun, 2011 02:03:45 Top