The ActiveX Scripting Engine

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.

Registry Standard

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().

Script Engine States

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:

A Word About Threading

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.

For Scripting Engine Implementers

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:

For Scripting Hosts

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.

Script Thread Execution States

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.

IActiveScript

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);
  };

SetScriptSite


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.

pScriptSite
The host-supplied script site to be associated with this instance of the scripting engine. This site must be uniquely assigned to this scripting engine instance; it cannot be shared with other scripting engines.

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.)

GetScriptSite


HRESULT IActiveScript::GetScriptSite(
  [in]  REFIID iid, 
  [out] void **ppvSiteObject);

Retrieves the site object associated with the ActiveX Scripting engine.

iid
The IID of the requested interface.
ppvSiteObject
The returned interface pointer to the site object.

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.

GetScriptState


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.

pss
Returned state of the indicated thread, as follows:
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.

SetScriptState


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.

ss
Sets the scripting engine to the given state:
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).

Close


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).

AddNamedItem


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.

pstrName
Name of the item as viewed from the script. Must be unique and persistable.
dwFlags
Flags associated with item. The following flags are defined:
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.

AddTypeLib


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.

guidTypeLib
LIBID of the Type library to add.
dwMaj
Major version number.
dwMin
Minor version number.
dwFlags
Option flags:
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.

GetScriptDispatch


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.

pstrItemName
The Named Item for which the caller wants the associated dispatch object. NULL indicates a global dispatch object, if supported.
ppdisp
The returned object associated with the script's global methods/properties. If the scripting engine does not support such an object, NULL is returned.

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.

GetCurrentScriptThreadID


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).

pstidThread
Returned script thread ID associated with the current thread. The interpretation of this identifier is left to the scripting engine, and may in fact, just be a copy of the Windows thread id. Note that if the Win32 thread terminates, this ID becomes unassigned and may subsequently be assigned to another thread. 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_POINTER An invalid pointer was passed.

GetScriptThreadID


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).

dwWin32ThreadID
The thread ID of a running Win32 thread in the current process. Use GetCurrentThreadID() for this parameter to get the thread ID of the currently executing thread.
pstidThread
Returned script thread ID associated with the indicated Win32 thread. The interpretation of this identifier is left to the scripting engine, and may in fact, just be a copy of the Windows thread id. Note that if the Win32 thread terminates, this ID becomes unassigned and may subsequently be assigned to another thread. 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_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).

GetScriptThreadState


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.

stidThread
Thread ID of the thread for which the state is desired. The following special thread IDs can be used:
SCRIPTTHREADID_CURRENT The currently executing thread.
SCRIPTTHREADID_BASE The base thread (the thread in which the scripting engine was instantiated).
pstsState
Returned state of the indicated thread, as follows:
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).

InterruptScriptThread


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.

stidThread
Thread ID of thread to interrupt. The following special thread IDs can be used:
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.
pexcepinfo
Error information associated with the error condition (for macro invocations and immediate execution, this is returned to the caller).
dwFlags
Option flags associated with the interruption.
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).

Clone


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.

ppscript
The returned, unsited, cloned scripting engine. The host must create a site and call SetScriptSite() on the new scripting engine before it will be in the initialized state and, therefore, usable.

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).

IActiveScriptParse

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);
  };

InitNew


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.

AddScriptlet


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'").

pstrDefaultName
A default name to associate with the scriptlet. If the scriptlet does not contain naming information (as in the ONCLICK example above), this name will be used to identify the scriptlet. If this parameter is NULL, the scripting engine will manufacture a unique name if necessary.
pstrCode
The scriptlet, in textual form, to add. The interpretation of this string is language dependent.
pstrItemName
Identifies the named item this scriptlet is associated with. This parameter, in addition to pstrSubItemName, identifies the specific object for which the scriptlet is an event handler.
pstrSubItemName
Identifies a sub-object of the named item with which this scriptlet is associated; this name must be found in the named item's type information. A NULL is passed if the scriptlet is to be associated with the named item instead of a sub-item. This parameter, in addition to pstrItemName, identifies the specific object for which the scriptlet is an event handler.
pstrEventName
Identifies the event for which the scriptlet is an event handler.
pstrEndDelimiter
When pstrCode is parsed from a stream of text, the host typically uses a delimiter, such as two single quotation marks ("), to detect the end of the scriptlet. The delimiter the host used is passed in here, so that the scripting engine can provide some conditional primitive preprocessing (for example, replacing a single quotation mark ['] with two single quotation marks for use as a delimiter). Exactly how (and if) the scripting engine makes use of this information is left to the scripting engine. NULL may be passed, indicating that the host did not use a delimiter to detect the end of the scriptlet.
dwFlags
Flags associated with the scriptlet:
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.
pbstrName
The actual name used to identify the scriptlet. This will be, in order of preference: a name explicitly specified in the scriptlet text, the default name provided in pstrDefaultName, or a unique name synthesized by the scripting engine.
pexcepinfo
Pointer to a structure containing exception information. This structure should be filled in if DISP_E_EXCEPTION is returned.

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.

ParseScriptText


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.

pstrCode
The scriptlet, in textual form, to evaluate. The interpretation of this string is language dependent.
pstrItemName
Identifies the context in which the scriptlet is to be evaluated. If NULL, then the code is evaluated in the scripting engine's global context.
punkContext
Reserved for use in a debugging environment, where such a context may be provided by the debugger to represent an active runtime context. If NULL, pstrItemName is used to identify the context.
pstrEndDelimiter
When pstrCode is parsed from a stream of text, the host typically uses a delimiter, such as two single quotation marks ("), to detect the end of the scriptlet. The delimiter the host used is passed in here, so that the scripting engine can provide some conditional primitive preprocessing (for example, replacing a single quotation mark ['] with two single quotation marks for use as a delimiter). Exactly how (and if) the scripting engine makes use of this information is left to the scripting engine. NULL may be passed, indicating that the host did not use a delimiter to detect the end of the scriptlet.
dwFlags
Flags associated with the scriptlet:
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.
pvarResult
Pointer to where the result is to be stored, or NULL if the caller expects no result (SCRIPTEXT_ISEXPRESSION is not set).
pexcepinfo
Pointer to a structure containing exception information. This structure should be filled in if DISP_E_EXCEPTION is returned.

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.

IActiveScriptError

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);
  };

GetExceptionInfo


  HRESULT GetExceptionInfo([out] EXCEPINFO *pexcepinfo);

Retrieves error information.

pexcepinfo
Points to an EXCEPINFO structure that contains error information.

Returns
S_OK Success.
E_FAIL An error occurred.

GetSourcePosition


  HRESULT GetSourcePosition(
    [out] DWORD *pdwSourceContext,
    [out] ULONG *pulLineNumber,
    [out] LONG  *pichCharPosition);

Retrieves the error location in the source code.

pdwSourceContext
Points to a cookie that identifies the context. (This interpretation of this parameter depends on the host application.)
pulLineNUmber
Points to a value that specifies the line number in the source file where the error occurred..
pichCharPosition
Points to a value that specifies the character position in the line where the error occurred..

Returns
S_OK Success.
E_FAIL An error occurred.

GetSourceLineText


  HRESULT GetSourceLineText([out] BSTR *pbstrSourceLine);

Retrieves the line in the sourcefile where an error occurred.

pbstrSourceLine
Points to the line of source code in which the error occurred.

Returns
S_OK Success.
E_FAIL An error occurred.

© 1996 Microsoft Corporation