当Office载入你的操作DLL的时候,它首先调用图3所示的配置方法。Office首先调用SmartDocInitialize(允许你执行具体的一次性的初始化)。接着它将通过调用你的get_SmartDocXmlTypeCount实现查询文档中定义的拥有关联控件的XML元素的数量(文档中的XML元素没有关联控件的情况也是可以的)。在例子中,文档操作面板是空的,因此你可能希望为这些元素定义一些标准的帮助内容。你一旦告诉Office你对多少XML文档元素有兴趣后,它将查询每个元素的名称,这些名称是通过调用多个get_SmartDocXmlTypeName获得的。你必须返回XML元素的合格的名称(例如schema#element)。每个元素都有说明,当用户定位到这个元素中的时候,说明会出现在文档操作面板的标题中。这是通过调用get_SmartDocXmlTypeCaption返回的。对get_SmartDocXmlTypeName和 get_SmartDocXmlTypeCaption的调用是成对出现的,每个XML元素执行一次。下一步,Office希望知道每个元素的显示的事务面板中的控件信息。这些信息包括:
· get_ControlCount--给定的某个元素的控件数量。
· get_ControlID--允许你根据某个元素的控件索引(从1开始)给每个控件指定一个唯一的ID号。
· get_ControlNameFromID--在给定控件ID后返回控件的(非固定的)名称。这个名称没有显示,但是用于引用Word或Excel对象模型中的控件。
· get_ControlTypeFromID--给定控件ID后,返回控件的类型(从图2中)。
当用户在文档中移动的时候,Office用适当的控件更新文档操作事务面板,它接着在事务面板中绘制控件的时候调用控件绘制方法(图4所示)。首先它调用get_ControlCaptionFromID,允许你为控件提供一个说明。注意说明不是在配置的时候提供的,而是在显示的时候提供的,因此可以动态地修改它。Office不会绘制有空白的或NULL说明字符串的控件。这可能用于动态地隐藏和显示控件。为了隐藏一个控件,你只需要简单地为该控件从get_ControlCaptionFromID返回一个一个NULL或空字符串。
接着Office为每个控件调用该控件类型特定的填充方法(例如PopulateHelpContent)。你使用这些方法为控件提供内容,例如图像的位置或超级链接的文本。注意与控件关联的文档元素的XML和Text内容被传递到所有的填充方法。同时也要注意,C_TYPE_LABEL和C_TYPE_SEPARATOR类型的控件没有关联的填充方法。在所有的控件绘制了并且事务面板完成了以后,Office将调用OnPaneUpdateComplete。
当用户与事务面板中的控件交互操作的时候,Office调用图5显示的列表中的某个通知方法。标签和分隔符没有关联的通知方法。对于其它控件,通知方法表明要么状态改变了,要么被点击了,这都可能调用一个操作(例如超级链接或图像)。
注意,通知太多比太少更容易造成Office出错。例如,在Excel中的单元选择发生改变的时候(即使XML元素仍然没有变化),Office重新绘制文档操作工作面板并调用你的方法,这样在事务面板上你才拥有真正的动态内容。例如,你能够通过Excel对象模型查询被选择的单元的值并根据这个值更新控件。在示例代码中我利用了这个优点来更新事务面板中被选择的事务的信息,而不需要在文档操作DLL中操作Excel VBA事件。
属性包
大多数控件绘制方法都提供了ISmartDocProperties参数。这是一个名称/值对的属性组(继承自IPropertyBag),提供了控件上的附加信息。这是你指定控件的大小、字体、对齐方式等的地方。图7提供了应用于所有控件的关键的名称。属性值,包括整形属性的值,都是作为BSTR提供给的ISmartDocProperties::Write的。例如,PopulateTextboxContent下述代码行会把文本框控件的宽度设置为50个像素:
Props->Write(CComBSTR("W"), CComBSTR("50"));
图7. 所用控件的ISmartDocProperties
| 属性 | 描述 |
| X | 正的整型值,它指定控件应该离左边多远,按象素计算。 |
| Y | 正的整型值,它指定控件应该离顶部多远,按象素计算。 |
| H | 正的整型值,它指定控件的高度,按象素计算。 |
| W | 正的整型值,它指定控件的宽度,按象素计算。 |
| Align | 对齐方式。 |
拥有关联标签的控件(C_TYPE_TEXTBOX、C_TYPE_CHECKBOX)都有图8所示的附加属性以描述该控件的标签属性。注意这些只能影响该控件的标签,不会影响绘制控件的字体。最后,还有一些其它的属性只能应用于特定类型的控件。这些属性显示在图9中。
图8.控件标签的IsmartDocProperties
| 属性 | 描述 |
| FontFace | 显示控件标签的字体(例如"Arial") |
| FontSize | 显示标签控件的字体的大小,按"点(point)"计算。 |
| FontStyle | 字体格式,"none"(默认值)或"underline"、"italic"、"strikeout" (如果使用多个,用"|"字符隔开) |
| FontWeight | 它的值是 "normal"(default) 或"bold" |
图9. 其它的ISmartDocProperties名称/值对
属性 | 应用的控件类型 | 描述 |
| IsMultiLine | C_TYPE_TEXTBOX | 如果设置为True,就允许文本框接收多行文本,每行直接用回车换行符隔开。 |
| NumberOfLines | C_TYPE_TEXTBOX, C_TYPE_COMBO, C_TYPE_LISTBOX | 文本框中显示的行数。对于列表框或组合框,它是不滚动时显示的行数。 |
| PasswordCharacter | C_TYPE_TEXTBOX, C_TYPE_COMBO | 用于掩饰文本框中输入的内容的一个字符,这样文本框就可以用于输入密码。 |
| ExpandHelp | C_TYPE_HELP, C_TYPE_HELPURL | 如果设置为True,它在最初显示的时候就扩展帮助控件。 |
| Border | C_TYPE_IMAGE | 如果设置为True,当鼠标进入图像的范围内的时候显示图像的边框。 |
| IsEditable | C_TYPE_COMBO | 如果设置为True,它就允许编辑组合框中的文本内容。 |
| ControlOnSameLine | C_TYPE_TEXTBOX, C_TYPE_COMBO, C_TYPE_LISTBOX | 如果设置为True(默认值),它就把控件标签显示在控件周围。如果设置为False,它把控件标签显示在控件上面一行。 |
| Expanded | C_TYPE_DOCUMENTFRAGMENT, C_TYPE_DOCUMENTFRAGMENTURL | 如果设置为True,它就扩展事务面板中的文档片段内容。 |
现在你已经有了多种接口方法的一个相当快速的教程了,我将使用Visual Studio .NET建立一个智能文档操作处理程序DLL。