Summary: Provides information on how to use Microsoft Visual Studio Tools for the Microsoft Office System to take advantage of the objects available in Microsoft Office Word 2003. It introduces several important Word objects and provides examples of how to use them. You will learn how to work with Word 2003 applications and documents, as well as with some of the more important properties and methods. (105 printed pages)
Download the WordObject.exe from the Microsoft Download Center .
Contents
Introduction
Getting Started with a Word Project
The Underpinnings: Documents and Templates
Bird's-Eye View of the Word Object Model
The Application Object
The Document Object
The Selection Object
The Range Object
The Bookmark Object
Searching and Replacing Text
Printing
Creating Word Tables
Summary
Introduction
Microsoft® Word is probably one of the most commonly used software products in the world today. Most people using Word get by just fine without writing any code at all, although Word has a rich and powerful object model making it eminently programmable. Microsoft Visual Studio Tools for the Microsoft Office System enables developers to interact with the objects provided by the Microsoft Office Word 2003 object model by using a .NET language, such as Microsoft Visual Basic® .NET or Microsoft Visual C#®. Word possesses a rich feature set, all of which are accessible through code. There are quite a few objects to learn about, which can be confusing when you're first getting started. Conveniently, Word objects are arranged in a hierarchical fashion, and you can get a good start on the object model by focusing on the two main classes at the top of the hierarchy, the Application and Document classes. Focus on these two classes makes sense when you consider that most of the time you'll either be working with the Word application itself, or manipulating Word documents in some way.
As you dig into the Word object model, you'll find that it emulates the Word user interface, making it easy to guess that the Application object provides a wrapper around the entire application, each Document object represents a single Word document, the Paragraph object corresponds to a single paragraph, and so forth. Each of these objects has many methods and properties that allow you to manipulate and interact with it. The behaviors of the members of these objects are generally easy to guess—how about the PrintOut method? Others can be more obscure and sometimes tricky to use correctly. Once you learn the basics, you'll find that there isn't anything you can do in the Word user interface that you can't do just as easily in code. Programming in Word allows you to automate repetitive tasks, and to extend and customize the functionality built into Word.
In this document, you'll learn how to take advantage of many of the objects in Word 2003, and you will also be introduced to some of the properties, methods, and events of each object. You'll learn how to work with Word applications and documents, as well as with some of their more important methods and properties.
> Note Programming Word and its objects from Visual Basic .NET feels much like programming in VBA. Visual Basic .NET handles optional parameters, and allows late binding, just like VBA. C#, on the other hand, provides unique challenges when programming against the Word object model. Because C# doesn't support optional parameters, parameterized properties, or late binding, you'll need to handle many of the Word methods and properties specially when programming in C#. This document points out the differences between Visual Basic .NET and C# programming, as they come up.
Getting Started with a Word Project
When you create a new Office project in Visual Studio .NET, you are given the option of creating a new Word Document or Word Template project, as shown in Figure 1 .

Figure 1. You can create either a Word Document or a Word Template project in Visual Studio .NET.
Visual Studio .NET automatically creates a code file named ThisDocument.vb or ThisDocument.cs in your new Word project for both Document and Template projects. Open ThisDocument in your new project. You'll see that a public class named OfficeCodeBehind has already been generated for you. Expand the hidden Generated initialization code region. The OfficeCodeBehind class includes code that wraps the Word.Document and Word.Application objects:
' Visual Basic
Friend WithEvents ThisDocument As Word.Document
Friend WithEvents ThisApplication As Word.Application
// C#
private Word.Application thisApplication = null;
private Word.Document thisDocument = null;
These two variables are declared for you:
- ThisDocument: Represents the Word Document object, and allows access to all of the built-in Document members in Word, including methods, properties and events.
- ThisApplication: Represents the Word Application object, and allows access to all of the Application object's members, including events.
The availability of these two predefined variables allows easy access to both Word objects in your code without having to declare separate Word.Document or Word.Application objects—just use ThisDocument and ThisApplication .
Each of the following sections digs into the Document and Application objects, picking specific members of each object for demonstration. Word has a very rich object model, and it would be impossible to dig into all of the members here: You'll get enough of the flavor of the object model to be able to get started, and you'll learn enough to use the Word online help for more details.
> Tip Throughout this article, you'll see many uses of the CType and DirectCast methods in the Visual Basic .NET code. The reason for this is that the sample project has its Option Strict setting on—this means that Visual Basic .NET requires strict type conversions. Many Word methods and properties return Object types: For example, the _Startup procedure is passed variables named application and document as Object types, and the CType function is used to explicitly convert each to Word.Application and Word.Document objects, respectively. Therefore, to be as rigorous about conversions as possible, the sample has enabled Option Strict , and handles each type conversion explicitly. If you're a C# developer reading this document, you'll likely appreciate this decision. However, as you'll see later on, there are certain Word features that don't translate well into the object-oriented paradigm—it can sometimes be more convenient to work with Option Strict off. For the most part, you'll want to work with Option Strict on; you'll learn about the few exceptions as they arise.
The Underpinnings: Documents and Templates
Before you can effectively program Word, you need to understand how Word works. Most of the actions you'll perform in code have equivalents in the user interface on the menus and toolbars. There is also an underlying architecture that provides structure to those UI choices. One of the most important concepts is the idea of templates. You probably are already familiar with the concept of a template—a Word template can contain boilerplate text and styles as well as code, toolbars, keyboard shortcuts and AutoText entries. Whenever you create a new Word document, it is based on a template, which is distinguished by the .dot file name extension—Word documents have a .doc filename extension. The new document is linked to the template, and has access to all template items. If you do not specify a custom template, any new documents you create will be based on the Normal.dot default template, which is installed when you install Word.
About Normal.dot
The Normal.dot template is global in scope, and is available to every document you create. You could, if you wanted to, put all of your code in the Normal.dot and base all of the documents in your environment on your Normal template. But the file could become quite large, so for many developers, a better solution is to create customized templates for specific applications. Documents created using your custom template still have access to the code in the default Normal template. In fact, you can attach a document to more than one custom template in addition to Normal if you so desire.
Templates and Your Code
You are not limited to templates as containers for styles and code; you can also customize and write code in individual documents without affecting the content of the template the document is based on. When Word runs your code, it uses the fully qualified reference of the source (which can be a template or the document), the module name, and the procedure name. This operates in a similar fashion to namespaces, keeping procedures separated. Figure 2 shows the Customize dialog box for toolbars, illustrating this concept. Each procedure is fully qualified with the name of the project, the module, and the procedure name. In this case, the item selected in the right pane refers to a procedure named TileVertical that is contained in the Tile module in Normal.dot. The SaveDocument procedure listed immediately below it is contained in the active document's code behind project.

Figure 2. Procedure references are fully qualified when you assign them to a Toolbar.
> Tip One thing to remember is that Word always uses the "most local" rule when it comes to templates and documents. If duplicate styles, macros, or any other items exist in all three locations—Normal.dot, a custom template, and the current document—the one in the document is used first, then the one in the custom template, and then the one in Normal.dot.
Styles and Formatting
Word allows you to format a document in two different ways:
- By direct formatting. You can select text and apply formatting options such as font, bold, italic, size, and so forth.
- By applying a style. Word comes with built-in styles that you can modify to customize your documents. When you apply a style to a paragraph or a selection, multiple attributes are applied all at once. Styles are stored in templates and in documents.
Styles are normally applied to an entire paragraph: you can also define character styles that you can apply to a character, word, or range within a paragraph. You can examine the available styles by selecting Format | Styles and Formatting from the menu to bring up the Styles and Formatting pane shown in Figure 3 , where the Normal paragraph style is selected.

Figure 3. The default paragraph style is Normal.
Modifying Styles
When you click on the style name, it turns into a drop-down list box where you can select Modify from the available options. You can modify any of the built-in styles, and optionally save your changes in the template the document is based on, as shown by the Add to template check box setting in Figure 4 . If you omit this check box, your changes will be saved in the document, and will not propagate back to the template the document was based on.

Figure 4. Modifying a style
When working with Word, you'll want to use styles as much as possible. Styles give you a way to control the formatting of complex documents in a way that would be very difficult to achieve with direct formatting. It's important to understand how they work so that you can take advantage of them to make your code more efficient.
Understanding Paragraph Marks
When you look at a document in the Word user interface, you see the document broken up into words, paragraphs, sections, and so on. Under the covers, the Word document is nothing more than a vast stream of characters. Some of these characters are meant to be read, such as the letters and numbers, and others are not, such as spaces, tabs and carriage returns. Each of these characters has a task to perform.
In addition to separating one paragraph from another, a paragraph mark plays a very important role in a Word document: it contains all of the information about how the paragraph is formatted. When you copy a paragraph and include the paragraph mark, all of the formatting in the paragraph travels along with it. If you copy a paragraph and omit the paragraph mark, the formatting of the original paragraph will be lost when it is pasted into a new location.
When you are editing a Word document and you press the ENTER key on your keyboard, a new paragraph is created that is a clone of the previous paragraph in terms of formatting, and whatever paragraph formatting or style that was in effect is propagated in the new paragraph. You can apply different formatting to the second paragraph. On the other hand, a line break, which you create by pressing SHIFT + ENTER, simply puts in a line feed character in the existing paragraph and does not hold any formatting. If you apply paragraph formatting, it will apply to all text both before and after the line break characters.
Figure 5 shows the difference between a line break and a paragraph mark when your options are set to display paragraph marks.

Figure 5. The line break does not take paragraph formatting with it and a paragraph mark does.
Displaying Paragraph Marks
If you inadvertently delete a paragraph mark, it's possible you may lose your paragraph formatting. The best course of action is to ensure that they are always displayed by choosing Tools | Options | View from the menu and selecting the Paragraph marks check box in the Formatting marks section, as shown in Figure 6 .

Figure 6. Displaying Paragraph marks in the Formatting marks section of the Options dialog box
Bird's-Eye View of the Word Object Model
At first glance, the Word object model is rather confusing because there appears to be a lot of overlap. For example, the Document and Selection objects are both members of the Application object, but the Document object is also a member of the Selection object. Both the Document and Selection objects contain Bookmarks and Range objects, as you can see in Figure 7 . The following sections briefly describe the top-level objects and how they interact with each other.

Figure 7. The Application object contains the Document, Selection, Bookmark, and Range objects.
The Application Object
The Application object represents the Word application, and is the parent of all of the other objects. Its members usually apply to Word as a whole. You can use its properties and methods to control the Word environment.
The Document Object
The Document object is central to programming Word. When you open an existing document or create a new document, you create a new Document object, which is added to the Word Documents collection. The document that has the focus is called the active document and is represented by the Application object's ActiveDocument property.
The Selection Object
The Selection object represents the area that is currently selected. When you perform an operation in the Word user interface, such as bolding text, you select the text and then apply the formatting. The Selection object is always present in a document; if nothing is selected, the Selection object represents the insertion point. The Selection object can also be multiple noncontiguous blocks of text.
The Range Object
The Range object represents a contiguous area in a document, and is defined by a starting character position and an ending character position. You are not limited to a single Range object; you can define multiple Range objects in the same document. A Range object has the following characteristics:
- It can consist of only an insertion point, a range of text, or the entire document.
- It includes non-printing characters such as spaces, tab characters, and paragraph marks.
- It can be the area represented by the current selection, or it can represent a different area than the current selection.
- It is dynamic; it exists only so long as the code that creates it is running.
When you insert text at the end of a range, Word automatically expands the range to include the inserted text.
The Bookmark Object
The Bookmark object is similar to the Range object in that it represents a contiguous area in a document, with both a starting position and an ending position. You use bookmarks to mark a location in a document, or as a container for text in a document. A Bookmark object can consist of the insertion point alone or be as large as the entire document. You can also define multiple bookmarks in a document. A Bookmark has the following characteristics, setting it apart from the Range object:
- You can give the Bookmark object a name.
- It is saved with the document, and does not go away when the code stops running or your document is closed.
- It is hidden by default, but can be made visible by setting the View object's ShowBookmarks property to True. (The View object is a member of the Window and Pane objects, which exist for both the Application and Document objects.)
Tying it all Together
Here are some scenarios for using the Selection , Range , and Bookmark objects:
- Bookmarks are useful in templates. For example, a business letter template can contain bookmarks where data is to be inserted from a database. At run time, your code can create a new document based on the template, obtain the data from a database, locate the named bookmark, and insert the text in the correct location.
- If you need to modify the text inside of a Bookmark, you can use the Bookmark's Range property to create a Range object, and then use one of the Range object's methods to modify the text.
- You can define boilerplate text in a document by using a Bookmark object. You specify its contents using a Range or a Selection object as the source. You can then conditionally navigate to various Bookmarks at some future time to copy and paste the boilerplate text into other documents.
These are just a few of the ways in which you can make use of these objects to build powerful customized applications.
The Application Object
The Word Application object represents the Word application itself. Every time you write code, you begin with the Application object. From the Application object, you can access all the other objects and collections exposed by Word, as well as properties and methods of the Application object itself.
Using ThisApplication
If you are working in Word, the Application object is automatically created for you, and you can use the Application property to return a reference to the Word Application object. When you're creating Visual Studio .NET solutions, you can use the ThisApplication variable defined for you within the OfficeCodeBehind class.
If you are automating Word from outside this class, you must create a Word Application object variable and then create an instance of Word:
' Visual Basic
Dim appWord As Word.Application = _
New Word.Application
// C#
Word.Application appWord = new Word.Application();
> Tip Declaring a Word.Application variable works in your OfficeCodeBehind class the same way that ThisApplication does. However, it's an unnecessary extra step to explicitly create a new Word.Application variable because ThisApplication has already been created for you.
When you're referring to objects and collections beneath the Application object, you don't need to explicitly refer to the Application object. For example, you can refer to the active document without the Application object by using the built-in ThisDocument property. ThisDocument refers to the active document, and allows you to work with members of the Document object. The Document object will be covered more fully in later sections of this document.
> Tip The ThisApplication.ActiveDocument property, which refers to the active Document object, is likely the one you'll use most often. You'll generally want to use ThisDocument instead of ThisApplication.ActiveDocument syntax. ActiveDocument is available, but you need to fully qualify it with an Application object in order to use it in your code. Using ThisDocument is more efficient as the variable is already created for you, and amounts to the same thing.
Application Properties
Once you have a reference to an Application object, you can work with its methods and properties. The Application object provides a large set of methods and properties that you can use in your code to control Word. Most of the members of the Application object apply to global settings or the environment rather than to the contents of individual documents. Setting or retrieving some properties often requires only a single line of code; other retrievals are more complex.
ActiveWindow: Returns a Window object that represents the window that has the focus. This property allows you to work with whatever window has the focus. The sample code below creates a new window based on the current document and then uses the Arrange method of a Window object to tile the two windows. Note that the Arrange method uses the WdArrangeStyle . wdTiled enumerated value.
' Visual BasicFriend Sub CreateNewWindowAndTile() ' Create a new window from the active document. Dim wnd As Word.Window = _ ThisApplication.ActiveWindow.NewWindow ' Tile the two windows. ThisApplication.Windows.Arrange( _ Word.WdArrangeStyle.wdTiled) End Sub
// C# public void CreateNewWindowAndTile() { // Create a new window from the active document. Word.Window wnd = ThisApplication.ActiveWindow.NewWindow();
// Tile the two windows. Object value = Word.WdArrangeStyle.wdTiled; ThisApplication.Windows.Arrange(ref value);}
> Tip The Arrange method, like many methods in Word, requires C# developers to pass one or more parameters using the "ref" keyword. This means that the parameter you pass must be stored in a variable before you can pass it to the method. In every case, you'll need to create an Object variable, assign the variable the value you'd like to pass to the method, and pass the variable using the ref keyword. You'll find many examples of this technique throughout this document.
ActiveDocument: Returns a Document object that represents the active document or the document that has the focus
ActivePrinter: Returns or sets the name of the active printer
ActiveWindow: Returns the window that has the focus
AutoCorrect: Returns the current AutoCorrect options, entries, and exceptions. This property is read-only.
Caption: Returns or sets the caption text for the specified document or application window. You can use the Caption property to display "My New Caption" in the document window or application title bar:
' Visual BasicFriend Sub SetApplicationCaption() ' Change caption in title bar. ThisApplication.Caption = "My New Caption" End Sub
// C# public void SetApplicationCaption() { // Change caption in title bar. ThisApplication.Caption = "My New Caption"; }
CapsLock: Determines whether CapsLock is turned on, returning a Boolean value. The following procedure displays the state of CapsLock:
' Visual BasicFriend Sub CapsLockOn() MessageBox.Show("CapsLock is " & _ ThisApplication.CapsLock.ToString()) End Sub
// C# public void CapsLockOn() { MessageBox.Show(ThisApplication.CapsLock.ToString()); }
DisplayAlerts: Lets you specify how alerts are handled when code is running, using the WdAlertLevel enumeration. WdAlertlevel contains three values: wdAlertsAll , which displays all messages and alerts (the default); wdAlertsMessageBox , which displays only message boxes; and wdAlertsNone , which does not display any alerts or message boxes. When you set DisplayAlerts to wdAlertsNone, your code can execute without the user seeing any messages and alerts. When you're done, you'll want to ensure that DisplayAlerts gets set back to wdAlertsAll (generally, you'll reset this in a Finally block):
' Visual BasicFriend Sub DisplayAlerts() Try ' Turn off display of messages and alerts. ThisApplication.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone ' Your code runs here without any alerts. ' . . .code doing something here. Finally ' Turn alerts on again when done. ThisApplication.DisplayAlerts = Word.WdAlertLevel.wdAlertsAll End Try End Sub
// C# public void DisplayAlerts() { // Turn off display of messages and alerts. try { ThisApplication.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone; // Your code runs here without any alerts. // . . .code doing something here.
} catch (Exception ex) { // Do something with your exception. } finally { // Turn alerts on again when done. ThisApplication.DisplayAlerts = Word.WdAlertLevel.wdAlertsAll; }}
DisplayStatusBar: Read/write, returns a Boolean indicating whether or not the status bar is displayed. Returns True if it is displayed and False if it is not. The following procedure toggles the display of the status bar:
' Visual BasicFriend Sub ToggleStatusBar() Dim bln As Boolean = (ThisApplication.DisplayStatusBar) ThisApplication.DisplayStatusBar = Not bln End Sub
// C# public void ToggleStatusBar() { // Toggle display of the status bar. bool bln = ThisApplication.DisplayStatusBar; ThisApplication.DisplayStatusBar = !bln; }
FileSearch: Searches for files using either an absolute or a relative path. You supply the search criteria, and FileSearch returns the name of the files found in the FoundFiles collection.
' Visual BasicPublic Sub ListAllDocFilesOnC() Dim str As String Dim sw As New StringWriter Try ThisApplication.System.Cursor = Word.WdCursorType.wdCursorWait With ThisApplication.FileSearch .FileName = "*.doc" .LookIn = "C:" .SearchSubFolders = True .Execute() For Each str In .FoundFiles sw.WriteLine(str) Next End With MessageBox.Show(sw.ToString()) Finally ThisApplication.System.Cursor = Word.WdCursorType.wdCursorNormal End Try End Sub
// C# public void ListAllDocFilesOnC() { try { ThisApplication.System.Cursor = Word.WdCursorType.wdCursorWait; StringWriter sw = new StringWriter(); Office.FileSearch fs = ThisApplication.FileSearch; fs.FileName = "*.doc"; fs.LookIn = "C:\"; fs.SearchSubFolders = true; // Select the defaults, optional in VBA: fs.Execute(Office.MsoSortBy.msoSortByFileName, Office.MsoSortOrder.msoSortOrderAscending, true); foreach (String str in fs.FoundFiles) { sw.WriteLine(str); } MessageBox.Show(sw.ToString()); } finally { ThisApplication.System.Cursor =
Word.WdCursorType.wdCursorNormal; } }
> Tip In this example, you'll note that Visual Basic .NET developers needn't pass all the parameters to the Execute method, as they're all optional. C# developers, however, must pass every parameter. In this case, the code supplies values that match the default values. For reference-type parameters, you can pass the Type.Missing value, indicating to Word that it should treat the parameters as if you hadn't passed a value at all. For value-type parameters, you must specify an actual value. You can use the Word VBA help file to determine the default values for the value-type parameters.
Path: When used with the Application object, returns the path of the current application:
' Visual BasicMessageBox.Show(ThisApplication.Path)
// C# MessageBox.Show(ThisApplication.Path);
> Tip To return the path of the active document, use ThisDocument.Path.
Options: Returns an Options object that represents application settings for Word, allowing you to set a variety of options in your application. Many, but not all, of these options are available in the Tools | Options dialog box. The following code fragment will turn on the BackgroundSave and Overtype properties, among others. If the file is printed, any fields will be automatically updated, and hidden text and field codes will be printed.
' Visual Basic' Set various application options With ThisApplication.Options .BackgroundSave = True .Overtype = True .UpdateFieldsAtPrint = True .PrintHiddenText = True .PrintFieldCodes = True End With
// C# // Set various application options. Word.Options options = ThisApplication.Options;
options.BackgroundSave = true; options.Overtype = true; options.UpdateFieldsAtPrint = true; options.PrintHiddenText = true; options.PrintFieldCodes = true;
Selection: A read-only object that represents a selected range (or the insertion point). The Selection object is covered in detail later in this document.
UserName: Gets or sets the user name. The following procedure displays the current user's name, sets the UserName property to "Dudley" and displays the new UserName . The code then restores the original UserName .
' Visual BasicFriend Sub ChangeUserName() Dim str As String = ThisApplication.UserName MessageBox.Show(str) ' Change UserName. ThisApplication.UserName = "Dudley" MessageBox.Show(ThisApplication.UserName) ' Restore original UserName. ThisApplication.UserName = str End Sub
// C# public void ChangeUserName() { string str = ThisApplication.UserName; MessageBox.Show(str);
// Change UserName. ThisApplication.UserName = "Dudley"; MessageBox.Show(ThisApplication.UserName); // Restore original UserName. ThisApplication.UserName = str;}
Visible: A read/write property that turns the display of the Word application itself on or off. While the Visible property is False, all open Word windows will be hidden, and it will appear to the user that Word has quit and all document are closed (they are still running in the background). Therefore, if you set the Visible property to False in your code, make sure to set it to True before your procedure ends. The following code accomplishes this in the Finally block of a Try/Catch exception handler:
' Visual BasicTry ThisApplication.Visible = False ' Do work here, invisibly.
Catch ex As Exception ' Your exception handler here.
Finally ThisApplication.Visible = True End Try
// C# try { ThisApplication.Visible = false; // Do whatever it is, invisibly. } catch (Exception ex) { // Your exception handler here. } finally { ThisApplication.Visible = true; }
Application Methods
There are several methods of the Application object that you may find useful for performing actions involving the Word application. Writing code to make use of Application object methods is similar to working with properties. Use the following methods to perform actions on the application itself:
CheckSpelling: Checks a string for spelling errors. Returns True if errors are found, and False if no errors. This is handy if you just want to spell check some text to obtain a yes/no answer to the question "Are there any spelling errors?"—It doesn't display the errors or allow you to correct them. The following code checks the string "Speling erors here" and displays False in a MessageBox .
' Visual BasicFriend Sub SpellCheckString() ' Checks a specified string for spelling errors. Dim str As String = "Speling erors here." If ThisApplication.CheckSpelling(str) Then MessageBox.Show(String.Format("No errors in ""{0}""", str)) Else MessageBox.Show(String.Format( _ """{0}"" is spelled incorrectly", str)) End If End Sub
// C# public void SpellCheckString() { // Checks a specified string for spelling errors. string str = "Speling erors here.";
Object CustomDictionary = Type.Missing; Object IgnoreUppercase = Type.Missing; Object MainDictionary = Type.Missing; Object CustomDictionary2 = Type.Missing; Object CustomDictionary3 = Type.Missing; Object CustomDictionary4 = Type.Missing; Object CustomDictionary5 = Type.Missing; Object CustomDictionary6 = Type.Missing; Object CustomDictionary7 = Type.Missing; Object CustomDictionary8 = Type.Missing; Object CustomDictionary9 = Type.Missing; Object CustomDictionary10 = Type.Missing; // The CheckSpelling method takes a lot of optional // parameters, in VBA: if ( ThisApplication.CheckSpelling(str, ref CustomDictionary, ref IgnoreUppercase, ref MainDictionary, ref CustomDictionary2, ref CustomDictionary3, ref CustomDictionary4, ref CustomDictionary5, ref CustomDictionary6, ref CustomDictionary7, ref CustomDictionary8, ref CustomDictionary9, ref CustomDictionary10) ) { MessageBox.Show(String.Format("No errors in \"{0}\"", str)); } else { MessageBox.Show( String.Format("\"{0}\" is spelled incorrectly", str)); }}
> Tip This example demonstrates another example in which Visual Basic .NET developers have it much easier than those developing in C#. The CheckSpelling method accepts a single required string parameter, followed a large number of optional parameters. C# developers must pass a series of values by reference—in this case, a group of variables all containing the Type.Missing value. You'll find it useful, if you must call methods like CheckSpelling multiple times, to create a "helper" class that wraps up the method call. This class could include methods that expose only the most useful parameters for the Word method calls.
- Help: Displays Help dialog boxes. Specify a member of the WdHelpType enumeration to choose the particular dialog box, selecting from the following list:
- WdHelp: Displays the Microsoft Word main Help dialog box
- WdHelpAbout: Displays the dialog box available from the Help | About Microsoft Word menu item
- WdHelpSearch: Displays the main Help dialog box with the Answer Wizard displayed
The following line of code will display the Help About Microsoft Word dialog box:
' Visual Basic
Friend Sub DisplayHelpAbout()
ThisApplication.Help(Word.WdHelpType.wdHelpAbout)
End Sub
// C#
public void DisplayHelpAbout()
{
Object value = Word.WdHelpType.wdHelpAbout;
ThisApplication.Help(ref value);
}
Move: Moves the application's main window based on the required Left and Top arguments, which are both Integer values
Resize: Resizes the application's main window based on the required arguments Width and Height (in points). This example moves the application to the uppermost left corner of the screen and sizes it too:
' Visual BasicFriend Sub MoveAndResizeWindow() ' None of this will work if the window is maximized ' or minimized. ThisApplication.ActiveWindow.WindowState = _ Word.WdWindowState.wdWindowStateNormal
' Position at upper left corner. ThisApplication.Move(0, 0) ' Size to 300 x 600 points. ThisApplication.Resize(300, 600)End Sub
// C# public void MoveAndResizeWindow() { // None of this will work if the window is // maximized or minimized. ThisApplication.ActiveWindow.WindowState = Word.WdWindowState.wdWindowStateNormal;
// Position at upper left corner. ThisApplication.Move(0, 0); // Size to 300 x 600 points. ThisApplication.Resize(300, 600);}
Quit: Quits Word. You can optionally save any open documents, passing a value from the WdSaveOptions enumeration: wdSaveChanges , wdPromptToSaveChanges , and wdDoNotSaveChanges . The following fragment shows all three different ways to quit Word:
' Visual Basic' Automatically save changes. ThisApplication.Quit(Word.WdSaveOptions.wdSaveChanges)
' Prompt to save changes. ThisApplication.Quit(Word.WdSaveOptions.wdPromptToSaveChanges)
' Quit without saving changes. ThisApplication.Quit(Word.WdSaveOptions.wdDoNotSaveChanges)
// C# // Automatically save changes. Object saveChanges = Word.WdSaveOptions.wdSaveChanges; Object originalFormat = Type.Missing; Object routeDocument = Type.Missing; ThisApplication.Quit(ref saveChanges, ref originalFormat, ref routeDocument);
// Prompt to save changes. saveChanges = Word.WdSaveOptions.wdPromptToSaveChanges; originalFormat = Type.Missing; routeDocument = Type.Missing; ThisApplication.Quit(ref saveChanges, ref originalFormat, ref routeDocument);
// Quit without saving changes. saveChanges = Word.WdSaveOptions.wdDoNotSaveChanges; originalFormat = Type.Missing; routeDocument = Type.Missing; ThisApplication.Quit(ref saveChanges, ref originalFormat, ref routeDocument);
> Tip The Application.Quit method adds to the list of methods that require special handing in C#. In this case, the method requires three parameters, each passed by reference.
SendFax: Launches the Fax Wizard, as shown in Figure 8 . The user can then step through the Wizard to complete the operation.
' Visual BasicFriend Sub LaunchFaxWizard() ThisApplication.SendFax() End Sub
// C# public void LaunchFaxWizard() { ThisApplication.SendFax(); }

Figure 8. The Fax Wizard can be launched by the SendFax method.
Using the Built-In Dialog Boxes in Word
When working with Word, there are times when you need to display dialog boxes for user input. Although you can create your own, you might also want to take the approach of using the built-in dialog boxes in Word, which are exposed in the Application object's Dialogs collection. This allows you to access over 200 of the built-in dialog boxes in Word, represented as values in the WdWordDialog enumeration. To use a Dialog object in your code, declare it as a Word.Dialog :
' Visual Basic
Dim dlg As Word.Dialog
// C#
Word.Dialog dlg;
To specify the Word dialog you're interested in, assign the variable to one of the values returned from the array of available dialogs:
' Visual Basic
dlg = ThisApplication.Dialogs(Word.WdWordDialog.wdDialogFileNew)
// C#
Dlg = ThisApplication.Dialogs[Word.WdWordDialog.wdDialogFileNew];
Once you've created the Dialog variable, you can make use of its methods. The Show method displays the dialog box as though the user had selected it manually from the Word menus. The following procedure displays the File New dialog box:
' Visual Basic
Friend Sub DisplayFileNewDialog()
Dim dlg As Word.Dialog
dlg = ThisApplication.Dialogs( _
Word.WdWordDialog.wdDialogFileNew)
dlg.Show()
End Sub
// C#
public void DisplayFileNewDialog()
{
Object timeOut = Type.Missing;
Word.Dialog dlg;
dlg = ThisApplication.Dialogs[Word.WdWordDialog.wdDialogFileNew];
dlg.Show(ref timeOut);
}
> Tip The Show method allows you to specify a TimeOut parameter, indicating the number of milliseconds to wait before automatically closing the dialog box. In Visual Basic .NET, you can ignore the parameter. In C#, pass Type.Missing by reference to indicate the default value—no timeout at all.
Another good use for the Word dialogs is to spell check a document. The following procedure launches the spell checker for the active document with the wdDialogToolsSpellingAndGrammar enumeration:
' Visual Basic
Friend Sub DisplaySpellCheckDialog()
Dim dlg As Word.Dialog
dlg = ThisApplication.Dialogs( _
Word.WdWordDialog.wdDialogToolsSpellingAndGrammar)
dlg.Show()
End Sub
// C#
public void DisplaySpellCheckDialog()
{
Object timeOut = Type.Missing;
Word.Dialog dlg;
dlg = ThisApplication.Dialogs
[Word.WdWordDialog.wdDialogToolsSpellingAndGrammar];
dlg.Show(ref timeOut);
}
Word.Dialog Methods
In addition to the Show method, there are three additional methods that you can use with Word dialog boxes: Display , Update, and Execute :
Display: Displays the specified built-in Word dialog box until either the user closes it or the specified amount of time has passed. It does not execute any of the actions that the dialog box normally would. You can also specify an optional timeout value. The code in the following procedure uses the Display method, supplying an optional Timeout value that will display the UserInfo dialog box for approximately three seconds. If the user does not dismiss the dialog, it will automatically close:
' Visual BasicFriend Sub DisplayUserInfoDialog() Dim dlg As Word.Dialog dlg = ThisApplication.Dialogs( _ Word.WdWordDialog.wdDialogToolsOptionsUserInfo) dlg.Display(3000) End Sub
// C# public void DisplayUserInfoDialog() { Word.Dialog dlg; Object timeout = 3000; dlg = ThisApplication.Dialogs[ Word.WdWordDialog.wdDialogToolsOptionsUserInfo]; dlg.Display(ref timeout); }
> Tip Although it's tempting for C# developers to attempt to pass literal parameters as simple parameters, doing so will make your code not compile. Instead, C# developers must create an Object variable, place the literal value into the variable, and pass the variable by reference.
If you care about which button the user chooses in dismissing a dialog box, you can return the result of the Display method in an Integer variable so that you can branch in your code depending on the button selected. For example, a user might have edited the name of the user in the UserInfo dialog box. If the user clicks the OK button, they expect their changes to be saved, and if they click the Cancel button, they expect any edits to be abandoned.
' Visual Basic
Dim returnValue As Integer = dlg.Display()
// C#
Integer returnValue = dlg.Display();
The possible return values are displayed in Table 1 :
Table 1. Command button return values
| Value | Button Clicked |
|---|---|
| -2 | The Close button |
| -1 | The OK button |
| 0 (zero) | The Cancel button |
| > 0 (zero) | A command button: 1 is the first button, 2 is the second button, and so on. |
Unless you take explicit action to save changes made in this dialog box, it doesn't matter which button the user selects; all changes will be thrown away. You need to use the Execute method to explicitly apply changes within the dialog box.
Execute: If you simply call the Display method and the user changes values in the dialog box, those changes won't be applied. You need to use the Execute method after the Display method to explicitly apply any changes the user made. Unlike the Save method that saves user changes, all changes will be discarded even if the user clicks OK. The following code calls the UserInfo dialog box using Display , and then the code checks the return value of the Integer variable. If the user clicked the OK button (returning a value of -1), the code uses the Execute method to apply the changes:
' Visual BasicFriend Sub DisplayExecuteDialog() Dim dlg As Word.Dialog dlg = ThisApplication.Dialogs( _ Word.WdWordDialog.wdDialogToolsOptionsUserInfo) ' Wait 10 seconds for results. Dim int As Integer = dlg.Display(10000) ' Did the user press OK? If int = -1 Then dlg.Execute() End If End Sub
// C# public void DisplayExecuteDialog() { Word.Dialog dlg; dlg = ThisApplication.Dialogs[ Word.WdWordDialog.wdDialogToolsOptionsUserInfo];
// Wait 10 seconds for results. Object timeout = 10000; int value = dlg.Display(ref timeout); // Did the user press OK? if (value == -1) { dlg.Execute(); }}
> Tip You can retrieve the Name value entered in the UserInfo dialog box using the ThisApplication.UserName property.
- Update: Use the Update method when you want to ensure that the dialog box is displaying the correct values. Because you can modify the contents of the dialog box using code, even after you've retrieved a reference to the dialog box, you may need to update the contents of the dialog box before displaying it. (See the next section for information on using the Word dialog boxes in hidden mode—that's when you would need this method.)
Modifying Dialog Values
Because of the way the Word dialog boxes have been designed, all the properties of the various dialogs that correspond to values of controls on the forms are available only at run time. That is, when Word loads the dialog box, it creates the various properties and adds them at run time to the appropriate objects. This type of scenario makes it difficult for developers working in a strongly typed world (as in C#, and in Visual Basic .NET with Option Strict set to On ) to write code that compiles.
For example, the Page Setup dialog box (represented by the WdWordDialog.wdDialogFilePageSetup enumeration) provides a number of properties dealing with page setup, including PageWidth , PageHeight , and so on. You'd like to be able to write code like the following to access these properties:
' Visual Basic
Dim dlg As Word.Dialog
dlg = ThisApplication.Dialogs( _
Word.WdWordDialog.wdDialogFilePageSetup)
dlg.PageWidth = 3.3
dlg.PageHeight = 6.6
Unfortunately, this code simply won't compile in Visual Basic .NET with Option Strict set On , or in C# at all—the PageWidth and PageHeight properties aren't defined for the Dialog object until run time.
You have two options for working with these properties: you can either create a Visual Basic file that includes the Option Strict Off setting at the top, or you can find a way to perform late binding. (You could, of course, work through the intricacies of using the System.Reflection namespace to perform the late binding yourself—that's what Visual Basic .NET does when you turn Option Strict off, under the covers.) The CallByName method, provided by the Microsoft.VisualBasic assembly, allows you to specify the name of the property with which you want to interact, as a string, along with the value for the property and the action you'd like to take. You can use this method whether you're a Visual Basic .NET or a C# developer. C# developers will, of course, need to add a reference to the Microsoft.VisualBasic assembly in order to take advantage of this technique.
Once you've referenced the assembly, you can add code like the following:
' Visual Basic
dlg = ThisApplication.Dialogs( _
Word.WdWordDialog.wdDialogFilePageSetup)
CallByName(dlg, "PageWidth", CallType.Let, 3.3)
CallByName(dlg, "PageHeight", CallType.Let, 6)
// C#
using VB = Microsoft.VisualBasic;
// Then, within some procedure:
dlg = ThisApplication.Dialogs
[Word.WdWordDialog.wdDialogFilePageSetup];
VB.Interaction.CallByName(dlg, "PageWidth",
VB.CallType.Let, 3.3);
VB.Interaction.CallByName(dlg, "PageHeight",
VB.CallType.Let, 6);
It's not a perfect solution—the code is tricky to read and write, and requires C# developers to use methods from Visual Basic (which may seem too draconian a solution, in any case), but it does provide a simple way to work with an otherwise unavailable set of properties.
The sample project includes the following procedure, which modifies the page settings for the current document, using the Page Setup dialog box. Note that this code uses the Execute method of the Dialog class, and never actually displays the dialog box—this is perfectly valid behavior, and this technique provides a simple way to set a large number of properties in one place without requiring you to dig around into multiple objects:
' Visual Basic
using VB = Microsoft.VisualBasic;
Public Sub HiddenPageSetupDialog()
Dim dlg As Word.Dialog
dlg = ThisApplication.Dialogs( _
Word.WdWordDialog.wdDialogFilePageSetup)
CallByName(dlg, "PageWidth", CallType.Let, ConvertToInches(3.3))
CallByName(dlg, "PageHeight", CallType.Let, ConvertToInches(6))
CallByName(dlg, "TopMargin", CallType.Let, ConvertToInches(0.72))
CallByName(dlg, "BottomMargin", CallType.Let, _
ConvertToInches(0.72))
CallByName(dlg, "LeftMargin", CallType.Let, _
ConvertToInches(0.66))
CallByName(dlg, "RightMargin", CallType.Let, _
ConvertToInches(0.66))
CallByName(dlg, "Orientation", CallType.Let, _
Word.WdOrientation.wdOrientPortrait)
CallByName(dlg, "DifferentFirstPage", CallType.Let, False)
CallByName(dlg, "HeaderDistance", CallType.Let, _
ConvertToInches(0.28))
' Use the ApplyPropsTo property to determine where
' the property settings are applied:
' 0=This Section
' 1=This Point Forward
' 2=Selected Sections
' 3=Selected Text
' 4=Whole Document
CallByName(dlg, "ApplyPropsTo", CallType.Let, 0)
dlg.Execute()
End Sub
Private Function ConvertToInches(ByVal value As Double) As String
Return String.Format("{0}""", value)
End Function
// C#
public void HiddenPageSetupDialog()
{
Word.Dialog dlg;
dlg = ThisApplication.Dialogs[
Word.WdWordDialog.wdDialogFilePageSetup];
VB.Interaction.CallByName(dlg, "PageWidth", VB.CallType.Let,
ConvertToInches(3.3));
VB.Interaction.CallByName(dlg, "PageHeight", VB.CallType.Let,
ConvertToInches(6));
VB.Interaction.CallByName(dlg, "TopMargin", VB.CallType.Let,
ConvertToInches(0.72));
VB.Interaction.CallByName(dlg, "BottomMargin", VB.CallType.Let,
ConvertToInches(0.72));
VB.Interaction.CallByName(dlg, "LeftMargin", VB.CallType.Let,
ConvertToInches(0.66));
VB.Interaction.CallByName(dlg, "RightMargin", VB.CallType.Let,
ConvertToInches(0.66));
VB.Interaction.CallByName(dlg, "Orientation", VB.CallType.Let,
Word.WdOrientation.wdOrientPortrait);
VB.Interaction.CallByName(dlg, "DifferentFirstPage",
VB.CallType.Let, false);
VB.Interaction.CallByName(dlg, "HeaderDistance", VB.CallType.Let,
ConvertToInches(0.28));
// Use the ApplyPropsTo property to determine where
// the property settings are applied:
// 0=This Section
// 1=This Point Forward
// 2=Selected Sections
// 3=Selected Text
// 4=Whole Document
VB.Interaction.CallByName(dlg, "ApplyPropsTo", VB.CallType.Let,
0);
dlg.Execute();
}
private String ConvertToInches(double value)
{
return String.Format("{0}\"", value);
}
> Tip The use of measurements in Word can be confusing at times. Most measurements in Word contain values in points (1/72"), but you can always override the units by passing a string, like "3"" to indicate three inches. The sample includes the ConvertToInches method, which handles tacking on the necessary quote mark. The odd thing is that the PageWidth and PageHeight properties use the default units set by the user, whereas the other properties in this example require either points or a string containing a value with the unit indicator. The call to ConvertToInches is therefore unnecessary, in countries that use inches by default, for the first two properties in the example. Calling the method can't hurt, however.
When deciding whether or not to use the built-in dialog boxes, consider the amount of work that you are doing. If you are only setting a couple of properties in a single object, you're probably better off simply working with that object. If you need to display an interface for your users to interact with, your best bet is to use the corresponding dialog box. Consult the Word Help file for information on using the other Word built-in dialog boxes.
> Tip If you want to make full use of the Word Dialog object, you'll need to look deeper than the included Word help file. This file barely touches on the huge set of dialog boxes provided by Word. To find more information, you'll need the WordBasic help file, from Word 95. You can find this help file on www.microsoft.com . Search for "Word 95 WordBasic Help File" to locate the correct page.
The Document Object
The bulk of your programming activity in Word will involve the Document object or its contents. When you work with a particular document in Word, it is known as the active document, and can be referenced by the Application object's ActiveDocument property. All Word Document objects are also members of the Application object's Documents collection, which consists of all open documents. Using the Document object allows you to work with a single document, and the Documents collection allows you to work with all open documents. The Application and Document classes share many members as it is possible to perform document operations at both the Application and Document levels.
Some common tasks you can perform involving documents include:
- Creating and opening documents
- Adding, searching and replacing text
- Printing
Document Object Collections
A document consists of characters arranged into words, with words structured into sentences. Sentences are arranged into paragraphs, which can, in turn, be arranged inside of sections. Each section contains its own headers and footers. The Document object has collections that map to these constructs:
- Characters
- Words
- Sentences
- Paragraphs
- Sections
- Headers/Footers
Referencing Documents
You can refer to a Document object as a member of the Documents collection by using its index value. The index value is the Document object's location in the Documents collection, which is a 1-based collection (like all the collections within Word). The following code fragment sets an object variable to refer to the first Document object in the Documents collection:
' Visual Basic
Dim doc As Word.Document = _
DirectCast(ThisApplication.Documents(1), Word.Document)
// C#
Word.Document doc = (Word.Document) ThisApplication.Documents[1];
You can also reference a document by its name, which is usually a better choice if you want to work with a specific document. You will rarely refer to a document by using its index value in the Documents collection because this value can change for a given document as other documents are opened and closed. The following code fragment sets an object variable to point to the named document, "MyDoc.doc":
' Visual Basic
Dim doc As Word.Document = _
DirectCast(ThisApplication.Documents("MyDoc.doc"), Word.Document)
// C#
Word.Document doc =
(Word.Document) ThisApplication.Documents["MyDoc.doc"];
If you want to refer to the active document (the document that has the focus), you can use the ActiveDocument property of the Application object. You already have the property created for you in the Visual Studio .NET project, so your code will be more efficient if you use the ThisDocument reference when you need to refer to the document that has the focus. The following code fragment retrieves the name of the active document:
' Visual Basic
Dim str As String = ThisDocument.Name
// C#
String str = ThisDocument.Name;
Opening, Closing, and Creating New Documents
The reference to the ThisDocument object in your Word project gives you access to all members of the Document object, allowing you to work with its methods and properties, as applied to the active document. The first step in working with the Document object is to open an existing Word document or to create a new one.
Creating a New Word Document
When you create a new Word document, you add it to the Application's Documents collection of open Word documents. Consequently, the Add method creates a new Word document. This is the same as clicking on the New Blank Document button on the toolbar.
' Visual Basic
' Create a new document based on Normal.dot.
ThisApplication.Documents.Add()
// C#
// Create a new document based on Normal.dot.
Object template = Type.Missing;
Object newTemplate = Type.Missing;
Object documentType = Type.Missing;
Object visible = Type.Missing;
ThisApplication.Documents.Add(
ref template, ref newTemplate, ref documentType, ref visible);
> Tip The Documents.Add method accepts up to four optional parameters, indicating the template name, a new template name, the document type, and the visibility of the new document. In C#, you must pass Type.Missing by reference for each of these optional parameters in order to take advan