词条 | ActiveX脚本编程 |
释义 | ActiveX scripting(ActiveX脚本编程) 一种使用脚本语言来驱动ActiveX组件的行为。 一、ActiveX Scripting 背景 ActiveX Scripting 技术是Microsoft ActiveX 技术的一个组成部分,它的主要目的是使应用程序在不被修改的情况下,可被各种脚本语言所控制。比如大家比较熟悉的Microsoft Office中的Word字处理软件,它提供了方便的BASIC语言的可编程特性,用户可以通过编写BASIC语言实现较为复杂的功能扩充。 二、ActiveX Scripting 的结构 从技术的角度来看,ActiveX Scripting脚本引擎实际上是一组COM接口,通过这组接口建立应用程序和脚本之间的关系。脚本引擎是ActiveX Scripting技术的实现,一个应用系统如果实现了有关的标准接口, 那么它就可以通过脚本引擎提供对脚本语言的支持。应用系统为了支持脚本语言,首先它要实现几个标准接口,然后它把自己的一些被控对象暴露出来;脚本文件是一个文本文件,文件中包含了一些程序代码;脚本引擎本身是一个COM 对象,它负责对脚本文件的解释和执行工作,在必要时通过应用系统的接口与其交互。 应用系统首先需要创建脚本引擎对象,并设置必要的参数,然后装入脚本文件,再启动引擎,使引擎进入连接状态(即运行脚本状态),通常我们通过用户显式操作(例如通过菜单命令或快捷键)完成启动操作;应用系统也可以终止引擎的运行,使其进入无连接状态。在引擎处于连接状态时,当特定的事件被激发时,脚本文件中的相应的事件控制函数会被执行;在引擎处于无连接状态时,即使有事件发生,脚本文件中的事件控制函数也不会被执行。 应用系统也需要实现一些接口,分别为:IActiveScriptSite和IActiveScriptSiteWindow(可选)。接口IActiveScriptSite是每一个支持脚本语言的应用系统所必须实现的接口,脚本引擎通过它来获取其宿主程序的信息,特别是在解释脚本语言中一些名字时更需要用到这些信息,IActiveScriptSite的接口定义如下: class IActiveScriptSite : public IUnknown { public : virtual HRESULT GetLCID( LCID *plcid) = 0; virtual HRESULT GetItemInfo( LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown *ppiunkItem, ITypeInfo *ppti) = 0; virtual HRESULT GetDocVersionString(BSTR *pbstrVersion) = 0; virtual HRESULT OnScriptTerminate(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo) = 0; virtual HRESULT OnStateChange( SCRIPTSTATE ssScriptState) = 0; virtual HRESULT OnScriptError( IActiveScriptError *pscripterror) = 0; virtual HRESULT OnEnterScript( void) = 0; virtual HRESULT OnLeaveScript( void) = 0; }; 在这些成员函数中,GetItemInfo是关键函数,因为脚本引擎管理了一个名字空间,脚本引擎在解释执行过程中,如果需要某个名字的信息,则通过宿主程序的IActiveScriptSite::GetItemInfo函数获取。所以,应用系统通过GetItemInfo成员函数把自己的一些对象暴露给脚本引擎,以便在脚本文件中引用。 IActiveScriptSiteWindow接口是一个可选的接口,如果在脚本文件中要用到用户接口UI特性,则应用系统应该实现IActiveScriptSiteWindow接口,其定义很简单,如下: class IActiveScriptSiteWindow : public IUnknown { public : virtual HRESULT GetWindow( HWND *phwnd ) = 0; virtual HRESULT EnableModeless( BOOL fEnable ) = 0; }; 脚本引擎通过GetWindow成员函数获取宿主窗口句柄,作为脚本中弹出窗口的父窗口。 除了应用系统需要实现上面两个接口用作它与脚本引擎之间的通讯之外,脚本引擎也实现了一组接口用作两者之间的通讯,这组接口包括:IActiveScript、IActiveScriptParse和其它一些用于调试、状态管理或者错误处理的接口,IActiveScript和IActiveScriptParse是必须实现的接口,以下是它们的定义: class IActiveScript : public IUnknown { public: virtual HRESULT SetScriptSite( IActiveScriptSite *pass) = 0; virtual HRESULT GetScriptSite( REFIID riid, void **ppvObject) = 0; virtual HRESULT SetScriptState( SCRIPTSTATE ss) = 0; virtual HRESULT GetScriptState( SCRIPTSTATE *pssState) = 0; virtual HRESULT Close( void) = 0; virtual HRESULT AddNamedItem( LPCOLESTR pstrName, DWORD dwFlags) = 0; virtual HRESULT AddTypeLib( REFGUID rguidTypeLib, DWORD dwMajor, DWORD dwMinor, DWORD dwFlags) = 0; virtual HRESULT GetScriptDispatch( LPCOLESTR pstrItemName, IDispatch **ppdisp) = 0; virtual HRESULT GetCurrentScriptThreadID( SCRIPTTHREADID *pstidThread) = 0; virtual HRESULT GetScriptThreadID( DWORD dwWin32ThreadId,SCRIPTTHREADID *pstidThread) = 0; virtual HRESULT GetScriptThreadState( SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState) = 0; virtual HRESULT InterruptScriptThread( SCRIPTTHREADID stidThread,const EXCEPINFO *pexcepinfo, DWORD dwFlags) = 0; virtual HRESULT Clone( IActiveScript **ppscript) = 0; }; class IActiveScriptParse : public IUnknown { public: virtual HRESULT InitNew( void) = 0; virtual HRESULT AddScriptlet( LPCOLESTR pstrDefaultName,LPCOLESTR pstrCode, LPCOLESTR pstrItemName, LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter, DWORD dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, BSTR *pbstrName, EXCEPINFO *pexcepinfo) = 0; virtual HRESULT ParseScriptText( LPCOLESTR pstrCode, LPCOLESTR pstrItemName,IUnknown *punkContext, LPCOLESTR pstrDelimiter,DWORD dwSourceContextCookie, ULONG ulStartingLineNumber,DWORD dwFlags, VARIANT *pvarResult,EXCEPINFO *pexcepinfo) = 0; }; 应用系统通过IActiveScript接口控制脚本引擎的各种行为,也可以获取引擎的各种状态。通常,应用系统首先调用IActiveScript::SetScriptSite成员函数把自身实现的IActiveScriptSite接口传递给引擎,以后引擎就通过该接口与应用系统通讯。而应用系统也可以通过IActiveScript的其它成员函数获取或者设置引擎的运行状态。接口IActiveScriptParse用于对脚本代码的操作,应用系统利用IActiveScriptParse接口装入脚本代码。 在介绍了应用系统和脚本引擎所实现的一些关键接口之后,我们再进一步看看应用系统和脚本引擎的协作过程: (1)创建必要的受控对象,这些受控对象是指将要在脚本文件中引用到的Automation对象,通常是应用系统的文档对象,也可以是某些ActiveX控制; (2)创建引擎对象,不同的脚本语言使用不同的引擎对象,通常我们使用VBScript引擎或者JavaScript引擎,创建得到的接口指针是应用系统控制引擎的惟一途径; (3)装入脚本文件,调用引擎的IActiveScriptParse接口的ParseScriptText成员函数把脚本代码装入到引擎中,注意ParseScriptText成员函数只接收UNICODE字符串,如果程序中用到了ANSI字符串,则需要进行转换才能装入到引擎中; (4)加入名字项,凡是应用系统中要暴露给脚本文件的所有对象都需要加入到引擎的名字空间中,可以通过调用IActiveScript接口的AddNamedItem成员函数来完成; (5)启动引擎,以便运行脚本,直接调用IActiveScript::SetScriptState成员函数使其进入连接状态(运行状态)即可; (6)引擎在执行脚本时,首先处理其名字空间中的名字项,调用应用系统IActiveScriptSite接口的GetItemInfo成员函数获取每一个名字所对应的受控对象的信息,主要是COM接口;如果在脚本中有事件控制函数的话,则还要获取受控对象的类型信息; (7)在脚本执行过程中,当特定的事件发生时,引擎中的事件控制函数就要被调用; (8)在脚本执行过程中,有可能会调用到受控对象的属性和方法,则引擎会通过它所获取的对象接口调用IDispatch::Invoke成员函数; 如果应用系统希望终止引擎的执行过程,可以调用IActiveScript::SetScriptState成员函数使其进入非运行状态即可。 以上的步骤基本上反映了应用系统和引擎之间的协作过程。在实际使用过程中,可以根据情况的不同灵活应用。 |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。