What Is ActiveX Programming?
ActiveX Scripting technology is an integral part of Microsoft ActiveX technology. Its main purpose is to enable applications to be controlled by various scripting languages without modification. For example, the Word word processing software in Microsoft Office, which everyone is familiar with, provides convenient programmability of BASIC language, and users can implement more complex function expansion by writing BASIC language.
ActiveX script programming
- ActiveX scripting (ActiveX scripting)
- One use
- From a technical perspective, ActiveX Scripting
- The application system also needs to implement some interfaces, namely: IActiveScriptSite and IActiveScriptSiteWindow (optional). The interface IActiveScriptSite is an interface that every application system that supports a scripting language must implement. The script engine uses it to obtain information about its host program, especially when interpreting some names in the scripting language. This information is needed. as follows:
- 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;
- };
- Among these member functions, GetItemInfo is the key function because the script engine manages a namespace. During the execution of the script engine, if the information of a certain name is needed, it is obtained through the host program's IActiveScriptSite :: GetItemInfo function. Therefore, the application system exposes some of its own objects to the script engine through the GetItemInfo member function for reference in the script file.
- The IActiveScriptSiteWindow interface is an optional interface. If user interface UI features are to be used in a script file, the application system should implement the IActiveScriptSiteWindow interface. Its definition is simple, as follows:
- class IActiveScriptSiteWindow: public IUnknown
- {
- public:
- virtual HRESULT GetWindow (HWND * phwnd) = 0;
- virtual HRESULT EnableModeless (BOOL fEnable) = 0;
- };
- The script engine uses the GetWindow member function to obtain the host window handle as the parent window of the pop-up window in the script.
- In addition to the application system needing to implement the above two interfaces for communication between it and the script engine, the script engine also implements a set of interfaces for communication between the two. This set of interfaces includes: IActiveScript, IActiveScriptParse and others Interfaces for debugging, status management, or error handling. IActiveScript and IActiveScriptParse are the interfaces that must be implemented. The following are their definitions:
- 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, BSTRp * Info EXC
- virtual HRESULT ParseScriptText (LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown * punkContext, LPCOLESTR pstrDelimiter, DWORD dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, VARIANT * pvarResult, EXCEPINFO * pexcepinfo) = 0;
- };
- The application system controls various behaviors of the script engine through the IActiveScript interface, and can also obtain various states of the engine. Generally, the application system first calls the IActiveScript :: SetScriptSite member function to pass the IActiveScriptSite interface it implements to the engine, and the engine then communicates with the application system through this interface. The application system can also get or set the running status of the engine through other IActiveScript member functions. The interface IActiveScriptParse is used to operate the script code. The application system uses the IActiveScriptParse interface to load the script code.
- After introducing some of the key interfaces implemented by the application system and the script engine, let's take a closer look at the collaboration process between the application system and the script engine:
- (1) Create the necessary controlled objects. These controlled objects refer to the Automation objects to be referenced in the script file, usually the document objects of the application system, or some ActiveX controls;
- (2) Create engine objects. Different scripting languages use different engine objects. Usually we use VBScript engine or JavaScript engine. The created interface pointer is the only way to control the engine of the application system.
- (3) Load the script file and call the ParseScriptText member function of the engine's IActiveScriptParse interface to load the script code into the engine. Note that the ParseScriptText member function only accepts UNICODE strings. If ANSI strings are used in the program, conversion is required. Load into the engine;
- (4) Add a name item. All objects in the application system to be exposed to the script file need to be added to the engine's namespace. This can be done by calling the AddNamedItem member function of the IActiveScript interface;
- (5) Start the engine in order to run the script, and directly call the IActiveScript :: SetScriptState member function to enter the connection state (running state);
- (6) When the engine executes the script, it first processes the name items in its namespace and calls the GetItemInfo member function of the application's IActiveScriptSite interface to obtain the information of the controlled object corresponding to each name, mainly the COM interface. If there is an event control function, you also need to obtain the type information of the controlled object;
- (7) During the execution of the script, when a specific event occurs, the event control function in the engine will be called;
- (8) During the execution of the script, it is possible to call the properties and methods of the controlled object, and the engine will call the IDispatch :: Invoke member function through the object interface it gets;
- If the application system wishes to terminate the execution of the engine, it can call the IActiveScript :: SetScriptState member function to make it into a non-running state.
- The above steps basically reflect the collaborative process between the application system and the engine. In actual use, it can be flexibly applied according to different situations.