插件是怎么工作的?
在前面章节中给你们演示的InsertDate代码是相当简单的,而且自动完成功能让人感觉不可思议。
我将从对象浏览器开始(Object Browser)开始,因为他能够非常容易的让我们学习对象所以他是一非常好的助手。你可以在你要查看的对象上单击右键然后选择转到定义(Go To Definition)来快事的查看类的成员。最终结果参看图4,你可以在列出的成员中查看任何一个成员的原型,或则选择一个成员按F1访问在先帮助。
图4 对象浏览器
applicationObject对象描述了插件宿主(host)应用程序,在这个例子中宿主(host)应用程序为Visual Studio .NET IDE。applicationObject在OnConnection方法中实现。在在线帮助中找到“DTE”,甚至在向导自动产生的代码中声明为“_DTE”类型的变量applicationObject。在应用程序级别你会看到她又许多有趣的成员。
其中一个成员是ActiveDocument属性(property),它描述了当前焦点的文档(document)。这个文档就是你要进行InsertDate操作的文档。在窗口焦点和文档焦点有关系但是不同的情况下,一个非常有用的规则是,不管窗体是否有焦点具有焦点的文档都是将要被保存的。
ActiveDocument.Selection属性返回一个描述当前在文档中选择的对象。因为在C#中它是一个普通对象,所以我他它强制类型转换成TextSelectioni。ActiveDocument是一个普通的类,因为document(译者:类似于VC++中的document类)没有必要基于text,就好比一个窗体设计document(译者:学过VC++的人可能比较熟悉document类的继承关系,不熟悉的人可以看看有关这方面的书籍)。作为最终结果Selection属性也是一个普通的类,在这里我把它强制类型转换成类我们在代码中实际操作的TextSelection类型。
TextSelection描述了一个文件的视图(view),并且这个文件的动作和工具|选项中的设置还有使用的状态一至。他提供了很多的你可能想到用于修改文件的属性和方法,还有他可以影响使用的视图(view),当前选择的内容,插入位置。如果你曾经录制过宏,你可以看见使用TextSelection对象来捕获内容。
InsertDate简单的的设置了Text属性值是当前的日期。类似Text一样,所有的动作都可以设置同类型的值。这就意味着所有得到的内容都要被替换,如果没有选择内容那么就会在光标的位置上替换,不过你要注意当前的状态是插入还是覆盖模式。
另外一种方法是使用Insert函数,这个方法允许你控制文本放置的位置和描述了一个不能重做的动作。使用这个方法来替换Text属性指定插入内容的代码如下:
((TextSelection)applicationObject.ActiveDocument.Selection).Insert(
DateTime.Now.ToString("yyyy-MM-dd"),
(int)EnvDTE.vsInsertFlags.vsInsertFlagsCollapseToEnd);
这个vsInsertFlags指出了文本已什么方式什么位置插入的。在线帮组中忽略了vsInsertFlags的文档,所以我在图5中包含了这部分。
现在你因该理解了插件是怎么工作的了,让我们为这个命令简单的作一个键盘邦定和增加一个菜单。
图5 vsInsertFlags 值
vsInsertFlagsCollapseToEnd
The selection's current
contents are deleted before
performing the insertion, and
the TextSelection is left empty
at the end of the newly
inserted text.
vsInsertFlagsCollapseToStart
The selection's current
contents are deleted before
performing the insertion, and
the TextSelection is left empty
at the beginning of the newly
inserted text.
vsInsertFlagsContainNewText
The selection's current
contents are replaced with the
inserted text, and the
TextSelection is left containing
the new text.
vsInsertFlagsInsertAtStart
The inserted text is placed at
the beginning of the
TextSelection, and the
resulting TextSelection
contains both the new and
previous text.
vsInsertFlagsInsertAtEnd
The inserted text is placed at
the end of the TextSelection,
and the resulting
TextSelection contains both
the new and previous text.