Working with the Dialog Object
This chapter has briefly considered the Dialogs collection returned by the Application object's Dialogs property. You have also learned about the FileDialog object. You now learn in more detail how you can use and display Word's built-in dialogs by using the Dialog object.
Showing the Dialog and Letting Word Execute Actions
After you have a Dialog object, typically by using the Dialog collection's index operator, you can show the dialog in a variety of ways. The simplest way to show the dialog associated with a Dialog object is to call the Show method, which displays the dialog and lets Word execute any action the user takes in the dialog box. The Show method has an optional TimeOut parameter of type object that takes the number of milliseconds Word will wait before closing the dialog box automatically. If you omit the parameter, Word waits until the user closes the dialog box.The Show method returns an int value that tells you what button the user chose to close the dialog box. If the return value is 1, the user clicked the OK button. If the return value is 2, the user clicked the Close button. If the return value is 0, the user clicked the Cancel button.
Selecting the Tab on a Dialog box
For tabbed dialog boxes, such as the Options dialog, the Dialog object provides a DefaultTab property of type WdWordDialogTab. The DefaultTab property can be set before showing the dialog to ensure the dialog comes up with a particular tab selected. WdWordDialogType is an enumeration that contains values for the various tabs found in Word's built-in dialogs.
Showing the Dialog and Preventing Word from Executing Actions
Sometimes you will want to show a dialog without letting Word actually execute the action associated with the dialog box. For example, you might want to show the Print dialog box but execute your own custom actions when the user clicks OK in the Print dialog.The Dialog object has a Display method that will show the dialog while preventing Word from executing the action associated with the dialog. Just as with the Show method, the Display method takes an optional TimeOut parameter of type object and returns an int value that tells you which button the user pressed to close the dialog box.After you use the Display method to show a dialog, you can use the Execute method to apply the action the user took in the dialog that was shown using the Display method. As an example (one that would likely annoy a Word user), you might show the Print dialog and detect that a user clicked OK. But you might then prompt again to ask whether they are sure they want to print. If the user clicks Yes, you would call the Execute method on the dialog to print the document, as shown in Listing 8-13.
Listing 8-13. A VSTO Customization That Uses Display and Execute to Confirm Printing
private void ThisDocument_Startup(object sender, EventArgs e)
{
Range(ref missing, ref missing).InsertAfter("Test text");
Word.Dialog d = Application.Dialogs[
Word.WdWordDialog.wdDialogFilePrint];
int result = d.Display(ref missing);
if (result == -1)
{
DialogResult r = MessageBox.Show(
"Are you sure you want to print?",
"Annoying confirmation",
MessageBoxButtons.YesNoCancel);
if (r == DialogResult.Yes)
{
d.Execute();
}
}
}
Getting and Setting Fields in a Dialog
It is possible to prefill fields in a dialog box before showing it and to get fields from a dialog box after showing it. Unfortunately, it is rather difficult and inconsistent in availability and relies on some obscure functionality that originated from the original programming language for Word called Word Basic.The Dialog object you are working with may have several late-bound properties that can be get and set. A late-bound property does not appear in the type definition for the Dialog object, and so it cannot be seen using IntelliSense. In C#, a late-bound property cannot be called directly; it must be called through reflection. To use a late-bound property, you must first determine what the late-bound property names and types are for a particular dialog box. Then you must use the .NET framework reflection APIs to get and set the property.The available late-bound properties change depending on the type of dialog that you got from the Dialogs collection. So when you get a wdDialogXMLOptions dialog box, it will have one set of late-bound properties, and when you get a wdDialogFilePrint dialog box, it will have a different set of late-bound properties.Determining what the late-bound property names are for a particular dialog box involves some searching in older Word Basic help files. To get the Word Basic help files, search the Web for "wrdbasic.exe" to find an installer from Microsoft that installs Word Basic help. After you have installed the Word Basic help file, you can try to find a Word Basic function in the help file that corresponds to the dialog you are using.The Word Basic function is typically named as a concatenation of the menu name and command name. For example, the Word Basic function for the Print dialog in the File menu is FilePrint. By looking in the Word Basic help file for the FilePrint method, you will find that it has 14 parameters. Table 8-4 shows some of the late-bound properties documented in the Word Basic help file for the FilePrint (and hence the Print dialog box).
Property Name | Type | What It Does |
---|---|---|
Range | Selected int values | If 1, prints the selection. If 2, prints the current page. If 3, prints the range of pages specified by From and To. If 4, prints the range of pages specified by Pages. |
NumCopies | int | The number of copies to print. |
Pages | string | The page numbers and page ranges to print, such as "1-10, 15" which would print pages 1 through 10 and page 15. |
Listing 8-14. A VSTO Customization That Accesses Late-Bound Properties on a Dialog
private void ThisDocument_Startup(object sender, EventArgs e)
{
// Create 20 pages
Word.Range r = Range(ref missing, ref missing);
for (int i = 1; i < 20; i++)
{
object pageBreak = Word.WdBreakType.wdPageBreak;
r.InsertBreak(ref pageBreak);
}
Word.Dialog d = Application.Dialogs[
Word.WdWordDialog.wdDialogFilePrint];
// Set late-bound properties
SetPropertyHelper(d, "Range", 4);
SetPropertyHelper(d, "NumCopies", 2);
SetPropertyHelper(d, "Pages", "1-10, 15");
int result = d.Display(ref missing);
// Get late-bound properties
MessageBox.Show(String.Format(
"Range is {0}.",
GetPropertyHelper(d, "Range")));
MessageBox.Show(String.Format(
"NumCopies is {0}.",
GetPropertyHelper(d, "NumCopies")));
MessageBox.Show(String.Format(
"Pages is {0}.",
GetPropertyHelper(d, "Pages")));
}
private void SetPropertyHelper(object targetObject,
string propertyName, object propertyValue)
{
targetObject.GetType().InvokeMember(propertyName,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.SetProperty,
null,
targetObject,
new object[] { propertyValue },
System.Globalization.CultureInfo.CurrentCulture);
}
private object GetPropertyHelper(object targetObject, string propertyName)
{
return targetObject.GetType().InvokeMember(propertyName,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.GetProperty,
null,
targetObject,
null,
System.Globalization.CultureInfo.CurrentCulture);
}