CSDN博客

img shanhe

如何使应用程序具有脚本支持功能

发表于2004/6/24 10:05:00  3622人阅读

 

如何使应用程序具有脚本支持功能

 杨山河 胡晓敏

 

问题提出的背景
在软件开发规模日益庞大的今天,软件的可维护性和可重用性显得非常重要。谁都希望自己的开发成果能得到最大的应用,希望能够在不重新推倒原来的开发成果基础之上能够完善现有系统。提供二次开发功能成为解决当今日益严重的软件开发危机的一个重要途径。但如果提供API进行二次开发将带来诸于语言调用规则等棘手问题,基于此,许多成功系统都采用Script(脚本)技术来支持应用系统的二次开发。采用这种模式进行开发的系统一般情况下都将自身是一些重要、安全的功能留给脚本,让脚本解释装置来控制使用这些功能,实现应用软件系统自身功能的重利用。例如:在Photoshop中提供的Action功能,可以自动完成对当前图象的“批处理”。

传统的脚本支持功能是向用户提供一个解释型语言,此语言同系统密切相关,可以方便的通过相应的功能语句实现用户的二次开发需求。可是现在的开发都要求快速有效,尽量控制开发规模,如果每一应用系统还要承担开发一种与之适应的开发,且不说开发的规模,单就所开发的语言的配套文档就会让用户头疼,这样只会增加开发的规模和成本以及维护的难度。现在的计算机开发技术的发展使得我们不必去碰这样的麻烦,要想实现脚本支持,我们可以利用COM的功能,利用已有的支持脚本解释的COM组件来实现自己开发的应用系统的脚本支持。我们应当记得在IE中就提供了独立的VBScript的解释组件,可以解释嵌入HTML中的VBScript和Jscript,Office套件也支持VBA,这些软件是我们研究COM技术的经典例子。并且在VB6.0中,微软提供了一个 ActiveX控件棗ScripControl,利用好它,我们就可以在系统中嵌入VBScrip解释功能。如果采用C++、VB等支持COM的语言编写应用,我们可以轻松实现脚本支持功能。

Script宿主、Script引擎、Script(脚本)之间的关系
要想实现基于COM组件的脚本支持功能,我们需要正确理解Script各方以及相互之间的关系。有关脚本的概念有:Script Host(Script宿主)、Script Engine(Script引擎)、Script(脚本) 。

什么是Script宿主呢?听起来象生物学术语。类似生物学的概念,可以简单认为是我们所编写的脚本要控制的功能对象,是我们编写的应用程序,想提供给最终用户的功能组件。举例说,Word是微软提供给大家的文字处理系统,它采用了基于COM的软件结构,如果我们为Word编写一些脚本(就是平常所说的“宏”),那么,脚本所依附的对象 Word就是Script宿主了。脚本功能的最终执行者就是Script宿主。我们编写的任何自主应用程序都可以看作宿主,都可以嵌入脚本解释能力。当然,宿主应当是也最好是基于COM编程的。另一方面,脚本就是对宿主进行服务请求或进行控制的代码。

Script引擎就是Script宿主和Script之间的“桥梁”。脚本引擎获取脚本,并按照语法进行解释,并控制宿主程序提供的对象的属性,调用相关方法,实现脚本要求的功能。向脚本提供可利用的对象并解释脚本以实现二次开发是引擎的主要功能。

三者之间的关系可以用如下的图形来表示。

 

 


--------------------------------------------------------------------------------

向脚本控件提供对象


--------------------------------------------------------------------------------

控制宿主提供的对象

从输入部件获取要解释执行的脚本

 

 

Script引擎对象的属性、方法、事件
Script引擎是作为一个ActiveX控件提供给用户的,在利用它之前,我们来看一看此控件的属性和方法。

属性:

AllowUI:可读写,布尔值,检测是否允许运行用户的接口元素。如果为False,则诸如消息框之类的界面元素不可见。

CodeObject:返回宿主被调用的特定的公用成员对象。只读。

Modules:只读。返回宿主提供给脚本的组件库模块。COM组件通常都是以对象收集的形式向用户提供可以留给用户二次开发的对象集合,每一个收集即一个Modules(模块)。

Language:设置或获取脚本引擎解释的语言,例如:VBScript、JScript。

Name:返回模块、过程、或者对象的名字,只读属性。

Procedures:返回模块中定义的过程,只读。

SitehWnd:窗口句柄,如果本控件以ActiveX控件创建,则此属性为控件的容器;如果是以自动化对象创建,则为0,即桌面。此属性可读写。

State:设置或返回控件的状态,如果为0,控件只执行语句但不转发事件,为1则为加入的本控件接受的对象转发事件。

Timeout:设置或返回控件的相应脚本的超时值。当超时值到达时,将引发Timeout事件。也可设为-1,表示无超时设定。

UseSafeSubset:设置或返回宿主程序是否关心安全。宿主程序的安全级别可以从此属性设置。

Error:错误对象,发生错误时,此属性返回一个错误对象。

方法:

AddCode :往一个模块加入一些代码。格式为:AddCode code, 可以调用多次。

AddObject:向一个模块加入一个对象,格式:ScriptControl.AddObject(name, object[, addMembers]),name为欲加入的对象名字,Object为实际的对象,addMembers为可选指示此对象是否为全局对象,False为局部对象。只有往本对象中加入对象后才能在脚本中使用这些对象。

Eval:求值表达式。格式为object.Eval(expression) 。

ExecuteStatement:解释并执行脚本语句。格式:object.ExecuteStatement statement。

Reset:丢弃所有的对象和代码。State属性将为0。

Run:运行一个指定的过程。格式:object.Run(procedureName, parameters()),procedureName为要运行的过程名,parameters()为

事件

仅有两个事件:error 和TimeOut。前者可以用于错误捕获,后者在脚本得不到响应时发生。

VB开发实例
假设我们要在VB中开发一个编辑软件,此系统显然就是前文提到的脚本技术中的宿主,为了支持二次开发将系统设计为基于COM,并且向用户提供两个对象“WORD”及“MyBox”。实际上为了简化问题,达到演示说明的目的,此例子并未自行设计复杂的代码,向用户提供的对象实际都是“现成”的棗“WORD”就是您系统中安装的Office中的Word,只不过被我“转手”以“我提供的对象”形象出现,在Office VBA中Word所有的方法属性都可以在本系统的脚本功能中提供给用户;“MyBox”实际上是设计时添加的一个TextBox控件,但最终是以我的文本框提供给使用者。界面很简单(朴素?投机取巧?),尽量不转移大家的注意力,以了解本文所述的脚本技术实现。代码及注释如下:

VERSION 5.00

‘需要使用一个自动化服务器和一个ActiveX控件支持本例子。

Object = "{0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}#1.0#0"; "MSSCRIPT.OCX"

Begin VB.Form Form1

Caption = "具有脚本支持功能的演示系统"

ClientHeight = 4335

ClientLeft = 60

ClientTop = 345

ClientWidth = 4680

LinkTopic = "Form1"

ScaleHeight = 4335

ScaleWidth = 4680

StartUpPosition = 3 'Windows Default

Begin VB.TextBox Text2

Height = 1095

Left = 120

MultiLine = -1 'True

TabIndex = 2

Text = "vbscript.frx":0000

‘用户可以通过脚本代码窗输入控制此对象的属性的代码(我的对象名字为MyBox),也可以通过WORD对象来启动并控制您系统中的Office Word

ToolTipText = “在脚本代码框中输入代码以控制本对象的属性 ”

Top = 3120

Width = 2415

End

Begin VB.TextBox Text1

Height = 2295

Left = 120

MultiLine = -1 'True

ScrollBars = 3 'Both

TabIndex = 1

Text = "‘在此输入脚本代码"

ToolTipText = " 你可以在代码中控制两个本系统提供的对象:WORD和MyBox。"

Top = 480

Width = 4335

End

Begin VB.CommandButton Command1

Caption = "执行脚本代码"

BeginProperty Font

Name = "MS Sans Serif"

Size = 9.75

Charset = 0

Weight = 400

Underline = 0 'False

Italic = 0 'False

Strikethrough = 0 'False

EndProperty

Height = 735

Left = 2760

TabIndex = 0

Top = 3480

Width = 1815

End

‘脚本对象的缺省属性

Begin MSScriptControlCtl.ScriptControl ScriptControl1

Left = 0

Top = 2160

_ExtentX = 1005

_ExtentY = 1005

AllowUI = -1 'True

End

Begin VB.Label Label1

Caption = "请在此输入您的VB代码"

BeginProperty Font

Name = "MS Sans Serif"

Size = 9.75

Charset = 0

Weight = 400

Underline = 0 'False

Italic = 0 'False

Strikethrough = 0 'False

EndProperty

Height = 255

Left = 120

TabIndex = 3

Top = 120

Width = 3255

End

End

Attribute VB_Name = "Form1"

Attribute VB_GlobalNameSpace = False

Attribute VB_Creatable = False

Attribute VB_PredeclaredId = True

Attribute VB_Exposed = False

Private Sub Command1_Click()‘当点击Command1 时

ScriptControl1.ExecuteStatement Text1.Text‘解释并执行脚本

End Sub

Private Sub Form_Load() ‘窗体载入时

Dim ob As Object ‘定义一个对象变量

Set ob = CreateObject("Word.Application")‘创建一个自动化对象,引用编程ID

ScriptControl1.State = Connected‘设置脚本控件的状态

ScriptControl1.AddObject "WORD", ob ‘向脚本对象加入一个可接收的对象“WORD”

ScriptControl1.AddObject "MyBox", Text2 ‘加入一个本窗体的VB基本控件TextBox

End Sub

实例的运行要求:VB6.0、Pwin98,并且原则上要求您的系统中安装Word97,但如果您可以将Form_Load()中的CreateObject("Word.Application")语句修改,把“Word.Application”(Word97的在注册表中的ProgID)替换成任何您系统中现有的任何自动化对象的ProgID。在启动本例子后你可以在脚本输入框中输入如下代码以观察效果,也可以在了解脚本提供的对象的属性和方法基础上写入您自己的任何代码:

Word.visible =True ‘使Word对象显现,跟通过常规方法启动它一样使用它。

MyBox.Text =“这是在脚本中设置的内容”

补充几点
关于宿主提供的对象。
可以在编写宿主时添加任何自定义的对象,在本例这些对象可以是VB编写的对象、VB提供的控件(包括ActiveX控件)、系统中存在的自动化对象(甚至您用其它诸如Delphi等编写的控件、COM对象),但对于自定义对象必须用AddObject方法加入到脚本控件Modules。

对运行时对象的控制
在使用Object.xxx形式引用对象的方法和属性时必须要确认所输入代码的有效性。所谓“有效性”是指在脚本控件解释这些代码时所引用的属性、方法等必须可用或有效(有些属性只读或只写,有写方法在某些状态下不能调用),不能出现拼写错误。本例子未进行错误捕获,感兴趣大家可以自行设计。

C++中的脚本引擎利用
除了在VB中可以使用ScriptControl外还可以在C++中使用它。Visual Studio97中使用脚本功能必须实现一些特殊的接口,比较繁琐,利用此控件可以省下脚本支持接口方面的周折。我们开发的很多自主软件都没有利用脚本支持功能,导致软件使用和二次开发不便,例如WPS97就没有类似Word97的宏功能,应该说是我们国产软件同世界软件之间的一个差距(因手头没有 WPS2000,所以无法对其进行评论)。一般现在开发软件利用C++可以方便的实现COM,可以利用脚本控件轻松实现脚本支持,为自己的软件增色,何乐而不为呢?

以上抛砖引玉,希望得到同仁的指教,也希望能够看到有关的国产软件加入脚本实现功能,让广大用户来参与开发,毕竟“人民群众的力量是无穷的”!

--

1999年写的,对脚本技术挺感兴趣

0 0

相关博文

我的热门文章

img
取 消
img