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).

Table 8-4. Some Late-Bound Properties Associated with the Print Dialog

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.

For newer dialogs that were not around in Word 95 and are not listed in the Word Basic help file, you can try to figure out how to get to a particular dialog option by trial and error. For example, in the XML Options dialog, which is new to Word 2003 (WdWordDialog.wdDialogXMLOptions), you can determine some of the properties by writing reflection code to try to invoke names that seem reasonable based on the names of the controls in the dialog box. If the code fails, you know you guessed the wrong property name. If the code succeeds, you have found a property name. In this way you would discover that AutomaticValidation, IgnoreMixedContent, ShowAdvancedXMLErrors, and ShowPlaceholderText are some of the properties associated with the XML Options dialog. At this point, however, you are really out there on your own. A search on the Web for "ShowAdvancedXMLErrors," for example, returned no hitsyou might be the first person and the last person in the world to use this late-bound property.

Listing 8-14 shows a VSTO customization that prepopulates the Print dialog box with a page range and number of copies to print. It uses reflection to set the Range, NumCopies, and Pages properties on the Dialog object. The helper method SetPropertyHelper uses reflection to set a late-bound property. The helper method GetPropertyHelper uses reflection to get the value of a late-bound property. The code in Listing 8-14 will display the Print dialog without allowing Word to execute any actions. The user can change values in the dialog. The code then shows the values of Range, NumCopies, and Pages after the dialog has been displayed.

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); }

Категории