⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scriptenginefactory.cpp

📁 《深入剖析visual c++编程技术vcCode(人民邮电)》的源代码
💻 CPP
字号:
// ScriptEngineFactory.cpp: implementation of the ScriptEngineFactory class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ScriptEngineFactory.h"

#include "ExposedObject.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ScriptEngineFactory* ScriptEngineFactory::m_Instance = NULL;

ScriptEngineFactory::ScriptEngineFactory()
{
	m_iActiveScript           = NULL;
	m_iActiveScriptParse      = NULL;
	m_pScriptDispatch         = NULL;
}

ScriptEngineFactory::~ScriptEngineFactory()
{
}

ScriptEngineFactory* ScriptEngineFactory::Instance()
{
	if (m_Instance == NULL) {
		// Initialize singleton
		m_Instance = new ScriptEngineFactory;
	}

	return m_Instance;
}

BOOL ScriptEngineFactory::HRVerify(HRESULT hr, CString msg)
{
	// If we have a failure, add the error string including
	// hr value to the errormessages array of the scriptsite
	if (FAILED(hr)) {
		CString		str;

		str.Format("COM Error: 0x%08lx\n", hr);
		str += msg;
		m_ScriptSite.m_ErrorMessages.Add(msg);

		return FALSE;
	}

	return TRUE;
}

void ScriptEngineFactory::AddExposedObjectPtr(CString newObjectName, IUnknown* newExposedObject)
{
	//使用字符串转换宏
	USES_CONVERSION;
	HRESULT				hr;
	CString				str;
	ExposedObject*		pObj = NULL;
	//为脚本引擎添加名字空间
	hr = m_iActiveScript->AddNamedItem(
		T2OLE(newObjectName), 
		SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
	str.Format("Could not add Exposed-Script-Object [%s]", newObjectName);
	HRVerify(hr, str);
	//设置暴露对象信息
	pObj = new ExposedObject;
	pObj->SetExposedObject(newExposedObject);
	pObj->SetObjectName(newObjectName);
	//添加暴露对象
	m_ScriptSite.m_ExposedObjects.Add(pObj);
}

void ScriptEngineFactory::InitializeScriptEngine()
{
	int			index;
	HRESULT		hr;
	CLSID		clsid;
	CString		intMessage, extMessage;
	//删除错误信息
	m_ScriptSite.m_ErrorMessages.RemoveAll();
	//获取VBScript引擎的CLSID
	hr = CLSIDFromProgID(L"VBScript", &clsid);
	if (HRVerify(hr, "Scripting Engine (VBScript.dll) not registered") == FALSE) 
	{
		return;
	}
	//创建引擎接口
	hr = CoCreateInstance(
		clsid, NULL, CLSCTX_INPROC_SERVER, 
		IID_IActiveScript, (void**) &m_iActiveScript);
	if (HRVerify(hr, "Scripting Engine (VBScript.dll) not started") == FALSE) 
	{
		return;
	}
	
	//获取IActiveScriptParse接口
	hr = m_iActiveScript->QueryInterface(
		IID_IActiveScriptParse, (void**) &m_iActiveScriptParse);
	if (HRVerify(hr, "Scripting Engine Parser not available") == FALSE) 
	{
		m_iActiveScript->Release();
		m_iActiveScriptParse = NULL;
		m_iActiveScript      = NULL;
		m_pScriptDispatch    = NULL;
		return;
	}
	//设置实现对象
	hr = m_iActiveScript->SetScriptSite(&m_ScriptSite);
	if (HRVerify(hr, "Could not host scripting site") == FALSE) 
	{
		m_iActiveScript->Release();
		m_iActiveScriptParse->Release();
		m_iActiveScriptParse = NULL;
		m_iActiveScript      = NULL;
		m_pScriptDispatch    = NULL;
		return;
	}
	hr = m_iActiveScriptParse->InitNew();
	if (HRVerify(hr, "Could not initialize scripting parser") == FALSE) 
	{
		m_iActiveScript->Release();
		m_iActiveScriptParse->Release();
		m_iActiveScriptParse = NULL;
		m_iActiveScript      = NULL;
		m_pScriptDispatch    = NULL;
		return;
	}
	
	m_pScriptDispatch = NULL;
	//初始化暴露对象链表
	for (index = 0; index < m_ScriptSite.m_ExposedObjects.GetSize(); index ++) 
	{
		delete m_ScriptSite.m_ExposedObjects[index];
	}
	m_ScriptSite.m_ExposedObjects.RemoveAll();
	//设置程序主窗口为脚本的父窗口
	m_ScriptSite.m_hWnd = ::AfxGetMainWnd()->m_hWnd;
}

BOOL ScriptEngineFactory::RunScript(CString newScript)
{
	HRESULT		hr;
	EXCEPINFO	ei;
	BSTR		pParseText = newScript.AllocSysString();

	// Add script code to the engine
	hr = m_iActiveScriptParse->ParseScriptText(
		pParseText, NULL, NULL, NULL, 0, 0, 0L, NULL, &ei);
	if (HRVerify(hr, "Error parsing script text") == FALSE) {
		hr = m_iActiveScriptParse->Release();
		hr = m_iActiveScript->Release();

		m_iActiveScriptParse = NULL;
		m_iActiveScript      = NULL;
		m_pScriptDispatch    = NULL;

		return FALSE;
	}

	// This will actually run the script
	hr = m_iActiveScript->SetScriptState(SCRIPTSTATE_CONNECTED);
	if (HRVerify(hr, "Error running the script") == FALSE) {
		hr = m_iActiveScriptParse->Release();
		hr = m_iActiveScript->Release();

		m_iActiveScriptParse = NULL;
		m_iActiveScript      = NULL;
		m_pScriptDispatch    = NULL;

		return FALSE;
	}

	// This will disconnect the script
	hr = m_iActiveScriptParse->Release();
	hr = m_iActiveScript->Release();

	m_iActiveScriptParse = NULL;
	m_iActiveScript      = NULL;
	m_pScriptDispatch    = NULL;
	
	return TRUE;
}

CStringArray* ScriptEngineFactory::GetErrorMessages()
{
	return &m_ScriptSite.m_ErrorMessages;
}

BOOL ScriptEngineFactory::LoadScript(CString newScript)
{
	HRESULT		hr;
	EXCEPINFO	ei;
	BSTR		pParseText = newScript.AllocSysString();
	//解析脚本
	hr = m_iActiveScriptParse->ParseScriptText(
		pParseText, NULL, NULL, NULL, 0, 0, 0L, NULL, &ei);
	if (HRVerify(hr, "Error parsing script text") == FALSE) 
	{
		hr = m_iActiveScriptParse->Release();
		hr = m_iActiveScript->Release();
		m_iActiveScriptParse = NULL;
		m_iActiveScript      = NULL;
		m_pScriptDispatch    = NULL;
		return FALSE;
	}
	//运行脚本
	hr = m_iActiveScript->SetScriptState(SCRIPTSTATE_CONNECTED);
	if (HRVerify(hr, "Error running the script") == FALSE) 
	{
		hr = m_iActiveScriptParse->Release();
		hr = m_iActiveScript->Release();
		m_iActiveScriptParse = NULL;
		m_iActiveScript      = NULL;
		m_pScriptDispatch    = NULL;
		return FALSE;
	}
	
	hr = m_iActiveScript->GetScriptDispatch(0, &m_pScriptDispatch);
	if (HRVerify(hr, "Error getting script dispatch") == FALSE) 
	{
		m_pScriptDispatch = NULL;
		return FALSE;
	}
	AttachDispatch(m_pScriptDispatch);
	return TRUE;
}

BOOL ScriptEngineFactory::UnloadScript()
{
	// Release script dispatch pointer from this
	DetachDispatch();

	// Release all interfaces
	if (m_iActiveScriptParse) m_iActiveScriptParse->Release();
	if (m_iActiveScript) m_iActiveScript->Release();
	if (m_pScriptDispatch) m_pScriptDispatch->Release();

	m_iActiveScriptParse = NULL;
	m_iActiveScript      = NULL;
	m_pScriptDispatch    = NULL;

	return TRUE;
}

BOOL ScriptEngineFactory::GetIDOfFunction(CString strFunctionName, DISPID* pID)
{
	// This method retrieves the DISPID to use when
	// calling a method in the loaded script
	// One needs to know how many parameters are used and
	// if there is a return value
	// FALSE is returned when either there is no script loaded,
	// or the method is not there.
	if (m_pScriptDispatch == NULL) {
		return FALSE;
	}

	BSTR pFunctionName = strFunctionName.AllocSysString();
	BOOL bStatus = FALSE;

	bStatus = m_pScriptDispatch->GetIDsOfNames(
		IID_NULL, 
		&pFunctionName, 
		1, 
		LOCALE_SYSTEM_DEFAULT, 
		pID) == S_OK;

	return bStatus;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -