C#编写文本编辑器
VBA
文档对象还支持VBA,.NET框架支持脚本语言,.NET类库中的类
Microsoft.VisualBasic.Vsa.VsaEngine及接口 Microsoft.Vsa.IVsaSite 就支持脚本语言。我参照HTML文档对象模型,在的基础上设计一种处理文档的脚本语言,该语言中直接使用脚本全局对象document就访问了文档对象TextDocument,而使用document.all就能访问文档中的某些做了标记的文档元素对象,使用 dbconnection 就能使用文本编辑器后台使用的数据库连接对象,使用eventobj访问文档编辑器触发的事件的信息,使用vbsystem来调用某些例程。首先定义一些类型,用于实现脚本全局对象dbconnection,eventobj,vbsystem的功能,而全局对象document的类型就是TextDocument,已经实现,但document.all还未实现,为此在TextDocument中新增只读属性all,该属性返回一个System.Object类型的对象,由于document.all的类型中定义的字段根据文档的内容而动态改变,因此需要使用.NET的反射机制动态的创建对象类型并实例化对象,其创建过程为
新增一个System.Reflection.AssemblyName对象,设置其Name属性为
"RunTimeTextDocumentLib"
使用AppDomain.CurrentDomain.DefineDynamicAssembly来创建一个程序集生成器 System.Reflection.Emit.AssemblyBuilder
使用程序集生成器的DefineDynamicModule来创建一个模块生成器
使用模块生成器的DefineType来创建一个类型生成器,类型名称为 AllElements 遍历文档内容,根据名称和特定文档对象的对应关系生成一个按名称访问的哈希列表 遍历哈希列表中的名称,使用类型生成器的DefineField方法创建一个公开字段,字段类型为object类型。
使用类型生成器生成一个新的类型System.Type,然后动态创建一个该类型的实例,这样动态生成了AllElements对象
遍历文档元素对象哈希列表,使用System.Type.InvokeMember向该AllElements对象设置字段值
这样应用程序动态的创建了AllElements类型并实例化了一个对象引用,这时脚本程序就可以直接使用 document.all.文档元素对象名称 来直接访问文档中特定内容了。注意当文档内容发生改变时需要重新生成AllElements的类型并实例化。
以上的程序模块建好后就可以搭建脚本语言运行环境了,首先定义类型
TextDocumentVsaSite来实现IVsaSite接口,实现其中的GetGlobalInstance函数,该函数参数为字符串,返回一个对象,该函数实际上判断若参数"document"则返回文档对象TextDocument ,若参数为"eventobj"则返回刚刚定义了事件对象,若为
"dbconnection"则返回数据库连接对象。该对象还实现了IVsaSite.OnCompilerError来处理脚本编译错误。
程序还从Microsoft.VisualBasic.Vsa.VsaEngine派生了脚本引擎VBScriptEngine。该模块使用VsaEngine的Items.CreateItem来向引擎添加
document,eventobj,dbconnection等全局变量,还添加一些所需的.NET引用,此外还实现了对脚本代码文本的一些处理,比如加密,自动添加某些必须的代码等。