ActiveX腳本編程

ActiveX腳本編程

ActiveX Scripting 技術是Microsoft ActiveX 技術的一個組成部分,它的主要目的是使應用程式在不被修改的情況下,可被各種腳本語言所控制。比如大家比較熟悉的Microsoft Office中的Word字處理軟體,它提供了方便的BASIC語言的可程式特性,用戶可以通過編寫BASIC語言實現較為複雜的功能擴充。

基本介紹

  • 中文名:ActiveX腳本編程
  • 外文名:ActiveX script programming
  • 性質:技術的一個組成部分
  • 特點:可被各種腳本語言所控制
  • 優勢:控制函式
術語簡介,技術架構,實現方式,

術語簡介

ActiveX scripting(ActiveX腳本編程)
一種使用腳本語言來驅動ActiveX組件的行為。

技術架構

從技術的角度來看,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成員函式使其進入非運行狀態即可。
以上的步驟基本上反映了套用系統和引擎之間的協作過程。在實際使用過程中,可以根據情況的不同靈活套用。

相關詞條

熱門詞條

聯絡我們