Objective Toolkit : Chapter 19 ActiveScript Hosting Framework : Using the ActiveScript Framework
Using the ActiveScript Framework
The following topics describe how to use the ActiveScript framework.
ActiveScript and Type-libraries
Objective Toolkit must link to the type library ScriptHost.tlb to compile correctly. By default, the ScriptHost type library is included as a resource in your application at resource ID 1. If you are building an application with its own type library, such as an automation server, put your type library as resource 1 and ScriptHost.tlb as resource 2. This can be done in the resource editor by importing the .tlb file as a custom resource of the type TYPELIB.
You need to explicitly load and register the ScriptHost.tlb. This can be done in your InitInstance() method as the following code snippet illustrates.
 
AfxOleRegisterTypeLib(m_hInstance, _AHost_tlid,
_T("MyApp.exe\\2"));
If you are using static linking, you need only to include ahostguid.h in your CWinApp-derived class cpp file:
 
#include "Toolkit\ActvHost\AhostGUID.h"
If your application is linking to the DLL version of Objective Toolkit, the GUID AHost_tlid is unresolved. Add the following includes to your CWinApp-derived class cpp file:
 
#include <initguid.h>
#include "Toolkit\ActvHost\AhostGUID.h"
To prevent the Objective Toolkit library from automatically including ScriptHost.tlb as resource
To prevent the Objective Toolkit library from automatically including ScriptHost.tlb as resource 1, insert:
 
#define SEC_NO_TLB
before any inclusion of:
 
#include "\Toolkit\SecRes.rc"
To incorporate scripting into your application
1. Setup your application as an OLE control container. The following lines should be added to your application’s InitInstance() method for this purpose.
 
BOOL CScriptApp::InitInstance()
{
. . .
 
// Initialize OLE libraries,
//a must for ActiveScript usage.
if (!AfxOleInit())
{
TRACE(_T("Failed to initialize OLE libraries\n"));
return FALSE;
}
SECAScriptOccManager *pScriptOccMgr =
new SECAScriptOccManager();
AfxEnableControlContainer( pScriptOccMgr );
2. Determine the window within which you want to host the script and multiply inherit it from IActiveScriptErrorHandler. For example,
 
class CDlgScript : public CDialog, public IActiveScriptErrorHandler
{
. . .
3. Override the HandleError() method defined by the IActiveScriptErrorHandler interface. For example,
 
HRESULT CDlgScript::HandleError(IActiveScriptError *pse)
{
. . .
4. Define the method that actually creates a script engine and executes a script. This function is application-specific and can be called in response to an application specific event. Assuming the script is run when the user presses a Run button, the handler might look something like this:
 
void CDlgScript::OnButtonRun()
{
SECAScriptHost* pScript =
new SECAScriptHost(this);
pScript->CreateScriptEngine(
SECAScriptHost::VBScript);
pScript->SetHostWindow(this);
The three lines of code shown above create a scripting host that implements the requisite IActiveScriptSite and IActiveScriptSiteWindow COM interfaces. The parameter to the SECAScriptHost constructor is a pointer to an error handler that implements the IActiveScriptErrorHandler interface. The script host forwards incoming error notifications to the error handler pointer. The call to the CreateScriptEngine() method calls CoCreateInstance() to create the COM object responsible for delivering the VBScript or JavaScript service, depending upon the parameter passed in. The call to SetHostWindow() sets the window that is hosting the script.
5. Create a form object and add it to the script’s name space as a top-level item. This step also establishes the connection between the script and the form that it runs within.
 
SECAFormObj* pForm=new SECAFormObj;
LPDISPATCH pFormDisp =
pForm->GetIDispatch(FALSE);
CString strForm = _T("DemoForm");
BSTR bstrForm = strForm.AllocSysString();
pScript->AddTopLevelItem(bstrForm, pFormDisp);
::SysFreeString(bstrForm);
6. Load and parse the actual script. For example,
 
CString strScript=m_strEditScript;
UINT nSize=strScript.GetLength();
pScript->ParseBuffer(strScript,nSize);
7. Execute the script. For example,
 
pScript->SetScriptState(SCRIPTSTATE_CONNECTED);
pForm->FireOnLoad();
Once the execution is completed, the control returns to the statement following call to the FireOnLoad() method.
8. Perform cleanup operations—close the form, destroy the script engine, and release the VBScript host and form COM objects.
 
pForm->FireOnUnload();
pScript->DestroyScriptEngine();
pFormDisp->Release();
pScript->Release();