文档对象还支持VBA,.NET使用模块

VBA

文档对象也支持VBA,.NET框架支持VB.NET脚本语言,.NET类库中的Microsoft.VisualBasic类。 Vsa.VsaEngine 和界面 Microsoft.Vsa.IVsaSite 支持脚本语言。参考HTML文档对象模型,我设计了一种基于VB.NET处理文档的脚本语言。在该语言中,可以通过脚本全局对象document直接访问文档对象TextDocument,通过document.all可以访问文档对象TextDocument。对于一些被标记的文档元素对象,使用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

使用 Assembly Builder 的 DefineDynamicModule 创建模块构建器

使用 Module Builder 的 DefineType 创建类型名称为 AllElements 的类型构建器

p>

遍历文档内容,根据名称与特定文档对象的对应关系c语言实现文本编辑器,生成按名称访问的哈希表

遍历哈希列表中的名字,使用类型生成器的DefineField方法创建一个公共字段,字段类型为对象类型。

使用类型生成器生成新的类型System.Type,然后动态创建该类型的实例,即动态生成AllElements对象

遍历文档元素对象的哈希表,使用System.Type.InvokeMember配置字段值到AllElements对象

这样应用程序会动态创建 AllElements 类型并实例化一个对象引用,然后 VB.NET 脚本就可以直接使用 document. all.Document 元素对象名称直接访问文档中的特定内容。请注意,当文档内容发生变化时,所有元素都需要重新输入和实例化。

以上程序模块搭建完成后,即可搭建VB.NET脚本语言运行环境。首先定义TextDocumentVsaSite类型实现IVsaSite接口,实现GetGlobalInstance函数。函数参数为字符串,返回一个Object,函数实际判断如果参数为“document”,则返回文档对象TextDocument,如果参数为“eventobj”,则返回刚刚定义的事件对象,如果是“dbconnection”,则返回数据库连接对象。该对象还实现了 IVsaSite.OnCompilerError 来处理脚本编译错误。

该程序还从 Microsoft.VisualBasic.Vsa.VsaEngine 派生脚本引擎 VBScriptEngine。该模块使用 VsaEngine 的 Items.CreateItem 将 document、eventobj、dbconnection 等全局变量添加到引擎中,还添加了一些必需的 .NET 引用。另外,它还实现了对脚本代码文本的一些处理,比如加密、自动添加一些必要的代码等。

脚本环境还模拟并实现了文档事件的处理。例如,文档中的一些元素对象支持 onchange 事件。这些元素有名称。当用户修改这些元素的内容时,程序会查询脚本引擎。我们看看是否有一个名为对象名_OnChange的进程,如果存在则执行,从而模拟事件处理的实现。

在VB.NET脚本环境中,可以直接调用全局对象的成员函数,所以在vbsystem中定义的一些例程可以直接调用,如Alert、ConFirm、Prompt、DebugPrint等可以在vbsystem中定义成员函数,这些函数可以直接在脚本中使用。

访问数据库

由于应用需求,这个文本编辑器需要直接访问数据库,但是文本编辑器同时用于C/S程序和B/S程序。在B/S框架中,直接连接数据库并不容易c语言实现文本编辑器,必须通过服务器程序访问数据库。为了编程方便,这两种模式之间的差异应该被抹去。

我们来看看.NET框架中数据库操作的类型,具体操作SQLServer的到底是System.Data.SqlClient命名空间下的对象集合,还是System.Data.OleDb操作OLEDB。空间下面的对象集合(其他类似于特殊操作ODBC和ORACLE),这些对象集合最大的共同点是它们都遵循命名空间System.Data下的一组接口。这些接口包括IDataReader、IDbCommand、IDbConnection、IDbDataParameter、IDataParameterColleciton等。如果我们编译一组同样实现这些接口的对象,就相当于定制了一套.NET数据库驱动。于是小弟赶紧根据B/S架构特点写了一套对象。该组对象通过 HTTP 协议与 WEB 服务器进行数据通信。这组对象只是简单的将 SQL 语句及其参数打包后使用 POST 方法发送到指定的服务器页面,然后等待返回。 ,服务端页面解析SQL语句和参数查询数据库,将查询结果经过一定编码后返回给客户端,客户端根据HTTP返回处理后可以使用实现IDataReader的对象访问结果。这样,如果应用的其他模块查询数据库,只需要坚持使用System.Data.IDbConnection等接口,就消除了C/S和B/S环境下访问数据库的区别。

这种模式也是WebService的一种,服务端页面可以使用任何类型,可以使用ASP、ASP.NET、PHP、J2E或JSP等,只要能解析出SQL语句并返回一个具体结构数据就行了。小弟的服务器是J2E,连我对JAVA都不熟悉,所以用JSP实现了一个。我把这个模型称为两层半,实践证明它仍然有效。

派生对象

定义完基础对象,开始派生对象,首先定义字符对象类型TextChar,一个文档内容中最重要的是字符数据,这里为了方便实现,文档中的每个字符都是一个字符目的。字符对象重载了RefreshSize对象的RefreshSize方法,用于根据当前绘图对象(System.Drawing.Graph对象)的MeasureString计算文字大小。请注意,默认情况下,此方法计算字符串的显示宽度,并添加一些额外的空格。要计算实际大小,使用 System.Drawing.StringFormat.GenericTypographic 参数。此外,还有一个比较特殊的字符——制表符。这个字符的宽度不是固定的,需要在排版时计算出来。

字符对象 (TextChar) 也派生 RefreshView 方法。这种方法比较简单。根据Left和Top值转换坐标后,计算绘制位置,然后调用System.Drawing.Graph.DrawString方法即可。角色对象也定义了它自己的成员。例如,Char属性返回对象表示的字符数据,Font表示绘图对象使用的字体,ForeColor表示绘制文本的颜色。

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论