Smart Documents Development Overview

 

Paul Cornell
Microsoft Corporation

April 2003

Note   Updated November 14, 2003.

Applies to:
   Microsoft® Office Word 2003
   Microsoft Office Excel 2003

Summary: Learn how to create customized, context-sensitive task panes that interact with XML-based files in Microsoft Office Word 2003 and Microsoft Office Excel 2003. (47 printed pages)

Download odc_smartdocovw.exe.

Contents

What Are Smart Documents?
Basic Smart Document Terminology
Smart Document Development Approaches
Understanding the Smart Document Object Model
Walkthrough: Build and Run a Smart Document DLL
Creating and Using XML Expansion Pack Manifests
Microsoft Office Smart Tag List (MOSTL) Files for Smart Documents

What Are Smart Documents?

Smart documents are documents in Microsoft Word 2003 with XML or workbooks in Microsoft Excel 2003 with XML that are programmed to know what users need to do with them and give users help along the way. At its simplest level, you could provide context-sensitive help for an expense report in Excel or an employee review form in Word to assist users in filling out the form or report. You could enhance the solution by integrating controls such as list boxes, check boxes, and option buttons to restrict users to selecting only from predetermined values, thereby reducing data entry errors. You could provide links to more information on external Web sites, and even integrate data workflow processes, update value choices from external data sources, and so on.

To build on this example, let's imagine an employee routinely fills out an expense report but then follows a lot of time-consuming manual steps to actually get reimbursed for the expenses. For instance, the report may need to be routed for approval before the accounting department reimburses the expense. However, the reports are routinely sent back to the employee because certain expense details were not provided correctly. A smart document developer could solve this problem by creating a smart document in Excel that automates and tracks the expense approval and reimbursement process. The form makes sure all necessary information is entered into the expense report spreadsheet before displaying a button that allows the user to submit the expense report for approval. The form could then access information in a database that specifies who can approve the form and routes it behind the scenes to the appropriate people. After the form has been approved, only then is it submitted to the accounting department. And all this logic is contained in the form itself, so that at any time the expense report knows whether it is completed, approved, perhaps even paid to the employee.

Another example is a law firm that creates and manages contracts. When creating a new contract with smart document logic attached, the new document is organized and formatted as is standard for the type of contract the user is creating. Document fragments in the smart document allow users to easily insert boilerplate text into the contract at a click of the button. For centralized management, these document fragments can reside in an external database, an external XML document, or the text can be generated dynamically. This is in contrast to AutoText entries, which need to be updated on each user's individual computer every time a change in wording is required.

Smart documents, in addition to making document and workbook creation easier, are flexible in terms of technology as well. Smart document code can be written in Microsoft Visual Basic® 6.0, Microsoft Visual Basic .NET, Microsoft C#® .NET, or Microsoft Visual C++®. Smart documents can be deployed over a corporate intranet, over the Internet, using XML Web services, or through Web sites based on SharePointTM Team Services from Microsoft.

Note  You cannot use Office Visual Basic for Applications (VBA) to create smart document solutions.

Another interesting aspect to smart document solutions is in their deployment. As part of a typical Office solution, you may require end users to run .msi files, run regsvr32.exe on COM add-in DLLs, or other similar deployment steps. With Office 2003, users can interact with Word 2003 and Excel 2003 user interface components to quickly reference and load a smart document solution's component files, while at the same time respecting the user's Office security settings. The solution developer sets this up through the use of an XML expansion pack, which are discussed later in this article.

Basic Smart Document Terminology

Before you begin developing smart document solutions, there are a number of key terms that you should be familiar with. Additional terms will be presented throughout the rest of this article.

  • An action handler is a dynamic-link library (DLL) that implements the smart document programmatic object model or application programming interface (API).
  • The Document Actions task pane is an Office task pane that displays smart document actions and help content.
  • An XML expansion pack manifest file is an XML file that that specifies the identity and location of component files that are necessary to fully enable a specific smart document solution.
  • A solution is a generic term that describes a smart document and any of the smart document's supporting files.
  • A solution ID uniquely identifies a particular solution. Although not required, practically speaking, this should be a globally unique identifier (GUID).
  • A solution URL is the location of a solution's XML expansion pack manifest file.
  • Controls are a user interface component displayed in the Document Actions task pane, such as command buttons, hyperlinks, text boxes, and so on.

Smart Document Development Approaches

Although you can create a smart document solution as a DLL, you can also create a smart document solution as an XML file using an XML editor such as Microsoft Notepad or Word 2003. Note that a smart document XML file is limited to static text, hyperlinks, document fragments, and images; more information about smart document XML files is provided at the end of this article.

No matter which of the two approaches you take, the smart document development cycle is straightforward:

  1. Attach an XML schema to a document and associate XML elements with the portions of the document or workbook that will have smart document actions or help content associated with them.
  2. Use the smart document API or the smart document XML file schema to write code or XML that displays controls in the Document Actions task pane and takes action when the user interacts with the controls.
  3. Store the smart document code and all of the files used by the smart document on a file server or a Web server that your users can access.
  4. Create an XML expansion pack manifest file that references all of the files used by the smart document solution.
  5. Use the user interface to reference the XML expansion pack manifest file and attach the solution to the document or workbook.
  6. Distribute the document or workbook as a template. When a user creates an instance of the document or workbook from the template, the smart document and any supporting files used by the smart document are downloaded and registered locally on the user's computer without any user intervention.

Understanding the Smart Document Object Model

Now that you understand some of the basic smart document terms and you understand the smart document development cycle, it's time to explore the smart document programmatic object model that you can automate through code. (Since developing smart document solutions with XML files involves a subset of the smart document object model, I'll leave the creation of smart document XML files to the end of this article.)

Referencing the Smart Document Object Model

To develop a smart document DLL using the smart document object model, you'll need to first reference the smart document type library. In a default installation of Office 2003, the type library is located at C:\Program Files\Common Files\Microsoft Shared\Smart Tag\MSTAG.TLB. The display name for this type library is the Microsoft Smart Tags 2.0 Type Library, and the type library's programmatic ID (progID) is SmartTagLib. The smart document object model is similar to the smart tag programmatic object model, so that's why the smart document object model lives inside of the smart tags type library.

Once you set a reference to the Microsoft Smart Tags 2.0 Type Library, you write code to implement the 8 properties and 17 methods of the ISmartDocument interface. More on how to do implement the ISmartDocument interface is provided later in this article.

Smart Document Type Names

Smart document solutions use smart document type names to associate XML elements with smart document actions. Understanding how smart document type names are created is critical in developing smart document solutions.

XML namespaces guarantee that the elements in an XML file have unique names. Examples of XML namespaces are https://schemas.microsoft.com/office/smarttags/2003/mostl, http://www.w3.org/1999/XSL/Transform, https://schemas.microsoft.com/office/word/2003/wordml, and so on. To identify specific XML elements in files to smart documents, you refer to XML elements programmatically by their unique smart document type names. Simply put, a smart document type name consists of a namespace, followed by the "pound" character (#), followed by the unique XML element name. For example, the smart document type name for the caption element in the https://schemas.microsoft.com/office/smarttags/2003/mostl namespace would be https://schemas.microsoft.com/office/smarttags/2003/mostl\#caption. It's important to know how to create smart document type names as they are referenced quite frequently in smart document solution code. You'll sometimes see smart document type names referred to as namespace#element names to enforce this relationship.

As you create namespace#element names in smart document solution code, the smart document object model assigns a unique number to each namespace#element name. This number is known as the smart document type ID or namespace#element ID. Just remember for now that to automate the smart document object model, every XML element must have a unique namespace#element name and a unique namespace#element ID.

You can also use the reserved #element name of #actionPertainsToEntireSchema to specify a smart document type that pertains to the entire schema rather than an individual element; for example, https://schemas.microsoft.com/office/smarttags/2003/mostl\# actionPertainsToEntireSchema.

Control Indexes and Control IDs

When you write code that automates the smart document object model, you'll be creating controls to display in the Document Actions task pane and associating these controls with namespace#element names. For each control, you must assign a unique control ID. When your smart document solution code runs, it uses the combination of namespace#element names and unique control IDs to determine which controls to display in the Document Actions task pane, as well as what the initial state of the controls should be and what happens when users interact with the controls.

By default, the smart document object model assigns a non-unique control index number to each control associated with a namespace#element name. While the control index number is unique for each control for each namespace#element name, the control index number is not unique across all of the controls in the smart document solution, as you'll see in the following table:

Smart document type name (namespace#element name) Control index number
https://schemas.microsoft.com/office/smarttags/2003/mostl#caption 1
  2
  3
https://schemas.microsoft.com/office/smarttags/2003/mostl#action 1
  2

So, in this example, if you ask the smart document object model to display a control with the control index number of 2, how would it know which of the controls to display? Even though the smart document object model assigned the control index numbers, it can't distinguish between the two controls with the index number of 2 at run time. The answer in practice is for you to programmatically assign every control in the smart document solution a unique control ID based on some increment of the control's index number. For example, you could increment the control's default index number by 100 for all of the controls belonging to the https://schemas.microsoft.com/office/smarttags/2003/mostl\#caption smart document type name and increment the control's default index number by 200 for all of the controls belonging to the https://schemas.microsoft.com/office/smarttags/2003/mostl\#action smart document type name. This coding technique guarantees that every control in the smart document solution has a unique control ID number. In this example, this technique would result in the following unique control IDs:

Smart document type name (namespace#element name) Unique control ID number
https://schemas.microsoft.com/office/smarttags/2003/mostl#caption 101
  102
  103
https://schemas.microsoft.com/office/smarttags/2003/mostl#action 201
  202

You'll see how to do assign unique control ID numbers later in this article.

Smart Document Object Model Members

Now that you know how to reference the smart document object model, how to work with namespace#element names, and how control indexes and control IDs are handled, you can understand how each of the properties and methods in the smart document object model works.

The following table lists the smart document object model's properties and methods in alphabetical order.

Member name (property type) Description
ControlCaptionFromID property (String) Given the specific control's unique ID number, specifies the control's caption (if allowed) in the Document Actions task pane. For image controls, the caption is displayed only if the image cannot be loaded.
ControlCount property (Long) Given a unique namespace#element name, specifies the total number of controls assigned to the namespace#element name.
ControlID property (Long) Given a unique namespace#element name, returns an index number that is used to ID controls associated with the namespace#element name. As you programmatically add controls to a unique namespace#element name, the system defaults control ID numbering at one (1) and increments control ID numbers by one (1). Control index numbering is reset for each unique namespace#element name. You should add a "buffer" (such as ControlIndex + 100) to the default control index number to ensure that all controls have unique controls IDs in the smart document solution.
ControlNameFromID property (String) Given a specific control's unique ID number, specifies the control's unique friendly name. This friendly name can be used from Word and Excel application object model code.
ControlTypeFromID property (C_TYPE) Given the specific control's unique ID number, specifies the control's type (button, image, text box, and so on) as specified by a C_TYPE constant (see below).
ImageClick method Called when an image control is clicked.
InvokeControl method Called when a hyperlink is clicked, a command button control is clicked, or, in Word only, a document fragment is clicked.
OnCheckboxChange method Called when a specific check box control is selected or cleared.
OnListOrComboSelectChange method Called when a selection is made in a specific list box control or combo box control.
OnPaneUpdateComplete method Called when the Document Actions task pane has been filled with controls and all of the controls in the task pane have been initialized.
OnRadioGroupSelectChange method Called when a selection is made in a specific option button group.
OnTextboxContentChange method Called when text changes in a specific text box.
PopulateActiveXProps method Specifies the initial properties of an ActiveX® control displayed in the Document Actions task pane.
PopulateCheckbox method Specifies whether a specific check box control should be initially selected or cleared.
PopulateDocumentFragment method Specifies the initial contents of a document fragment.
PopulateHelpContent method Specifies the initial contents of XHMTL-formatted content.
PopulateImage method Determines a specific image control's initial image.
PopulateListOrComboContent method Specifies the initial list of items for a specific list box control or combo box control.
PopulateOther method Specifies the initial properties of a control that does not have a specific Populate… method already available, such as buttons, labels, links, and separators.
PopulateRadioGroup method Specifies the initial list of options for an option button group.
PopulateTextboxContent method Specifies the initial text for a specific text box control.
SmartDocInitialize method Called when a smart document is attached to, or loaded by, a document or workbook.
SmartDocXMLTypeCaption property (String) Given a namespace#element name, specifies the caption at the top of the Document Actions task pane when the corresponding XML element is selected in a document or workbook is clicked.
SmartDocXMLTypeCount property (Long) Specifies how many namespace#element names in the document or workbook have controls assigned to them. Each namespace#element name is assigned a unique ID number by the smart document object model. ID numbers start at one (1) and are incremented by one (1) by the object model.
SmartDocXMLTypeName property (String) Associates a unique namespace#element name with a unique ordinal number assigned by the smart document object model.

Input Parameters

Some of the smart document object model's properties and methods accept one or more input parameters. Since many of these input parameters are repeated in several properties and methods, the following table lists all of the input parameters in alphabetical order.

Input parameter name (input type) Description
ActiveXPropBag (ISmartDocProperties) A collection of ActiveX control properties.
ApplicationName (String) The application hosting the smart document solution.
Checked (Boolean) True if a check box control is selected and False if a check box control is cleared. The default value is False.
Content (String) A string of text representing help content. The string must be formatted as XHTML (for a help control) or a URL pointing to an XHTML file (for a help URL control).
ControlID (Long) A specific control's unique ID number.
ControlIndex (Long) A specific control's unique index number for a given control type. For a given control type, the first control is assigned number 1, the second control is assigned number 2, and so on.
Count (Long) The number of items in a list box control, combo box control, or option button group.
Document (Object) Represents an instance of the smart document.
DocumentFragment (String) Represents an XML string (for a document fragment control) or a path to an XML file (for a document fragment URL control).
ImageSrc (String) The path to the desired image file.
InitialSelected (Long) An ordinal number specifying which item is selected in a list box control, a combo box control, or an option button group. A number of -1 indicates that no item is initially selected.
List (array of String) A list of text strings to display in a list box control, combo box control, or option button group.
LocaleID (Long) Represents the numerical equivalent of a language. For example, 1033 represents the English language. In practice, you could use a Select Case construct to specify different behaviors for controls based on the user's target language.
Props (ISmartDocProperties) A collection of customer-defined control properties.
Selected (Long) The ordinal index number of a selected item in a list box control, a combo box control, or an option button group.
SmartDocID (Long) A unique ordinal number assigned by the smart document object model to a unique namespace#element name.
SmartDocName (String) A unique namespace#element name.
SolutionPath (String) The path in which the solution's files are installed (if you installed from an XML expansion pack manifest), or the path to the smart document itself (if you didn't install from an XML expansion pack manifest).
SolutionRegKeyRoot (String) The path to the place in the registry where the XML expansion pack manifest data for the solution that installed your smart doc resides. If you didn't install from an XML expansion pack manifest, this value will be Nothing.
Target (Object) For the ISmartDocInitialize and OnPaneUpdateComplete methods, represents the current Document object. For all other members, represents a Word or Excel Range object corresponding to the appropriate element's content.
Text (String) The corresponding element's text.
Value (String) The text of a selected item in a list box control, a combo box control, an option button group, or a text box control.
XCoordinate (Long) An image control's X (horizontal) coordinate (in pixels) when the image is clicked.
Xml (String) A simple XML representation of the corresponding element's tags and its properties.
YCoordinate (Long) An image control's Y (vertical) coordinate (in pixels) when the image is clicked.

Control Type Constants

The ControlTypeFromID property associates a control type with a control ID. The control type is defined as a C_TYPE constant. The C_TYPE constant names and values are listed alphabetically in the following table.

C_TYPE constant name (value) Description
C_TYPE_ACTIVEX (13) ActiveX® control
C_TYPE_BUTTON (6) Command button
C_TYPE_CHECKBOX (9) Check box control
C_TYPE_COMBO (12) Combo box control
C_TYPE_DOCUMENTFRAGMENT (14) Document fragment
C_TYPE_DOCUMENTFRAGMENTURL (15) URL to a document fragment
C_TYPE_HELP (3) XHMTL-formatted content
C_TYPE_HELPURL (4) URL to XHMTL-formatted content
C_TYPE_IMAGE (8) Image control
C_TYPE_LABEL (7) Label control
C_TYPE_LINK (2) Hyperlink
C_TYPE_LISTBOX (11) List box control
C_TYPE_RADIOGROUP (16) Option button
C_TYPE_SEPARATOR (5) Separator (equivalent to an HTML horizontal rule <hr>)
C_TYPE_TEXTBOX (10) Text box control

Built-In Control Properties

All of the methods that begin with the word Populate accept an argument named Props. The Props argument, as well as the ActiveXPropBag argument of the PopulateActiveXProps method, represent an ISmartDocProperties collection that contains one or more property values for a particular control. You can set control properties with code similar to the following for a text box control:

Private Sub ISmartDocument_PopulateTextboxContent _
        (ByVal ControlID As Long, ByVal ApplicationName As String, _
        ByVal LocaleID As Long, ByVal Text As String, _
        ByVal Xml As String, ByVal Target As Object, _
        ByVal Props As SmartTagLib.ISmartDocProperties, _
        Value As String)
    ...
    With Props
        .Write Key:="Align", Value:="left"
        .Write Key:="FontFace", Value:="Arial"
        .Write Key:="FontWeight", Value:="bold"
        .Write Key:="NumberOfLines", Value:="2"
    End With
    ...
End Sub

The following table lists the built-in control properties that you can set:

Property name (type): applies to Description
X (String formatted as an Integer): All controls How far from the left position, in pixels, the control should be indented. Negative values are ignored.
Y (String formatted as an Integer): All controls How far below the previous control should the control, in pixels, be positioned. Negative values are ignored.
H (String formatted as an Integer): All controls The height of the control in pixels. Negative values are ignored.
W (String formatted as an Integer): All controls The width of the control in pixels. Negative values are ignored.
Align (String): All controls The value "center" causes the control to be centered from left to right in the pane; "left" causes the control to be left aligned in the pane (the default); "right" causes the control to be right aligned in the pane.
FontFace (String): Controls with text labels The font face in which to display text.
FontSize (String formatted as an Integer): Controls with text labels The font size in which to display text.
FontStyle (String): Controls with text labels The value "none" (the default) or one or more of "underline", "italic", or "strikeout."
FontWeight (String): Controls with text labels The value "normal" (the default) or "bold."
IsMultiLine (String formatted as a Boolean): Text boxes True to allow the text box to accept multiple lines of text, each line separated by a carriage return/line feed character.
NumberOfLines (String formatted as an Integer): List boxes, and combo boxes The number of lines to display in a text box or the number of lines visible without scrolling in a list box or combo box.
PasswordCharacter (String formatted as a String): Text boxes A single character that is used to obscure typing into the text box so that it can be used as a password field.
ExpandHelp (String formatted as a Boolean): Help controls, help URL controls, list boxes, and combo boxes. True to expand the help control or help URL control contents in the task pane.
Border (String formatted as a Boolean): Image controls True to display a border when the user rests their mouse pointer on the control.
IsEditable (String formatted as a Boolean): Combo boxes True to edit content in combo boxes.
ControlOnSameLine (String formatted as a Boolean): List boxes, combo boxes, text boxes True to display the control on the same line as the control's caption. The default value is False.
Expand (String formatted as a Boolean): Document fragments True to expand the document fragment's or help topic's content in the task pane.
Layout (String): All controls The value "LTR" specifies left-to-right reading order layout, while the value "RTL" specifies right-to-left reading order layout.
SectionCaptionDirection (String): All controls The value "LTR" specifies left-to-right reading order section control, while the value "RTL" specifies right-to-left reading order section control.
ExpandToFill (String formatted as Boolean): ActiveX controls A Boolean value that specifies whether to expand the ActiveX control to fill the task pane. Do not use ExpandToFill with controls that do not pertain to the entire document.
KeepAlive (String formatted as Boolean): ActiveX controls A Boolean value that specifies whether the control remains active even if the context of the control changes. Although the control is kept active as long as possible, it is not guaranteed to be active when the task pane is redrawn. Do not use KeepAlive with ActiveX controls that do not pertain to the entire document.

Order of Events

When a smart document solution is attached to a document or workbook, or a document or workbook with an attached smart document solution is opened, the following takes place in the smart document DLL.

  1. The SmartDocInitialize method is called. The smart document solution developer can specify any initialization code to run when the smart document first loads.
  2. The SmartDocXmlTypeCount property determines how many namespace#element names have controls assigned to them.
  3. The SmartDocXmlTypeName property assigns namespace#element names to namespace#element IDs.
  4. The SmartDocXmlTypeCaption property determines the text that will appear at the top of the Document Actions task pane when a specific XML element is clicked in the document or workbook.
  5. The ControlCount property specifies how many controls are available to each namespace#element name.
  6. The ControlID property assigns a unique ID number for each control in the smart document solution.
  7. The ControlNameFromID property assigns a unique name to each control so that it can be referenced from the Word or Excel application object model if needed later.
  8. The ControlCaptionFromID property assigns a caption to each control, if one is allowed for the particular control.
  9. The ControlTypeFromID property determines each control's type, such as whether it is a text box control, a list box control, an image control, and so on.
  10. As the smart document object model adds controls to the Document Actions task pane, the controls' specific initialization methods are called such as PopulateActiveXProps, PopulateCheckbox, PopulateDocumentFragment, PopulateHelpContent, PopulateImage, PopulateListBoxOrComboContent, PopulateOther, PopulateRadioGroup, or PopulateTextboxContent.
  11. The OnPaneUpdateComplete method is called after all of the controls have been added to the Document Actions task pane and all of the controls have been initialized.
  12. As the user interacts with the controls in the Document Actions task pane, the smart document object model calls the controls' specific action methods such as ImageClick, InvokeControl, OnCheckboxChange, OnListOrComboSelectChange, OnRadioGroupSelectChange, or OnTextBoxContentChange.
  13. The following sections provide more details on each step in the process.

SmartDocInitialize Method

You use the SmartDocInitialize method to specify any initialization code to run when the smart document first loads. The Document input parameter can be used to work with the active document programmatically. The SolutionPath input argument provides the path in which the solution files were installed (except, of course, for those files that were installed to a special location).

SmartDocXmlTypeCount Property

You use the SmartDocXmlTypeCount property to specify how many namespace#element names have controls assigned to them. By default, the ISmartDocument interface begins assigning ID numbers at one (1) and increments ID numbers by (1) for each namespace#element name. For example, if you want to specify that three namespace#element names will have controls assigned to them, here's how the ISmartDocument interface would conceptually represent this in memory:

Smart document type ID Smart document type name
1 (not yet assigned)
2 (not yet assigned)
3 (not yet assigned)

SmartDocXmlTypeName Property

You use the SmartDocXmlTypeName property to assign namespace#element names to namespace#element IDs. In this property, you match up each namespace#element name to an ID provided earlier. For example, using the https://schemas.microsoft.com/office/smarttags/2003/mostl namespace and assigning the caption, action, and url elements to ID numbers, here's how the ISmartDocument interface would conceptually represent this in memory:

Smart document type ID Smart document type name (namespace#element name)
1 https://schemas.microsoft.com/office/smarttags/2003/mostl#caption
2 https://schemas.microsoft.com/office/smarttags/2003/mostl#action
3 https://schemas.microsoft.com/office/smarttags/2003/mostl#url

SmartDocXmlTypeCaption Property

You use the SmartDocXmlTypeCaption property to specify the text that will appear at the top of the Document Actions task pane when a specific XML element is clicked in the document or workbook. In this property, you match up namespace#element name ID numbers with text-based captions. For example, using our three namespace#element name ID numbers, here's how the ISmartDocument interface would conceptually represent this in memory:

Smart document type ID Caption
1 Specifying a caption
2 Using the action element
3 Specifying a URL

ControlCount Property

You use the ControlCount property to specify how many controls are available to each namespace#element name. In this property, you assign numbers to namespace#element names. For each number that you specify, the ISmartDocument interface automatically creates a number for the For example, if you wanted to assign one control to the caption and url elements and three controls to the action element, here's how the ISmartDocument interface would conceptually represent this in memory:

Smart document type name (namespace#element name) Number of controls Control index numbers
https://schemas.microsoft.com/office/smarttags/2003/mostl#caption 1 1
https://schemas.microsoft.com/office/smarttags/2003/mostl#action 3 1, 2, 3
https://schemas.microsoft.com/office/smarttags/2003/mostl#url 1 1
Control index numbers Control name, caption, type
1 (assigned to caption element) (not yet assigned)
1 (assigned to action element) (not yet assigned)
2 (assigned to action element) (not yet assigned)
3 (assigned to action element) (not yet assigned)
1 (assigned to url element) (not yet assigned)

ControlID Property

You use the ControlID property to specify a unique ID number for each control in the smart document solution. Each control in the smart document solution must be uniquely identifiable by a number. Notice in the previous two tables' "Control index numbers" column that the number 1 is repeated three times, and is therefore not unique. To overcome this issue, you could increment the default ControlIndex input parameter value by, say, 100 per namespace#element name, as follows:

Smart document type name Index number Resulting control IDs
https://schemas.microsoft.com/office/smarttags/2003/mostl#caption ControlIndex + 100 101
https://schemas.microsoft.com/office/smarttags/2003/mostl#action ControlIndex + 200 201, 202, 203
https://schemas.microsoft.com/office/smarttags/2003/mostl#url ControlIndex + 300 301

ControlNameFromID Property

You use the ControlNameFromID property to assign a unique name to each control so that it can be referenced from the Word or Excel application object model if needed later. In this property, you match control IDs to programmatic control alias names that you come up with, for example:

Control ID Programmatic name
101 captionHelp
201 actionHelp
202 actionLabel
203 actionOptions
301 urlHelp

ControlCaptionFromID Property

You use the ControlCaptionFromID property to specify a caption for each control, if one is allowed for the particular control. You match control IDs to control captions that you come up with, for example:

Control ID Control caption
101 Writing a compelling caption
201 Overview of actions
202 Select an action
203 Available actions
301 URL formatting guidelines

ControlTypeFromID Property

You use the ControlTypeFromID property to specify each control's type, such as whether it is a text box control, a list box control, an image control, and so on. You match control IDs to predetermined control type constants, for example:

Control ID Control type
101 C_TYPE_HELP (Help)
201 C_TYPE_HELP (Help)
202 C_TYPE_LABEL (Label control)
203 C_TYPE_RADIOGROUP (Option button group)
301 C_TYPE_HELP (Help)

Walkthrough: Build and Run a Smart Document DLL

In this example, I'll demonstrate how to build and run a smart document DLL with Microsoft Visual Basic 6.0. You can easily recode this DLL in Visual Basic .NET or C# using the techniques that I'll demonstrate here.

In this example, I'll be building a smart document DLL that works with XML documents conforming to the Microsoft Office Smart Tag List (MOSTL) schema for Office 2003 The schema's namespace is https://schemas.microsoft.com/office/smarttags/2003/mostl and defines elements such as smarttaglist, smartdoc, action, caption, url, and so on. The MOSTL schema is included in the mostl114809.xsd file in the download accompanying this article.

First, create the DLL project.

  1. Start Visual Basic 6.0 Professional or Enterprise Edition.
  2. In the New Project dialog box, on the New tab, click the ActiveX DLL icon and then click Open.
  3. On the Project menu, click References.
  4. In the Available References list of the References dialog box, select the Microsoft Smart Tags 2.0 Type Library check box and then click OK.

Next, add code to the DLL.

  1. Rename the Class1 class module to SmartDoc, and then type the following in the (General) (Declarations) section:

    Implements SmartTagLib.ISmartDocument
    

    This code instructs Visual Basic that you will be implementing the ISmartDocument interface in your DLL.

  2. In the Code window's Object list, select ISmartDocument. In the Procedure list, select ControlCaptionFromID [Property Get]. Repeat this step for all of the items in the Procedure list. There should be about 25 items in the Procedure list.

  3. In the (General) (Declarations) section, add one constant for the schema namespace URI, one constant for each namespace#element name that will have controls, one constant for the total number of namespace#element names that will have controls, and a variable to reference the active Word document. For this walkthrough, your code should look like this:

    Private Const NAMESPACE As String = _
        "https://schemas.microsoft.com/office/smarttags/2003/mostl"
    Private Const SMARTTAGLIST As String = _
        NAMESPACE & "#smarttaglist"
    Private Const SMARTDOC As String = _
        NAMESPACE & "#smartdoc"
    Private Const CAPTION_SMARTDOC As String = _
        NAMESPACE & "#caption"
    Private Const ACTION As String = _
        NAMESPACE & "#action"
    Private Const ACTIONTYPE As String = _
        NAMESPACE & "#actionType"
    Private Const HELP As String = _
        NAMESPACE & "#help"
    Private Const IMAGEURL As String = _
        NAMESPACE & "#imageurl"
    Private Const URL As String = _
        NAMESPACE & "#url"
    Private Const NUM_TYPES As Integer = 8
    Dim gobjDoc As Word.Document
    
  4. In the SmartDocXmlTypeCount property, specify the number of namespace#element names that will have associated controls, as follows:

    Private Property Get ISmartDocument_SmartDocXmlTypeCount() _
            As Long
    
        ISmartDocument_SmartDocXmlTypeCount = NUM_TYPES
    
    End Property
    
  5. In the (General) (Declarations) section, add one constant for each namespace#element name ID, as follows:

    Private Const SMARTTAGLIST_ID As Integer = 1
    Private Const SMARTDOC_ID As Integer = 2
    Private Const CAPTION_SMARTDOC_ID As Integer = 3
    Private Const ACTION_ID As Integer = 4
    Private Const ACTIONTYPE_ID As Integer = 5
    Private Const HELP_ID As Integer = 6
    Private Const IMAGEURL_ID As Integer = 7
    Private Const URL_ID As Integer = 8
    
  6. In the SmartDocXmlTypeName property, assign each namespace#element ID to a namespace#element name, as follows:

    Private Property Get ISmartDocument_SmartDocXmlTypeName _
            (ByVal SmartDocID As Long) _
            As String
    
        Select Case SmartDocID
            Case SMARTTAGLIST_ID
                ISmartDocument_SmartDocXmlTypeName = SMARTTAGLIST
            Case SMARTDOC_ID
                ISmartDocument_SmartDocXmlTypeName = SMARTDOC
            Case CAPTION_SMARTDOC_ID
                ISmartDocument_SmartDocXmlTypeName = CAPTION_SMARTDOC
            Case ACTION_ID
                ISmartDocument_SmartDocXmlTypeName = ACTION
            Case ACTIONTYPE_ID
                ISmartDocument_SmartDocXmlTypeName = ACTIONTYPE
            Case HELP_ID
                ISmartDocument_SmartDocXmlTypeName = HELP
            Case IMAGEURL_ID
                ISmartDocument_SmartDocXmlTypeName = IMAGEURL
            Case URL_ID
                ISmartDocument_SmartDocXmlTypeName = URL
            Case Else
        End Select
    
    End Property
    
  7. In the SmartDocXmlTypeCaption property, assign each namespace#element ID a task pane caption, as follows:

    Private Property Get ISmartDocument_SmartDocXmlTypeCaption _
            (ByVal SmartDocID As Long, ByVal LocaleID As Long) _
            As String
    
        Select Case SmartDocID
            Case SMARTTAGLIST_ID
                ISmartDocument_SmartDocXmlTypeCaption = _
                    "Help with the <smarttaglist> element"
            Case SMARTDOC_ID
                ISmartDocument_SmartDocXmlTypeCaption = _
                    "Help with the <smartdoc> element"
            Case CAPTION_SMARTDOC_ID
                ISmartDocument_SmartDocXmlTypeCaption = _
                    "Help with the <caption> element"
            Case ACTION_ID
                ISmartDocument_SmartDocXmlTypeCaption = _
                    "Help with the <action> element"
            Case ACTIONTYPE_ID
                ISmartDocument_SmartDocXmlTypeCaption = _
                    "Help with the <actionType> element"
            Case HELP_ID
                ISmartDocument_SmartDocXmlTypeCaption = _
                    "Help with the <help> element"
            Case IMAGEURL_ID
                ISmartDocument_SmartDocXmlTypeCaption = _
                    "Help with the <imageurl> element"
            Case URL_ID
                ISmartDocument_SmartDocXmlTypeCaption = _
                    "Help with the <url> element"
            Case Else
        End Select
    
    End Property
    
  8. In the ControlCount property, specify how many controls will be associated with each namespace#element name, as follows:

    Private Property Get ISmartDocument_ControlCount _
            (ByVal SmartDocName As String) _
            As Long
    
        Select Case SmartDocName
            Case SMARTTAGLIST
                ISmartDocument_ControlCount = 1 
            Case SMARTDOC
                ISmartDocument_ControlCount = 2
            Case CAPTION_SMARTDOC
                ISmartDocument_ControlCount = 2
            Case ACTION
                ISmartDocument_ControlCount = 1 
            Case ACTIONTYPE
                ISmartDocument_ControlCount = 1 
            Case HELP
                ISmartDocument_ControlCount = 1 
            Case IMAGEURL
                ISmartDocument_ControlCount = 1 
            Case URL
                ISmartDocument_ControlCount = 1 
            Case Else
        End Select
    
    End Property
    
  9. In the ControlID property, specify the range of control index numbers for each namespace#element name, as follows:

    Private Property Get ISmartDocument_ControlID _
            (ByVal SmartDocName As String, _
            ByVal ControlIndex As Long) _
            As Long
    
        Select Case SmartDocName
            Case SMARTTAGLIST
                ISmartDocument_ControlID = ControlIndex + 100
            Case SMARTDOC
                ISmartDocument_ControlID = ControlIndex + 200
            Case CAPTION_SMARTDOC
                ISmartDocument_ControlID = ControlIndex + 300
            Case ACTION
                ISmartDocument_ControlID = ControlIndex + 400
            Case ACTIONTYPE
                ISmartDocument_ControlID = ControlIndex + 500
            Case HELP
                ISmartDocument_ControlID = ControlIndex + 600
            Case IMAGEURL
                ISmartDocument_ControlID = ControlIndex + 700
            Case URL
                ISmartDocument_ControlID = ControlIndex + 800
            Case Else
        End Select
    
    End Property
    
  10. In the (General) (Declarations) section, add one constant for each control ID, as follows:

    Private Const SMARTTAGLIST_HELP As Integer = 101
    Private Const SMARTDOC_TEXTBOX As Integer = 201
    Private Const SMARTDOC_BUTTON As Integer = 202
    Private Const CAPTION_SMARTDOC_TEXTBOX As Integer = 301
    Private Const CAPTION_SMARTDOC_BUTTON As Integer = 302
    Private Const ACTION_COMBOBOX As Integer = 401
    Private Const ACTIONTYPE_OPTIONS As Integer = 501
    Private Const HELP_DOCFRAG As Integer = 601
    Private Const IMAGEURL_IMAGE As Integer = 701
    Private Const URL_LINK As Integer = 801
    
  11. In the ControlNameFromID property, specify the programmatic name for each control, as follows:

    Private Property Get ISmartDocument_ControlNameFromID _
            (ByVal ControlID As Long) _
            As String
    
        Select Case ControlID
            Case SMARTTAGLIST_HELP
                ISmartDocument_ControlNameFromID = _
                    SMARTTAGLIST & CStr(ControlID)
            Case SMARTDOC_TEXTBOX, SMARTDOC_BUTTON
                ISmartDocument_ControlNameFromID = _
                    SMARTDOC & CStr(ControlID)
            Case CAPTION_SMARTDOC_TEXTBOX, CAPTION_SMARTDOC_BUTTON
                ISmartDocument_ControlNameFromID = _
                    CAPTION & CStr(ControlID)
            Case ACTION_COMBOBOX
                ISmartDocument_ControlNameFromID = _
                    ACTION & CStr(ControlID)
            Case ACTIONTYPE_OPTIONS
                ISmartDocument_ControlNameFromID = _
                    ACTIONTYPE & CStr(ControlID)
            Case HELP_DOCFRAG
                ISmartDocument_ControlNameFromID = _
                    HELP & CStr(ControlID)
            Case IMAGEURL_IMAGE
                ISmartDocument_ControlNameFromID = _
                    IMAGEURL & CStr(ControlID)
            Case URL_LINK
                ISmartDocument_ControlNameFromID = _
                    URL & CStr(ControlID)
            Case Else
        End Select
    
    End Property
    
  12. In the ControlCaptionFromID property, specify each control's caption, as follows:

    Private Property Get ISmartDocument_ControlCaptionFromID _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, _
            ByVal LocaleID As Long, ByVal Text As String, _
            ByVal Xml As String, ByVal Target As Object) _
            As String
    
        Select Case ControlID
            Case SMARTTAGLIST_HELP
                ISmartDocument_ControlCaptionFromID = _
                    "Usage notes"
            Case SMARTDOC_TEXTBOX
                ISmartDocument_ControlCaptionFromID = _
                    "Type a value for the 'type' attribute"
            Case SMARTDOC_BUTTON, CAPTION_SMARTDOC_BUTTON
                ISmartDocument_ControlCaptionFromID = _
                    "Apply value to document"
            Case CAPTION_SMARTDOC_TEXTBOX
                ISmartDocument_ControlCaptionFromID = _
                    "Type a value for the 'caption' element (as " & _
                    "it applies to the 'smartDoc' element)
            Case ACTION_COMBOBOX
                ISmartDocument_ControlCaptionFromID = _
                    "Select or type a namespace#element name"
            Case ACTIONTYPE_OPTIONS
                ISmartDocument_ControlCaptionFromID = _
                    "Select an action type"
            Case HELP_DOCFRAG
                ISmartDocument_ControlCaptionFromID = _
                    "Document fragment graphical expando"
            Case IMAGEURL_IMAGE
                ISmartDocument_ControlCaptionFromID = _
                     "Microsoft Office logo"
            Case URL_LINK
                ISmartDocument_ControlCaptionFromID = _
                     "Microsoft Office Home Page"
            Case Else
        End Select
    
    End Property
    
  13. In the ControlTypeFromID property, specify each control's type, as follows:

    Private Property Get ISmartDocument_ControlTypeFromID _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, _
            ByVal LocaleID As Long) _
            As SmartTagLib.C_TYPE
    
        Select Case ControlID
            Case SMARTTAGLIST_HELP
                ISmartDocument_ControlTypeFromID = C_TYPE_HELP
            Case SMARTDOC_TEXTBOX, CAPTION_SMARTDOC_TEXTBOX
                ISmartDocument_ControlTypeFromID = C_TYPE_TEXTBOX
            Case SMARTDOC_BUTTON, CAPTION_SMARTDOC_BUTTON
                ISmartDocument_ControlTypeFromID = C_TYPE_BUTTON
            Case ACTION_COMBOBOX
                ISmartDocument_ControlTypeFromID = C_TYPE_COMBO
            Case ACTIONTYPE_OPTIONS
                ISmartDocument_ControlTypeFromID = C_TYPE_RADIOGROUP
            Case HELP_DOCFRAG
                ISmartDocument_ControlTypeFromID = _
                    C_TYPE_DOCUMENTFRAGMENT
            Case IMAGEURL_IMAGE
                ISmartDocument_ControlTypeFromID = C_TYPE_IMAGE
            Case URL_LINK
                ISmartDocument_ControlTypeFromID = C_TYPE_LINK
            Case Else
        End Select
    
    End Property
    
  14. In the PopulateDocumentFragment, PopulateHelpContent, PopulateImage, PopulateListOrComboContent, PopulateRadioGroup, and PopulateTextboxContent methods, specify the initial states of the controls, as follows:

    Private Sub ISmartDocument_PopulateDocumentFragment _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, ByVal LocaleID As Long, _
            ByVal Text As String, ByVal Xml As String, _
            ByVal Target As Object, _
            ByVal Props As SmartTagLib.ISmartDocProperties, _
            DocumentFragment As String)
    
        Select Case ControlID
            Case HELP_DOCFRAG
                DocumentFragment = "<html><body><p>Document " & _
                    "fragments look like this.</p></body></html>"
            Case Else
        End Select
    
    End Sub
    
    Private Sub ISmartDocument_PopulateHelpContent _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, ByVal LocaleID As Long, _
            ByVal Text As String, ByVal Xml As String, _
            ByVal Target As Object, _
            ByVal Props As SmartTagLib.ISmartDocProperties, _
            Content As String)
    
        Select Case ControlID
            Case SMARTTAGLIST_HELP
                Content = "<htm><body><p>It's important to fill " & _
                    "out all of the data for the " & _
                    " <b>&lt;smarttaglist&gt;</b> element properly. " & _
                    "If you don't, you could have a " & _
                    "lot of errors on your hands. For instance, " & _
                    "not following the right list of " & _
                    "elements could result in a lot of strikeout " & _
                    "symbols in the XML Source " & _
                    "task pane in Word.</p></body></html>"
            Case Else
        End Select
    
    End Sub
    
    Private Sub ISmartDocument_PopulateImage _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, ByVal LocaleID As Long, _
            ByVal Text As String, ByVal Xml As String, _
            ByVal Target As Object, _
            ByVal Props As SmartTagLib.ISmartDocProperties, _
            ImageSrc As String)
    
        Select Case ControlID
            Case IMAGEURL_IMAGE
                ImageSrc = _
                    "https://www.microsoft.com/products/shared/images/bnr_office.gif"
            Case Else
        End Select
    
    End Sub
    
    Private Sub ISmartDocument_PopulateListOrComboContent _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, ByVal LocaleID As Long, _
            ByVal Text As String, ByVal Xml As String, _
            ByVal Target As Object, _
            ByVal Props As SmartTagLib.ISmartDocProperties, _
            List() As String, Count As Long, InitialSelected As Long)
    
        Select Case ControlID
            Case ACTION_COMBOBOX
                Props.Write Key:="IsEditable", Value:="True"
                ReDim List(1 To 8) As String
                Count = 8
                List(1) = SMARTTAGLIST
                List(2) = SMARTDOC
                List(3) = CAPTION_SMARTDOC
                List(4) = ACTION
                List(5) = ACTIONTYPE
                List(6) = HELP
                List(7) = IMAGEURL
                List(8) = URL
                InitialSelected = -1
            Case Else
        End Select
    
    End Sub
    
    Private Sub ISmartDocument_PopulateRadioGroup _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, ByVal LocaleID As Long, _
            ByVal Text As String, ByVal Xml As String, _
            ByVal Target As Object, _
            ByVal Props As SmartTagLib.ISmartDocProperties, _
            List() As String, Count As Long, InitialSelected As Long)
    
        Select Case ControlID
            Case ACTIONTYPE_OPTIONS
                ReDim List(1 To 7) As String
                Count = 7
                List(1) = "Button"
                List(2) = "HelpURL"
                List(3) = "Help"
                List(4) = "Image"
                List(5) = "Label"
                List(6) = "Link"
                List(7) = "Separator"
                InitialSelected = -1
            Case Else
        End Select
    
    End Sub
    
    Private Sub ISmartDocument_PopulateTextboxContent _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, ByVal LocaleID As Long, _
            ByVal Text As String, ByVal Xml As String, _
            ByVal Target As Object, _
            ByVal Props As SmartTagLib.ISmartDocProperties, _
            Value As String)
    
        Select Case ControlID
            Case SMARTDOC_TEXTBOX, CAPTION_SMARTDOC_TEXTBOX
                Props.Write Key:="ControlOnSameLine", Value:="False"
            Case Else
        End Select
    
    End Sub
    
  15. In the InvokeControl, OnListOrComboSelectChange, and OnRadioGroupSelectChange methods, specify what happens when the user interacts with the controls, as follows:

    Private Sub ISmartDocument_InvokeControl _
            (ByVal ControlID As Long, _
            ByVal ApplicationName As String, ByVal Target As Object, _
            ByVal Text As String, ByVal Xml As String, _
            ByVal LocaleID As Long)
    
        Set objDoc = Word.Application.ActiveDocument
    
        Select Case ControlID
            Case SMARTDOC_BUTTON
                Select Case ApplicationName
                    Case "Word.Application.11"
                        Dim strText As String
                        Dim objNode As XMLNode
                        Set objNode = _
                            Word.Application.Selection.XMLParentNode
                        strText = objDoc.SmartTags.Item _
                            (Index:=SMARTDOC).SmartTagActions.Item _
                            (Index:=SMARTDOC & _
                            SMARTDOC_TEXTBOX).TextboxText
                        If objNode.Attributes.Count = 0 Then
                            objNode.Attributes.Add _
                                ("type", "").NodeValue = strText
                        Else
                            objNode.Attributes.Item _
                                (1).NodeValue = strText
                        End If
                        MsgBox _
                            Prompt:="Type attribute changed to '" & _
                                strText & "'."
                End Select
            Case CAPTION_SMARTDOC_BUTTON
                Select Case ApplicationName
                    Case "Word.Application.11"
                        Dim strText2 As String
                        Dim objNode2 As XMLNode
                        Set objNode2 = _
                            Word.Application.Selection.XMLParentNode
                        strText2 = objDoc.SmartTags.Item _
                            (Index:=CAPTION_SMARTDOC). _
                            SmartTagActions.Item _
                            (Index:=CAPTION_SMARTDOC & _
                            CAPTION_SMARTDOC_TEXTBOX). _
                            TextboxText
                        objNode2.Range.Text = strText2
                        MsgBox Prompt:="Value changed to '" & _
                            strText2 & "'."
                End Select
            Case URL_LINK
                Dim ieInternetExplorer As Variant
                Set ieInternetExplorer = _
                    CreateObject("InternetExplorer.Application")
                ieInternetExplorer.Navigate2 _
                    "https://www.microsoft.com/office"
                ieInternetExplorer.Visible = True
            Case Else
        End Select
    
    End Sub
    
    Private Sub ISmartDocument_OnListOrComboSelectChange _
            (ByVal ControlID As Long, ByVal Target As Object, _
            ByVal Selected As Long, ByVal Value As String)
    
        Select Case ControlID
            Case ACTION_COMBOBOX
                Dim objNode As XMLNode
                Set objNode = Word.Application.Selection.XMLParentNode
                If objNode.Attributes.Count = 0 Then
                    objNode.Attributes.Add("id", "").NodeValue = Value
                Else
                    objNode.Attributes.Item(1).NodeValue = Value
                End If
                MsgBox Prompt:="id attribute changed to '" & _
                    Value & "'."
            Case Else
        End Select
    
    End Sub
    
    Private Sub ISmartDocument_OnRadioGroupSelectChange _
            (ByVal ControlID As Long, ByVal Target As Object, _
            ByVal Selected As Long, ByVal Value As String)
    
        Select Case ControlID
            Case ACTIONTYPE_OPTIONS
                Dim objNode As XMLNode
                Set objNode = Word.Application.Selection.XMLParentNode
                objNode.Range.Text = Value
            Case Else
        End Select
    
    End Sub
    

Next, set debugging properties and make the DLL.

  1. On the Project menu, click Properties.
  2. Click the Debugging tab.
  3. Select the Start program option.
  4. Type or browse to the WINWORD.EXE file.
  5. Click OK.
  6. On the File menu, click Make DLL. If prompted, save the project and DLL with the name MOSTL2003.

Finally, create an XML expansion pack manifest file and run the solution.

  1. Create an XML expansion pack manifest file (see the next section), or use the MOSTL2003_manifest.xml file included in the download accompanying this article.
  2. In Visual Basic 6.0, on the Run menu, click Start. Word 2003 starts.
  3. On the Tools menu, click Templates and Add-Ins.
  4. On the XML Schema tab, click Schema Library.
  5. Click Add Schema.
  6. Locate and click the mostl114809.xsd file included in the download accompanying this article, and then click Open.
  7. Click OK twice.
  8. Select the https://schemas.microsoft.com/office/smarttags/2003/mostl check box.
  9. On the XML Expansion Packs tab, click Add.
  10. Locate and click the MOSTL2003_manifest.xml file included in the download accompanying this article, click Open (this walkthrough assumes that the smart document DLL is named MOSTL2003.dll and is in the same directory as the XML expansion pack manifest file), and click OK.
  11. Using the XML Structure task pane, add elements to the XML document. As you add elements, switch to the Document Actions task pane and experiment with the available actions.

Creating and Using XML Expansion Pack Manifests

An XML expansion pack manifest file is an XML file that describes the locations and behaviors of a particular solution's component files. A solution can contain as little as one file or a virtually unlimited number of files. XML expansion pack manifest files work not only for distributing smart document DLLs, but virtually any type of file that you want to distribute as part of a Word 2003 or Excel 2003 solution. These components files could include schemas, transforms, additional DLLs, COM add-ins, text files, configuration files, and so on. You can also chain XML expansion pack manifest files together to create XML expansion pack manifest file collections, where one XML expansion pack manifest file references another one, and so on.

You create XML expansion pack manifest files with an XML editor such as Word 2003, Microsoft Visual Studio® .NET or a text editor such as Microsoft Notepad. A copy of the schema (manifest114809.xsd) is included with the download accompanying this article.

You reference an XML expansion pack manifest file in Word 2003 through the Templates and Add-Ins dialog box's XML Expansion Packs tab. In Excel 2003, on the Data menu, point to XML and click XML Expansion Packs.

The basic structure of an XML expansion pack manifest file looks like this:

xmlns="https://schemas.microsoft.com/office/xmlexpansionpacks/2003"
<manifest>
    <version>
    <updateFrequency>
    <uri>
    <manifestURL>
    <solution>
        <solutionID>
        <type>
        <alias>
        <documentSpecific>
        <context>
        <targetApplication>
        <file>
            <runFromServer>
            <type>
            <managed>
            <application>
            <version>
            <filePath>
            <installPath>
            <CLSID>
            <CLSNAME>
            <PROGID>
            <templateID>
            <regsvr32>
            <registry>
                <registryKey>
                    <keyName>
                    <keyValue>
                        <valueName>
                        <valueType>
                        <value>

The XML expansion pack manifest file elements, in the order presented, are as follows:

  • manifest  The root element for a valid XML expansion pack manifest file.

  • version (as it applies to the manifest element)  A required version number for the XML expansion pack manifest file. The version number is used during the update process to determine whether a new version should be downloaded. Version numbers must follow the format major.minor, for example, 1.0, 1.1, 2.0, and so on. Version numbers such as 1.0.0 or 1.1.4809.2003 are not allowed.

  • updateFrequency  An optional amount of time which should elapse (in minutes) between client polls to the server to check for updates.

  • uri  : An optional XML namespace which is associated with the solution. If the uri element is missing, the predefined URI https://schemas.microsoft.com/office/otherSolution is used for XML expansion pack manifest files not particularly tied to a namespace (for example, an XML expansion pack manifest file referencing only a COM add-in DLL).

  • manifestURL  An optional string which defines the location of an XML expansion pack manifest file that will be installed with the current XML expansion pack manifest file.

  • solution  The wrapper element for a single solution in the schema library. This element can occur any number of times, once per solution.

  • solutionID  A required string that uniquely identifies this solution in the schema library. It is essential that the string is unique. You must identify each solution with a globally unique identifier (GUID), which can be generated with a tool such as guidgen.exe that is included with Microsoft Visual Studio® .NET.

    Caution  Failure to provide a unique GUID for each solution may result in difficult-to-debug problems later on.

  • type (as it applies to the solution element)  A required string that defines the solution type. Valid values include smartDocument, schema, transform, and other.

  • alias  A required string that defines the friendly name of the solution exposed to the user in the XML Expansion Packs dialog box. An optional attribute, lcid, defines the locale IDs in which the name should be exposed. Two special values for the lcid attribute (0 or *) can be used to define a language-independent alias. This alias will be used only if there is no locale ID specified for the current language. If the lcid attribute is missing, the alias is available for all languages. Also, duplicates lcid attribute values are not allowed (for example, two aliases for the same locale ID are not allowed).

  • documentSpecific  An optional Boolean value which determines whether the solution will be available to any document with XML in the namespace (False), or only to those documents which explicitly reference it (True). The default is True for smart document solution types and False for all other solution types.

  • context  For solutions of type transform only, a required element that defines the URI of the application which can use the transform. For example, if the transform's result is the Word XML document schema, the solution would use the Word XML document schema namespace.

  • targetApplication  An optional string for solutions of type smartDocument. This element specifies the applications in which the solution is valid. Valid values include Word.Application, Excel.Application, Word.Application.11, and Excel.Application.11. Word.Application.11 and Excel.Application.11 limit the solution to this version of Word or Excel only, while Word.Application and Excel.Application refer to the current version and all subsequent versions. This element can occur up to four times per solution.

  • file  The wrapper element for information on a single file within a solution. This element can occur an unlimited number of times per solution.

  • runFromServer  This optional element tells the application to run the current file from a server location (specified in the filePath element) rather than download the file to the client.

  • type (as it applies to the file element)  A required string that defines the current file's type. Valid values include template (a document update file), smartTagList (a MOSTL file with smart tag elements), solutionList (a MOSTL file with smart document elements), schema (a schema file), primaryTransform (a primary transform file), secondaryTransform (a secondary transform file), actionHandler (a smart tag DLL or smart document DLL), solutionActionHandler (a smart tag DLL or smart document DLL that's only loaded when a particular solution is loaded), recognizer (a smart tag recognizer DLL or assembly), solutionRecognizer (a smart tag recognizer DLL or assembly that's only loaded when a particular solution is loaded), actionAndRecognizer (a DLL or assembly that implements both the ISmartTagAction (or ISmartTagAction2) and ISmartTagRecognizer (or ISmartTagRecognizer2) interfaces), solutionActionAndRecognizer (a DLL or assembly that implements both the ISmartTagAction (or ISmartTagAction2) and ISmartTagRecognizer (or ISmartTagRecognizer2) interfaces and is only loaded when a particular solution is loaded), COMAddIn (a COM add-in DLL), installPackage (an .msi file that will run after it's downloaded), and other (files such as images, text, and so on).

  • **managed  **This optional element instructs the application to use the Visual Studio Tools for Office loader to load the current file, as opposed to the traditional Office COM component loader.

  • application  This optional element, only valid for files of type COMAddIn, defines the applications in which the COM object is valid. Valid values are Word and Excel. This element can occur up to two times per file.

  • version (as it applies to the file element)  A required string analogous to the version for the manifest, this element determines whether the current file needs to be updated during the update procedure. Version numbers must follow the format major.minor, for example, 1.0, 1.1, 2.0, and so on. Version numbers such as 1.0.0 or 1.1.4809.2003 are not allowed.

  • filePath  A required string that indicates the location of the current file.

  • installPath  An optional string that allows you to specify a path (relative to the root path for the solution in the schema library) where the current file will be installed.

  • CLSID  For DLLs, this required element contains the class ID (CLSID). This element is used to set up the registry.

  • CLSNAME  For managed DLLs, a required string which contains the class name for managed action handlers loaded with the Visual Studio Tools for Office loader.

  • PROGID  An optional string which contains the programmatic ID (progID). This element is only valid for files of type COMAddin.

  • templateID  A optional string for files of type template, which is used to uniquely identify a template to allow it to be replaced when updating. If the XML expansion pack manifest file specifies an update frequency, this element is required, but it will only be used if the template points to an XML expansion pack manifest file that includes a file element for the template itself.

  • regsvr32  This optional element instructs the application to register the current file using revsvr32.exe. This procedure is automatic for files of type COMAddIn.

  • registry  The wrapper element for a single registry entry for either an entire solution or an individual file. This element is only required if you want to install registry entries as part of your solution.

  • registryKey  The wrapper element for a single registry key to be written. This element can occur an unlimited number of times per registry element.

  • keyName  A required string containing the name of the registry entry to be written.

  • keyValue  An optional wrapper element for a single registry entry to be written the current key. You can use the value of $PATH to be dynamically replaced with the path to the file, or you can use the value $SolutionRoot to be dynamically replaced with the registry path to the solution root. This element can occur an unlimited number of times per registry key.

  • valueName  A required string containing the name for a registry entry.

  • valueType  A required string containing the data type for a registry entry. Valid values include REG_SZ, REG_EXPAND_SZ, and REG_DWORD.

  • value  A required string containing the actual data for a registry entry. For string values, this string is optional. An empty string (REG_SZ) or a zero (REG_DWORD) is used by default.

Here's an example of an XML expansion pack manifest file for the smart document DLL that you created earlier in the walkthrough:

<? xml version="1.0" ?>
<SD:manifest 
        xmlns:SD=
        "https://schemas.microsoft.com/office/xmlexpansionpacks/2003">
    <SD:version>1.0</SD:version>
    <SD:updateFrequency>20160</SD:updateFrequency>
    <SD:uri>
        https://schemas.microsoft.com/office/smarttags/2003/mostl
    </SD:uri>
    <SD:solution>
        <SD:solutionID>
            {CAA3479D-3E91-4b80-A56E-8A1CEFC50F2E}
        </SD:solutionID>
        <SD:type>smartDocument</SD:type>
        <SD:alias lcid="1033">
            MOSTL 2003 Smart Document Solution
        </SD:alias>
        <SD:file>
            <SD:type>solutionActionHandler</SD:type>
            <SD:version>1.1</SD:version>
            <SD:filePath>MOSTL2003.DLL</SD:filePath>
            <SD:CLSID>
                {8BF70F8B-1198-452E-A8E2-65B070F6811C}
            </SD:CLSID>
            <SD:regsvr32 />
        </SD:file>
    </SD:solution>
</SD:manifest>

You can also chain two or more XML expansion pack manifest files into an XML expansion pack manifest collection. The basic structure of an XML expansion pack manifest collection looks like this:

xmlns="https://schemas.microsoft.com/office/xmlexpansionpacks/2003"
<manifestCollection>
    <manifest>
        <uri>
        <path>
  • manifestCollection  The root element for a valid XML expansion pack manifest collection.
  • **manifest  **The root element for an individual XML expansion pack manifest file. This element can occur an unlimited number of times per manifestCollection element.
  • uri  The namespace URI associated with the XML expansion pack manifest file.
  • path  The file path associated with the URI.

Here's an example of a fictional XML expansion pack manifest collection:

<manifestCollection xmlns=
        "https://schemas.microsoft.com/office/xmlexpansionpacks/2003">
    <manifest>
        <uri>urn:fabrikam.com/schemas/tripReports</uri>
        <path>http://www.fabrikam.com/solutions/manifest.xml</path>
    </manifest>
    <manifest>
        <uri>urn:fabrikam.com/schemas/tripReports</uri>
        <path>http://www.fabrikam.com/solutions/manifest2.xml</path>
    </manifest>
</manifestCollection>

When an end user references this XML expansion pack manifest collection from the Word 2003 or Excel 2003 user interface, the XML expansion pack manifest files at http://www.fabrikam.com/solutions/manifest.xml and http://www.fabrikam.com/solutions/manifest.xml are automatically referenced in turn (provided the end user has access to them).

Microsoft Office Smart Tag List (MOSTL) Files for Smart Documents

As part of the smart tags feature in Microsoft Office XP, you could create "simple" smart tags using XML-based Microsoft Office Smart Tag List (MOSTL) files. These smart tag actions were limited to hyperlinks only. In Office 2003, you can also create "simple" smart document solutions using extensions to the MOSTL file schema for Office 2003. These types of smart document solutions are limited to hyperlink, separator, button, label, image, and embedded help content only, and buttons are limited to hyperlink actions only.

Similar to creating an XML expansion pack manifest file, you create a MOSTL file with an XML editor such as Microsoft Visual Studio .NET or a text editor such as Microsoft Notepad. A copy of the schema (mostl114809.xsd) is included in the download accompanying this article.

After you create a MOSTL file, you must create an XML expansion pack manifest file to reference the MOSTL file, and then reference the XML expansion pack manifest file through the XML Expansion Packs dialog box.

The basic structure of a MOSTL file, as it applies to "simple" smart document solutions, looks like this:

namespace: https://schemas.microsoft.com/office/smarttags/2003/mostl
<smartTagList>
    <solutionID>
    <caption/>
      <actions>
         <action>
            <actionType/>
            <caption/>
            <help/>
            <imageURL/>
            <url/>
            <elementAction>
               <insertXML/>
               <removeXML/>

The MOSTL file elements as they apply to smart documents, in the order presented, are as follows:

  • smartTagList  The required root element for a MOSTL file.

  • smartDoc  The required root element for a MOSTL file containing smart document elements. This element can occur an unlimited number of times, once per associated namespace#element name. A required attribute, type, specifies the specific namespace#element name to which the accompanying smart document actions occur.

  • actions  The required container element for the actions associated with a specific namespace#element name.

  • action  The required element for an action associated with a specific namespace#element name. This element can occur an unlimited number of times per actions element. A required attribute, id, specifies a unique ID for the action.

  • actionType  The type of action. Valid values include Link, Separator, Button, Label, Image, HelpURL, and Help.

  • caption (as it applies to the action element)  The optional caption for the current action. This element applies to all action types except Separator.

  • help  The optional location of an XHTML-compliant file with help content to be displayed, or the XHTML itself. This element applies to the Help action type.

  • imageURL  The optional location of an image to display for an Image action type.

  • url  A URL that will be launched when the user invokes a Link or Button action type.

  • solutionID A required string that uniquely identifies this solution in the schema library. It is essential that the string is unique. You must identify each solution with a globally unique identifier (GUID), which can be generated with a tool such as guidgen.exe that is included with Microsoft Visual Studio® .NET.

    Caution Failure to provide a unique GUID for each solution may result in difficult-to-debug problems later on.

  • elementAction Specifies an action that will be performed in the context of the XML element in the smart document.

  • insertXML Specifies whether to insert XML content into the element at the location specified in a smart document.

  • removeXML Specifies whether to remove all content from within the XML element.

Here's an example of a MOSTL file that you can use in place of the smart document DLL that you created earlier in the walkthrough (although it won't be as functional as the smart document DLL):

<?xml version="1.0"?>
<smartTagList xmlns=
        "https://schemas.microsoft.com/office/smarttags/2003/mostl">
    <smartDoc type=
        "https://schemas.microsoft.com/office/smarttags/2003/mostl#smartTagList">
        <caption>Help with the &lt;smartTagList&gt; element</caption>
        <actions>
            <action id="smartTagList_Label">
                <actionType>Label</actionType>
                <caption>The &lt;smartTagList&gt; element defines a MOSTL
                    file.</caption>
            </action>
        </actions>
    </smartDoc>
    <smartDoc type=
        "https://schemas.microsoft.com/office/smarttags/2003/mostl#smartDoc">
        <caption>Help with the &lt;smartDoc&gt; element</caption>
        <actions>
            <action id="smartDoc_Label1">
                <actionType>Label</actionType>
                <caption>The &lt;smartDoc&gt; element defines a smart
                    document action.</caption>
            </action>
            <action id="smartDoc_Label2">
                <actionType>Label</actionType>
                <caption>A required attribute, type, defines the
                    namespace#element name associated with the smart
                    document action.</caption>
            </action>
        </actions>
    </smartDoc>
    <smartDoc type=
            "https://schemas.microsoft.com/office/smarttags/2003/mostl#solutionID">
        <caption>Help with the &lt;solutionID&gt; element</caption>
        <actions>
            <action id="solutionID_Label">
                <actionType>Label</actionType>
                <caption>The &lt;solutionID&gt; element defines the
                    unique solution ID, usually a GUID.</caption>
            </action>
        </actions>
    </smartDoc>
    <smartDoc type=
            "https://schemas.microsoft.com/office/smarttags/2003/mostl#caption">
        <caption>Help with the &lt;caption&gt; element</caption>
        <actions>
            <action id="caption_Help_smartDoc">
                <actionType>Help</actionType>
                <caption>As it applies to the &lt;smartDoc&gt;
                    element</caption>
                <help><html><head></head><body><p>For the
                    &lt;smartDoc&gt; element, the &lt;caption&gt;
                    element defines the text that appears on the
                    <b>XML Expansion Packs</b>
                    tab.</p></body></html></help>
            </action>
            <action id="caption_Help_action">
                <actionType>Help</actionType>
                <caption>As it applies to the 
                    &lt;action&gt; element</caption>
                <help><html><head></head><body><p>
                    For the &lt;action&gt; element, the &lt;caption&gt;
                    element defines the element that appears in the
                    <b>Document Actions</b> task
                    pane.</p></body></html></help>
            </action>
        </actions>
    </smartDoc>
    <smartDoc type=
            "https://schemas.microsoft.com/office/smarttags/2003/mostl#actions">
        <caption>Help with the &lt;actions&gt; element</caption>
        <actions>
            <action id="actions_Label">
                <actionType>Label</actionType>
                <caption>The &lt;actions&gt; element defines one or
                    more actions associated with the namespace#element
                    name.</caption>
            </action>
        </actions>
    </smartDoc>
    <smartDoc type=
            "https://schemas.microsoft.com/office/smarttags/2003/mostl#action">
        <caption>Help with the &lt;action&gt; element</caption>
        <actions>
            <action id="action_Label1">
                <actionType>Label</actionType>
                <caption>The &lt;action&gt; element defines an
                    action.</caption>
            </action>
            <action id="action_Label2">
                <actionType>Label</actionType>
                <caption>A required attribute, id, defines a unique
                    action ID.</caption>
            </action>
        </actions>
    </smartDoc>
    <smartDoc type=
            "https://schemas.microsoft.com/office/smarttags/2003/mostl#actionType">
        <caption>Help with the &lt;actionType&gt; element</caption>
        <actions>
            <action id="actionType_HelpURL">
                <actionType>HelpURL</actionType>
                <caption>Using the &lt;actionType&gt; element</caption>
                <help>mostl_smartdoc_docfrag.htm</help>
            </action>
        </actions>
    </smartDoc>
    <smartDoc type=
            "https://schemas.microsoft.com/office/smarttags/2003/mostl#help">
        <caption>Help with the &lt;help&gt; element</caption>
        <actions>
            <action id="help_Label">
                <actionType>Label</actionType>
                <caption>The &lt;help&gt; element specifies XHTML
                    -formatted text for actionType=Help, 
                    or a path to an XHMTL-formatted file for
                    actionType=HelpURL.</caption>
            </action>
        </actions>
    </smartDoc>
    <smartDoc type=
            "https://schemas.microsoft.com/office/smarttags/2003/mostl#imageURL">
        <caption>Help with the &lt;imageURL&gt; element</caption>
        <actions>
            <action id="imageURL_Label">
                <actionType>Label</actionType>
                <caption>The &lt;imageURL&gt; element specifies the
                    path to an image file. Here's an example:</caption>
            </action>
            <action id="imageURL_Image">
                <actionType>Image</actionType>
                <caption>Microsoft Office logo on a yellow
                    background</caption>
                <imageURL>https://www.microsoft.com/products/shared/
                    images/bnr_office.gif</imageURL>
             </action>
        </actions>
    </smartDoc>
    <smartDoc type=
            "https://schemas.microsoft.com/office/smarttags/2003/mostl#url">
        <caption>Help with the &lt;url&gt; element</caption>
        <actions>
            <action id="url_Label1">
                <actionType>Label</actionType>
                <caption>The &lt;url&gt; element specifies a clickable
                    hyperlink or button target.</caption>
            </action>
            <action id="url_Separator">
                <actionType>Separator</actionType>
            </action>
            <action id="url_Label2">
                <actionType>Label</actionType>
                <caption>And here's an example of a
                    hyperlink:</caption>
            </action>
            <action id="url_Link">
                <actionType>Link</actionType>
                <caption>Microsoft Office Home Page</caption>
                <url>https://www.microsoft.com/office</url>
            </action>
            <action id="url_Label3">
                <actionType>Label</actionType>
                <caption>And here's an example of a button:</caption>
            </action>
            <action id="url_Button">
                <actionType>Button</actionType>
                <caption>Microsoft Office Home Page</caption>
                <url>https://www.microsoft.com/office</url>
            </action>
        </actions>
    </smartDoc>
</smartTagList>

Here's an example of an XML expansion pack manifest file that you can use to reference the MOSTL file:

<?xml version="1.0"?>
<manifest xmlns=
        "https://schemas.microsoft.com/office/xmlexpansionpacks/2003">
    <version>1.0</version>
    <uri>https://schemas.microsoft.com/office/smarttags/2003/mostl</uri>
    <solution>
        <solutionID>{387D23FD-E460-4852-B51C-D17E2BF34CD0}</solutionID>
            <type>smartDocument</type>
            <alias lcid="*">MOSTL v.11 Smart Document Solution</alias>
            <file>
                <type>solutionList</type>
                <version>1.0</version>
                <filePath>mostl_smartdoc.xml</filePath>
            </file>
    </solution>
</manifest>

Note  If you're using the mostl_smartdoc_manifest.xml file that accompanies this article, be sure to change the <version>1.0.0102.2003</version> tags to <version>1.0</version>, or the solution may not work properly.

Conclusion

In this article, you learned:

  • What smart documents are and what they can be used for.
  • How the smart document object model works and how to use it to build and run a smart document DLL.
  • How to use XML expansion pack manifests to reference a solution's component files.
  • How to create simple smart document solutions by using XML-based MOSTL files with smart document elements.