Using Word Dialogs programmatically: C# sample
This blog is about a sample add-in project (with source code) demonstrating how to use Word dialogs programmatically. With this add-in you can:
- check if a given dialog is suitable for your task
- get version-specific information about that dialog and its properties
Microsoft Word contains a lot of built-in dialogs; there are 238 of them in Word 2010! Although the whole feature seems to be abandoned, it looks like many dialogs can be used. Run this add-in to check if any given dialog is okay.
The UI of the add-in is built into an Advanced Word Task Pane. You specify a Word version (#1 in the screenshot), choose a Word dialog (#2), set a property (#3) and click an action button (#4) to invoke a method that the Word.Dialog interface provides.
Many dialogs provide properties e.g. the dialog identified by the constant wdDialogConnect provides the properties Drive, Password and Path (see the screenshot). Dialog properties are accessible via late binding only, see code samples in How to: Use Built-In Dialog Boxes in Word on MSDN or pay attention to the property WdBuiltinDialogProperty.Value in the code of this add-in. Properties names are published in MSDN. They are also available in the code of the add-in.
Word Dialogs: Backward compatibility issues
You should know that Office applications are almost 100% backward-compatible. Dialog properties is the area where backward compatibility gets broken too often. The list of properties existing in every Word version of every Word dialog is contained in the constructor of the WdBuiltinDialogs class, see the code of the add-in.
Good luck!
Available downloads:
These sample COM Add-ins were developed using Add-in Express for Office and .net:
2 Comments
Hi Andrei,
Unfortunately it seems the forum search isn’t working so I’ll have to ask my question as a comment here. I hope you don’t mind!
QUESTION: Using .NET and VSTO, is there a way to programmatically check if any built-in dialog box is open in Word?
Reason being, I do some initialization in my add-in when a document is opened, and during that time I disable the add-in’s ribbon. Here’s the scenario:
1. User opens a document, the add-in loads just fine.
2. User opens the Word Options dialog.
3. User then opens a second document.
4. The initialization code runs, and throws an exception.
5. The ribbon on the first document is disabled!
So as you can see, I need a way to detect if a dialog box is open in Word so that I can stop the user from opening a second document.
The code I am using is:
var word = new Microsoft.Office.Interop.Word.Application();
foreach (Microsoft.Office.Interop.Word.Document document in word.Documents)
{
if (document.ReadOnly) // This line fails with: “System.Runtime.InteropServices.COMException (0x8001010A): The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))”
{
// Do some stuff
}
}
Do you have any idea of how to achieve this?
Thanks in advance,
~Sam.
Hello Sam,
1. You can intercept Ribbon buttons and keyboard combinations opening that dialog.
2. The error message makes me think you run this code in a background thread. If so, you need to change your code so that all of the object model calls are performed on the main thread. This is because the Word object model (as well as object models of all Office applications) is NOT thread safe. Another possibility to get this exception may be var word = new Microsoft.Office.Interop.Word.Application(): a Word add-in isn’t expected to create a new Word.Application. Instead, you need to use the WordApp property of the add-in module. You access it via {add-in project name e.g. MyAddin1}.AddinModule.CurrentInstance.WordApp.
3. Of all Office applications, Word is most tolerant to your leaving COM objects unreleased. Still, if you run in an issue which is sporadic, reproduced with difficulties, etc. You might need to review your code so that all COM objects it creates are released. In such a case, please note that using foreach on an Office COM collection isn’t recommended; use a for loop instead.