天天看点

我的VSTO之路(三):Word基本知识

我的VSTO之路(三):Word基本知识

)。言归正传,我录制了一段视频来演示本文所要介绍的内容。

这段视频,描述了一个简单的Word搜索插件,包含了以下几个功能点

自定义Ribbon 自定义Task Pane VSTO插件中获取Word内容全文 修改Word内容和样式

首先,要开发出良好的程序,我们需要了解我们的开发平台,而Word本身是一个很复查的平台,我在这里先从Word的对象模型开始介绍。Word Object Model中一共包含有数百个不同类型的对象,其中最关键的也是最常用的是Application、Document、Range、Selection和Bookmark,他们的关系如下图:

我的VSTO之路(三):Word基本知识

我来依次介绍这几个对象:

Application代表Word程序,而一个Word程序内可以包含多个Word文档。用通俗的话来说,无论你开几个Word文档,都是在一个Word进程里面管理。这我们以后会讲到的Excel不一样。同时Application又是所有Word对象根,你可以通过Application对象,获得其他对象。在Addin开发过程中,我们可以通过以下方式来获得Application对象:

Document对象代表着一个Word文档,即便你刚打开你的Word,是一个空的新文档,也会有一个Document。在开发过程中,以下这个属性从Application中获得当前的Document对象:

此外Application对象也维护着一个集合,即Application.Documents,里面包含着现在所有打开的Word文档。

Range是一个比较特殊的对象(我其实都不知道如何用中文翻译贴切地翻译这个单词),在你日常使用Word的过程中,你甚至可能不会知道有这样一个对象存在,但如果你想通过程序方式修改Word正文的内容,Range是一个很关键的对象。用微软官方的表述,Range代表着文档中一片连续的区域,微软为它列出了一下几个特性:

Range的组成成分可以是单独的插入点,也可以是一个文本范围或整个文档。

Range包含非打印字符,例如空格、制表符和段落标记。

Range可以是当前所选内容所表示的区域,也可以表示当前所选内容之外的区域。

Range与始终可见的所选内容不同,它在文档中是不可见的。

Range不随文档保存,仅存在于代码运行期间。

我再为它加2条

Range有明确的开始和结束,但不同的Range之间是可以有交集的

Range的长度是在变化的,如果你往一个Range里面插入的一个单词,它的长度会自动变长。

获得Range对象的方式很多,我们可以通过Document对象的Range(ref object Start = Type.Missing, ref object End = Type.Missing)方法,创建一个自定义的Range。通过Word中文档相关的对象都有一个Range属性,比如Paragraph.Range、Selection.Range。

Selection代表着当前光标所选中的对象,我们在开发过程中这个对象会和Application.WindowSelectionChange一起使用。

Delegate接口

Bookmark即书签,在Word文档中做一个标记,方便查阅。开发过程中,我们可以基于Range来创建Bookmark。如:

至此我们已经介绍完毕了Word中的主要5个对象,现在我们运用我们学到的东西,来实开头视频中的那个插件

插件:自定义Search面板

我先定义一下我们要实现的功能点,获得Word文档的内容,取得与检索关键字相关的上下文并显示在ListView中,当用户点中ListView中的项目时,高亮显示Word文档中对应的内容。以下是如何实现这几个功能的介绍。

获得Word的全文

要取得当前Word的全文,我们主要要解决两个问题。

如何获得当前的Document对象?

如何通过Document对象获得文档内容?

对于第一个问题,因为搜索功能主要是写在Task Pane中的UserControl中(这一点在上一篇文章中已经有过介绍),所以取得Document对象的主要方法,是通过Application对象获得ActiveDocument的对象,即当前编辑的文档:

对于第二个问题,我们有两个方法:首先,Document对象有Paragraphs集合,这个集合里面包含了每个段落的对象,而每个段落对象,都有Range属性,我们可以通过Paragraph.Range.Text,来获得每个段落的正文。其次Document对象有一个Range方法,通过它我们可以把整个Document作为一个Range。

Search按钮代码

介绍一下这段代码的几个功能点:

在Search功能开始时,先清除文档中的高亮显示(ClearMark方法稍后会介绍)。

分段落,依次查找关键字。

获得关键字的上下文,并放入ListView中显示。需要注意的时候,我在ListViewItem的tag对象里面,存入了Keyword在文档中的Range,为了ListView点击事件。

ListView点击事件

总体来说这段代码很简单,我稍微介绍一下Range对象的使用,这里我修改了HighlightColorIndex属性,来修改文字的背景色,如果你修改字体相关的样式,可以通过Range.Font属性。(此外,我会在下一篇文中,介绍如何通过Range加超链接、书签或者Content Control)。

其他方法

我在Search事件和ListView点击方法中都会先调用这个方法,它会使用在lvSearchResult_ItemSelectionChanged中保存的Range和Color,来恢复之前的样式。

总结

本文中,我介绍了Word对象模型的基本内容和我写的一个Word插件,包含对Application、Document和Range对象的操作。Word程序包含的内容是很多的,本来想把自己了解的Word知识一次写完,但写到这里发现已经写了很多了,怕大家会看得累

我的VSTO之路(三):Word基本知识

,所以先发出来,再下一篇文章,我会进一步深入介绍Word插件开发。下次内容预告:

修改右键菜单

往文档中插入内容

添加超链接、书签

基于选中内容,显示悬浮框