To write an ActiveX Scripting engine, write an OLE COM object supporting the interfaces listed below:
Interface | Required? | Description |
IActiveScript | Yes | Basic scripting ability. |
IPersist* | Yes. At least one of the following(*) | Persistence support. |
IPersistStorage | DATA={url} syntax for OBJECT tag. | |
IPersistStreamInit | Same as above, as well as DATA="string-encoded byte stream" syntax for OBJECT tag. | |
IPersistPropertyBag | PARAM= syntax for OBJECT tag. | |
IActiveScriptParse | No | Ability to add script text, evaluate expressions, and so on. |
Support for the IActiveScriptParse interface is optional; however, if it is not supported, the script engine must implement some sort of IPersist* interface in order to load a given script.
An ActiveX Scripting engine can identify itself using Component Categories. ActiveX Scripting currently defines two Component Categories:
CATID_ActiveScript | Indicates the CLSIDs are ActiveX Scripting engines that support, at a minimum, IActiveScript and a persistence mechanism (IPersistStorage, IPersistStreamInit, or IPersistPropertyBag). |
CATID_ActiveScriptParse | Indicates the CLSIDs are ActiveX Scripting engines that support, at a minimum, IActiveScript and IActiveScriptParse. |
Although IActiveScriptParse is not a true persistence mechanism, it does support an InitNew() method which is functionally equivalent to IPersist*::InitNew().
An ActiveX Scripting engine can be in one of several general states:
Uninitialized | The script has not yet been initialized or loaded using an IPersist interface, or does not have an IActiveScriptSiteset. The scripting engine is generally not usable from this state until steps are taken to initialize the scripting engine. |
Initialized | The script has been initialized with an IPersist interface and has an IActiveScriptSite set, but is not connected to host objects and sinking events. Note that this state simply means that IPersist*::Load(), IPersist*::InitNew(), or IActiveScriptParse::InitNew() has been completed, and IActiveScript::SetScriptSite() has been called. No code can run in this mode. Code that is executed via IActiveScriptParse::ParseScriptText() is queued and executed after the transition to the started state. |
Started | The transition from the initialized state to started state causes any code that was queued in the initialized state to execute. When in this state, code can execute, but the scripting engine is not connected to events of the objects added via IActiveScript::AddNamedItem(). Thus, code can be executed by calling IDispatch obtained from IActiveScript::GetScriptDispatch() or by calling IActiveScriptParse::ParseScriptText(). It is possible that further background initialization (progressive loading) is still ongoing, and that calling SetScriptState(SCRIPTSTATE_CONNECTED) may cause the script to block until initialization is complete. |
Connected | The script is loaded and connected for sinking events from host objects. |
Disconnected | The script is loaded and has a runtime state, but is temporarily disconnected from sinking events from host objects. This state is distinguished from the initialized state in that the transition to this state does not cause the script to reset, the runtime state of the script is not reset, and a script initialization procedure is not executed |
Closed | The script has been closed. The scripting engine will no longer work and will return errors for most methods. |
These states are entered via the following methods:
The scripting engine performs the following actions on the given transitions:
Because an ActiveX Scripting engine can be used in many environments, it is important to keep its execution model as flexible as possible. For example, server-based hosts may have a multithreaded design that they want to preserve while using ActiveX Scripting in a efficient manner. At the same time, hosts that do not care about threading, such as a typical application, should not be burdened with threading management. ActiveX Scripting achieves this balance by restricting the ways a free-threaded scripting engine may call back to the host, freeing hosts from this burden.
Scripting engines used on servers are typically implemented as free-threading COM objects. This means that methods on IActiveScript (and its associated interfaces) may be called from any thread in the process, without marshaling(**). Synchronization is the responsibility of the scripting engine. For scripting engines that are not internally reentrant, or for language models that are not multithreaded, synchronization could be as simple as serializing access to the scripting engine with a mutex. Of course, certain member functions, such a InterruptScriptThread(), should not be serialized in this way, so that a stuck script can be terminated from another thread.
The fact that IActiveScript is free-threaded generally implies that IActiveScriptSite and the host's object model should be free-threaded as well. This would make implementation of the host quite difficult, particularly in the common case where the host is a single-threaded Windows application with single-threaded or apartment-model OLE Controls in its object model. For this reason, the following constraints are placed on the scripting engine's use of IActiveScriptSite:
Scripting Engine Rules:
The host can safely assume that IActiveScriptSite will only be called in the context of the base thread, as long as it obeys the following rules:
Scripting Host Rules:
Note that these rules are automatically followed by all single-threaded hosts. The restricted model described above is intentionally loose enough to allow a host to abort a stuck script by calling InterruptScriptThread() from another thread (initiated by a CTRL-BREAK handler or the like), or to duplicate a script in a new thread using Clone().
Note that none of these restrictions apply to a host that chooses to implement a free-threaded IActiveScriptSite and a free-threaded object model. Such a host may use IActiveScript from any thread, without restriction.
Each script thread(***) can be in one of several execution states:
NotInScript | The thread is not currently running in a script (sinking a scripted event, processing ParseScriptText(), or being called through a global script function published through GetScriptDispatch()). |
Running | The thread is currently executing script code. |
The scripting engine must implement this interface in order to be an ActiveX Scripting engine.
Interface IActiveScript : IUnknown { HRESULT SetScriptSite([in] IActiveScriptSite *pScriptSite); HRESULT GetScriptSite([in] REFIID iid, [out] void **ppvScriptSite); HRESULT SetScriptState([in] SCRIPTSTATE ss); HRESULT GetScriptState([out] SCRIPTSTATE *pss); HRESULT Close(); HRESULT AddNamedItem([in] LPCOLESTR pstrName, [in] DWORD dwFlags); HRESULT AddTypeLib([in] REFGUID guidTypeLib, [in] WORD wMaj, [in] WORD wMin, [in] DWORD dwFlags); HRESULT GetScriptDispatch([in] LPCOLESTR pstrItemName, [out] IDispatch **ppdisp); HRESULT GetCurrentScriptThreadID([out] SCRIPTTHREADID *pstid); HRESULT GetScriptThreadID([in] DWORD dwWin32ThreadID, [out] SCRIPTTHREADID *pstid); HRESULT GetScriptThreadState([in] SCRIPTTHREADID stid, [out] SCRIPTTHREADSTATE *psts); HRESULT InterruptScriptThread([in] SCRIPTTHREADID stid, [in] EXCEPINFO *pei, [in] DWORD dFlags); HRESULT Clone([out] IActiveScript **ppscript); };
HRESULT IActiveScript::SetScriptSite([in] IActiveScriptSite *pScriptSite);
Informs the scripting engine of the IActiveScriptSite site provided by the host. This method must be called before any other IActiveScript methods may be used.
Returns
S_OK | Success. |
E_POINTER | An invalid pointer was passed. |
E_INVALIDARG | An invalid argument was passed. |
E_FAIL | Unspecified error. The scripting engine was unable to complete its site initialization. |
E_UNEXPECTED | The call was not expected. (for example, a site has already been set.) |
HRESULT IActiveScript::GetScriptSite( [in] REFIID iid, [out] void **ppvSiteObject);
Retrieves the site object associated with the ActiveX Scripting engine.
Returns
S_OK | Success. |
S_FALSE | Success, but no site has yet been set, so ppvSiteObject is NULL. |
E_POINTER | An invalid pointer was passed. |
E_INVALIDARG | An invalid argument was passed. |
E_NOINTERFACE | The specified interface is not supported. |
HRESULT IActiveScript::GetScriptState([out] SCRIPTSTATE *pss);
Returns the current state of the scripting engine. This method may be called from non-base threads without resulting in a non-base callout to host objects or to IActiveScriptSite.
SCRIPTSTATE_UNINITIALIZED | The script has just been created and has not yet been initialized using an IPersist interface and IActiveScript::SetScriptSite(). |
SCRIPTSTATE_INITIALIZED | The script has been initialized, but is not running (connecting to other objects, sinking events) or executing any code. Code can be queried for execution via IActiveScriptParse::ParseScriptText(). |
SCRIPTSTATE_STARTED | The script can execute code, but is not yet sinking the events of objects added via IActiveScript::AddNamedItem(). |
SCRIPTSTATE_CONNECTED | The script is loaded and connected for sinking events. |
SCRIPTSTATE_DISCONNECTED | The script is loaded and has a runtime execution state, but is temporarily disconnected from sinking events. |
SCRIPTSTATE_CLOSED | The script has been closed. The scripting engine will no longer work and will return errors for most methods. |
Returns
S_OK | Success. |
E_POINTER | An invalid pointer was passed. |
HRESULT IActiveScript::SetScriptState([in] SCRIPTSTATE ss);
Puts the scripting engine into the given state. This method may be called from non-base threads without resulting in a non-base callout to host objects or to IActiveScriptSite.
SCRIPTSTATE_INITIALIZED | Returns the scripting engine back to the initialized state (from started, connected, or disconnected). Because languages can vary widely in semantics, scripting engines are not required to support this state transition. (Engines that support IActiveScript::Clone() must, however, support this state transition.) Hosts must prepare for this and take the equivalent action: Release() the current scripting engine, create a new scripting engine, and Load() or InitNew() (and possibly also call ParseScriptText()). Use of this transition should be considered an optimization of the above steps. Note that any information the scripting engine has obtained about the names of Named Items and the type information describing Named Items remains valid.
Because languages vary widely, defining the exact semantics of this transition is difficult. Minimally, the scripting engine must disconnect from all events, and release all of the SCRIPTINFO_IUNKNOWN pointers obtained via IActiveScriptSite::GetItemInfo(). These pointers must be refetched after the script is run again. The scripting engine should also reset the script back to an initial state that is appropriate for the language. VBScript, for example, will reset all variables, and retain any code added dynamically via IActiveScriptParse with the SCRIPTTEXT_ISPERSISTENT flag set. Other languages may choose to retain current values (such as Lisp because there is no code/data separation) or reset to a well-known state (this includes languages with statically initialized variables). These languages may or may not retain code added via IActiveScriptParse. Note that the transition to the started state should have the same semantics (that is, it should leave the scripting engine in the same state) as IPersist::Save()-ing the scripting engine and then IPersist::Load()-ing a new scripting engine; these actions should have the same semantics as IActiveScript::Clone(). Scripting engines that do not yet support Clone() or IPersist* should carefully consider how the transition to the started state should behave, so that such a transition would not violate the above conditions if Clone() or IPersist* support were later added. During this transition to the started state, the scripting engine will disconnect from event sinks after the appropriate destructors, and so on, are executed in the script. To avoid having these destructors executed, the host can first move the script into the disconnected state before moving into the started state. Use InterruptScriptThread() to cancel a running script thread without waiting for current events, and so on, to finish running. |
SCRIPTSTATE_STARTED | The transition to this mode causes any code that was queued during the initialized state to be executed. From this state, script code may be executed, for example, by calling IActiveScriptParse::ParseScriptText() or by calling the IDispatch obtained from IActiveScript::GetScriptDispatch(). The transition to this state is also the appropriate time to execute routines such as a main()-like script routine, if appropriate for the script language. |
SCRIPTSTATE_CONNECTED | Causes the script to connect to events. If this is a transition from the initialized state, the scripting engine should transition through the started state, performing the necessary actions, before entering the connected state and connecting to events. |
SCRIPTSTATE_DISCONNECTED | Causes the script to disconnect from event sinks. This can be done either logically (ignoring events received), or physically (calling Unadvise() on the appropriate connection points). Returning to the connected state reverses this process. If this is a transition from the initialized state, the scripting engine should transition through the started state, performing the necessary actions, before entering the disconnected state. Event sinks that are in progress are completed before the state changes (use InterruptScriptThread() to cancel a running script thread). The script's execution state is maintained. For example, an HTML browser may put the scripting engine into this state when a scripted HTML page is moved into the LRU cache, before the page is actually destroyed. |
Returns
S_OK | Success, the script has entered the given state. |
S_FALSE | Success, but the script was already in the given state. |
OLESCRIPT_S_PENDING | The function was queued successfully, but the state hasn't changed yet. When the state changes, the site will be called back on IActiveScriptSite::OnStateChange(). |
E_FAIL | The scripting engine does not support the transition back to the initialized state. The host must discard this scripting engine and create, initialize, and load a new scripting engine to achieve the same effect. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
HRESULT IActiveScript::Close();
Causes the scripting engine to abandon any currently loaded script, lose its state, and release any interface pointers it has to other objects, thus entering a closed state. Event sinks, immediately executed script text, and macro invocations that are already in progress are completed before the state changes (use InterruptScriptThread() to cancel a running script thread). This method must be called by the creating host before it calls Release() to prevent circular reference problems.
Returns
S_OK | Success, the script has been closed. |
S_FALSE | Success, but the script was already closed. |
OLESCRIPT_S_PENDING | The function was queued successfully, but the state hasn't changed yet. When the state changes, the site will be called back on IActiveScriptSite::OnStateChange(). |
E_UNEXPECTED | The call was not expected (for example, the scripting engine was already in the closed state). |
HRESULT IActiveScript::AddNamedItem( [in] LPCOLESTR pstrName, [in] DWORD dwFlags);
Adds a root-level name (an object with properties/methods, an event source, or both) to the scripting engine's name space.
SCRIPTITEM_ISPERSISTENT | Indicates that the item should be saved if the scripting engine is saved. Similarly, setting this flag indicates that a transition back to the initialized state should retain the item's name and type information (the scripting engine must, however, release all pointers to interfaces on the actual object). |
SCRIPTITEM_ISSOURCE | Indicates that the item sources events that the script can sink. Children (properties of the object that are in themselves objects) can also source events to the script. This is not recursive, but provides a convenient mechanism for the common case, for example, of adding a container and all of its member controls. |
SCRIPTITEM_ISVISIBLE | Indicates that the item's name is available in the namespace of the script, allowing access to the properties, methods, and events of the item. Because by convention, the properties of the item include the item's children, all child object properties and methods (and their children, recursively) will be accessible. |
SCRIPTITEM_GLOBALMEMBERS | Indicates that the item is a collection of global properties and methods associated with the script. Normally, a scripting engine would ignore the object name (other than for the purpose of using it as a cookie for IActiveScriptSite::GetItemInfo(), or for resolving explicit scoping) and expose its members as global variables and methods. This allows the host to extend the library (runtime functions and so on) available to the script. It is left to the scripting engine to deal with name conflicts (for example, when two SCRIPTITEM_GLOBALMEMBERS items have methods of the same name), although an error should not be returned because of this situation. |
SCRIPTITEM_NOCODE | Indicates that the item is simply a name being added to the script's name space, and should not be treated as a item for which code should be associated. For example, without this flag being set, VBScript will create a separate module for the named item, and C++ might create a separate wrapper class for the named item. |
SCRIPTITEM_CODEONLY | Indicates that the named item represents a code-only object, and that the host has no IUnknown to be associated with this code-only object. The host only has a name for this object. In object-oriented (C++-like) languages, this would create a class. Not all languages support this flag. |
Returns
S_OK | Success, named item has been added to the script's namespace. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
E_POINTER | An invalid pointer was passed. |
E_INVALIDARG | An invalid argument was passed. |
HRESULT IActiveScript::AddTypeLib( [in] REFGUID guidTypeLib, [in] DWORD dwMaj, [in] DWORD dwMin, [in] DWORD dwFlags);
Adds a type library to the namespace for the script. This is similar to #include in C/C++. It allows a set of predefined items (class definitions, typedefs, named constants, and so on) to be added to the runtime environment available to the script.
SCRIPTTYPELIB_ISCONTROL | Indicates that the type library describes an OLE Control used by the host. |
Returns
S_OK | Success, the specified type library has been added. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
TYPE_E_CANTLOADLIBRARY | The specified type library could not be loaded. |
E_INVALIDARG | An invalid argument was passed. |
HRESULT IActiveScript::GetScriptDispatch( [in] LPCOLESTR pstrItemName [out] IDispatch **ppdisp);
Returns the IDispatch for methods/properties associated with the running script itself. If NULL is passed for pstrItemName, this object contains as its members all of the global methods and properties defined by the script. Through this interface (and its associated ITypeInfo), the host can invoke script methods or view/modify script variables. Note that because methods and properties can be added via IActiveScriptParse, and so on, the IDispatch returned may dynamically support new methods and properties. Similarly, IDispatch::GetTypeInfo() should return a new, unique ITypeInfo when methods and properties are added. Note, however, that language engines must not change the IDispatch in an incompatible way with previous TypeInfos returned. That implies, for example, that DISPIDs will never be reused.
Returns
S_OK | Success. |
S_FALSE | The scripting engine does not support a dispatch object. NULL is returned in ppdisp. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
E_POINTER | An invalid pointer was passed. |
E_INVALIDARG | An invalid argument was passed. |
HRESULT IActiveScript::GetCurrentScriptThreadID( [out] SCRIPTTHREADID *pstidThread);
Returns a scripting-engine-defined identifier for the currently executing thread. This identifier can then be used in subsequent calls to script thread execution control methods (for example, InterruptScriptThread(), and so on).
Returns
S_OK | Success. |
E_POINTER | An invalid pointer was passed. |
HRESULT IActiveScript::GetScriptThreadID( [in] DWORD dwWin32ThreadID, [out] SCRIPTTHREADID *pstidThread);
Returns a scripting-engine-defined identifier for the currently executing thread. This identifier can then be used in subsequent calls to script thread execution control methods (for example, InterruptScriptThread(), and so on).
Returns
S_OK | Success. |
E_POINTER | An invalid pointer was passed. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
HRESULT IActiveScript::GetScriptThreadState( [in] SCRIPTTHREADID stidThread, [out] SCRIPTTHREADSTATE *pstsState);
Returns the current state of a script thread. Note that if this is not the current thread, the state may change at any time. This method may be called from non-base threads without resulting in a non-base callout to host objects or to IActiveScriptSite.
SCRIPTTHREADID_CURRENT | The currently executing thread. |
SCRIPTTHREADID_BASE | The base thread (the thread in which the scripting engine was instantiated). |
SCRIPTTHREADSTATE_NOTINSCRIPT | The specified thread is not currently servicing a scripted event, processing immediately executed script text, or running a script macro. |
SCRIPTTHREADSTATE_RUNNING | The specified thread is actively servicing a scripted event, processing immediately executed script text, or running a script macro. |
Returns
S_OK | Success. |
E_POINTER | An invalid pointer was passed. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
HRESULT IActiveScript::InterruptScriptThread( [in] SCRIPTTHREADID stidThread, [in] const EXCEPINFO *pexcepinfo, [in] DWORD dwFlags);
Interrupts the execution of a running script thread (either an event sink, an immediate execution, or a macro invocation). This method can be used to terminate a script that is stuck (for example, in an infinite loop). It may be called from non-base threads without resulting in a non-base callout to host objects or to IActiveScriptSite.
SCRIPTTHREADID_CURRENT | The currently executing thread. |
SCRIPTTHREADID_BASE | The base thread (the thread in which the scripting engine was instantiated). |
SCRIPTTHREADID_ALL | All threads. The interrupt is applied to all script methods currently in progress. Note that unless the caller has requested that the script be disconnected (with SetScriptState() to SCRIPTSTATE_DISCONNECTED or _INITIALIZED), the next scripted event will cause script code to run again. |
SCRIPTINTERRUPT_DEBUG | If supported, enter the scripting engine's debugger at the current script execution point. |
SCRIPTINTERRUPT_RAISEEXCEPTION | If supported by the scripting engine's language, let the script handle the exception. Otherwise, the script method is aborted and the error code is returned to the caller (the event source or macro invoker). |
Returns
S_OK | Success, indicated thread will be interrupted. |
E_POINTER | An invalid pointer was passed. |
E_INVALIDARG | An invalid argument was passed. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
HRESULT IActiveScript::Clone([out] IActiveScript **ppscript);
Clones the current scripting engine (minus any current execution state), returning a loaded, unsited scripting engine in the current thread. The state of this new scripting engine should be identical to the state the original scripting engine would be in if it were transitioned back to the initialized state. Note that Clone() is an optimization of IPersist*::Save(), CoCreateInstance(), and IPersist*::Load(), so the state of the new scripting engine should be the same as if the state of the original scripting engine were saved and loaded into a new scripting engine. Named items will be duplicated in the cloned scripting engine, but specific object pointers for each item will be forgotten and will be obtained with GetItemInfo(). This allows an identical object model with per-thread entry points (an apartment model) to be used. This method is used for multithreaded server hosts that may run multiple instances of the same script. The scripting engine may return E_NOTIMPL, in which case the host can achieve the same result by duplicating the persistent state and creating a new instance of the scripting engine with IPersist*. This method may be called from non-base threads without resulting in a non-base callout to host objects or to IActiveScriptSite.
Returns
S_OK | Success. |
E_NOTIMPL | Method not supported. |
E_POINTER | An invalid pointer was passed. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
If the ActiveX Scripting engine allows raw text code scriptlets to be added to the script, or allows expression text to be evaluated at runtime, it implements IActiveScriptParse. For interpreted scripting languages that have no independent authoring environment, such as Visual Basic Script, this provides an alternate mechanism (other than IPersist) to get script code into the scripting engine, and to attach script fragments to various object events.
Interface IActiveScriptParse : IUnknown { HRESULT InitNew(); HRESULT AddScriptlet( [in] LPCOLESTR pstrDefaultName, [in] LPCOLESTR pstrCode, [in] LPCOLESTR pstrItemName, [in] LPCOLESTR pstrSubItemName, [in] LPCOLESTR pstrEventName, [in] LPCOLESTR pstrEndDelimiter, [in] DWORD dwFlags, [out] BSTR *pbstrName, [out] EXCEPINFO *pexcepinfo); HRESULT ParseScriptText( [in] LPCOLESTR pstrCode, [in] LPCOLESTR pstrItemName, [in] IUnknown *punkContext, [in] LPCOLESTR pstrEndDelimiter, [in] DWORD dwFlags, [out] VARIANT *pvarResult, [out] EXCEPINFO *pexcepinfo); };
HRESULT IActiveScriptParse::InitNew();
Before the scripting engine may be used, one of the following methods must be called: IPersist*::Load(), IPersist*::InitNew(), or IActiveScriptParse:: InitNew(). The semantics of this method are identical to IPersistStreamInit::InitNew(), in that this method tells the scripting engine to initialize itself. Note that it is not valid to call both InitNew() and Load(), nor is it valid to call InitNew() or Load() more than once.
Returns
S_OK | Success, the scripting engine has been initialized. |
E_FAIL | An error occurred during initialization. |
HRESULT IActiveScriptParse::AddScriptlet( [in] LPCOLESTR pstrDefaultName, [in] LPCOLESTR pstrCode, [in] LPCOLESTR pstrItemName, [in] LPCOLESTR pstrSubItemName, [in] LPCOLESTR pstrEventName, [in] LPCOLESTR pstrEndDelimiter , [in] DWORD dwFlags, [out] BSTR *pbstrName, [out] EXCEPINFO *pexcepinfo);
Adds a code scriptlet to the script. This method is used in environments where the persistent state of the script is intertwined with the host document and must be restored under the host's control, rather than though IPersist. The primary examples are HTML scripting languages that allow scriptlets of code imbedded in the HTML document to be attached to intrinsic events (for example, ONCLICK="button1.text='Exit'").
SCRIPTTEXT_ISVISIBLE | Indicates that the script text should be visible (and, therefore, callable by name) as a global method in the namespace of the script. |
SCRIPTTEXT_ISPERSISTENT | Indicates that the code added during this call should be saved if the scripting engine is saved, such as via IPersist*::Save(), or if the scripting engine is reset via a transition back to the initialized state. Indicates that the script text should be visible (and, therefore, callable by name) as a global method in the namespace of the script. |
Returns
S_OK | Success, the scriptlet has been added to the script, and its name is returned in pbstrName. |
OLESCRIPT_E_INVALIDNAME | The default name supplied is invalid in this scripting language. |
OLESCRIPT_E_SYNTAX | There was a unspecified syntax error in the scriptlet. |
DISP_E_EXCEPTION | An exception occurred in the parsing of the scriptlet. Exception information is returned in pexcepinfo. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine has not yet been loaded or initialized). |
E_NOTIMPL | Method is not supported, the scripting engine does not support adding event-sinking scriptlets. |
E_POINTER | An invalid pointer was passed. |
E_INVALIDARG | An invalid argument was passed. |
HRESULT IActiveScriptParse::ParseScriptText( [in] LPCOLESTR pstrCode, [in] LPCOLESTR pstrItemName, [in] IUnknown *punkContext, [in] LPCOLESTR pstrEndDelimiter, [in] DWORD dwFlags, [out] VARIANT *pvarResult, [out] EXCEPINFO *pexcepinfo);
Parses the given code scriptlet, adding declarations into the name space and evaluating code as appropriate. If the scripting engine is in the initialized state, no code will actually be evaluated during this call, rather, such code is queued and executed when the scripting engine is transitioned into (or through) the started state. Because execution is not allowed in the initialized state, it is an error to call this method with the SCRIPTTEXT_ISEXPRESSION flag when in the initialized state. The scriptlet may be an expression, a list of statements, or anything allowed by the script language. For example, this method is used in the evaluation of the HTML <SCRIPT> tag, which allows statements to be executed as the HTML page is being constructed, rather than just compiling them into the script state. Note that the code passed to this method must be a valid, complete portion of code. For example, in VBScript it is illegal to call this method once with Sub Foo(x) and then a second time with End Sub. The parser must not wait for the second call to complete the subroutine, but rather must generate a parse error because a subroutine declaration was started but not completed.
SCRIPTTEXT_ISEXPRESSION | If the distinction between a computational expression and a statement is important but syntactically ambiguous in the script language, this flag specifies that the scriptlet is to be interpreted as an expression, rather than as a statement or list of statements. By default, statements are assumed unless the correct choice can be determined from the syntax of the scriptlet text. |
SCRIPTTEXT_ISPERSISTENT | Indicates that the code added during this call should be saved if the scripting engine is saved, such as via IPersist*::Save(), or if the scripting engine is reset via a transition back to the initialized state. |
SCRIPTTEXT_ISVISIBLE | Indicates that the script text should be visible (and, therefore, callable by name) as a global method in the namespace of the script. |
Returns
S_OK | Success, the expression or statement(s) have been evaluated. The result, if any, is returned in pvarResult. |
E_POINTER | An invalid pointer was passed. |
E_INVALIDARG | An invalid argument was passed. |
E_UNEXPECTED | The call was not expected (for example, the scripting engine is in the uninitialized or closed state, or the SCRIPTEXT_ISEXPRESSION flag was set and the scripting engine is in the initialized state). |
DISP_E_EXCEPTION | An exception occurred in the processing of the scriptlet. Exception information is returned in pexcepinfo. |
OLESCRIPT_E_SYNTAX | There was a unspecified syntax error in the scriptlet. |
E_NOTIMPL | The function is not supported. The scripting engine does not support run-time evaluation of expressions or statements. |
An object implementing this interface is passed to IActiveScriptSite::OnScriptError() whenever the scripting engine encounters an unhandled error. The host then calls methods on this object to obtain information about the error that ocurred.
Interface IActiveScriptError : IUnknown { HRESULT GetExceptionInfo([out] EXCEPINFO *pexcepinfo); HRESULT GetSourcePosition( [out] DWORD *pdwSourceContext, [out] ULONG *pulLineNumber, [out] LONG *pichCharPosition); HRESULT GetSourceLineText([out] BSTR *pbstrSourceLine); };
HRESULT GetExceptionInfo([out] EXCEPINFO *pexcepinfo);
Retrieves error information.
Returns
S_OK | Success. |
E_FAIL | An error occurred. |
HRESULT GetSourcePosition( [out] DWORD *pdwSourceContext, [out] ULONG *pulLineNumber, [out] LONG *pichCharPosition);
Retrieves the error location in the source code.
Returns
S_OK | Success. |
E_FAIL | An error occurred. |
HRESULT GetSourceLineText([out] BSTR *pbstrSourceLine);
Retrieves the line in the sourcefile where an error occurred.
Returns
S_OK | Success. |
E_FAIL | An error occurred. |