当先锋百科网

首页 1 2 3 4 5 6 7


Script.h

#pragma once
#include <xstring>
#include <list>

#import "msscript.ocx" no_namespace

#define LANGUAGE_DEFAULT	_T("JScript")
#define RT_SCRIPT			_T("SCRIPT")
#define LANGUAGE_NAME_LEN	40
#define ERROR_DESC_LEN		256

using namespace std;

#ifndef _UNICODE
typedef list<string> stl_string_list;
#else
typedef list<wstring> stl_string_list;
#endif

class CScript
{
public:
	CScript(void);
	~CScript(void);
public:
	bool LoadScript(__in LPCTSTR szFilename);   //通过路径加载脚本文件
	bool LoadScriptResource(__in LPCTSTR lpName, __in LPCTSTR lpType,__in HINSTANCE hInstance);  //通过资源加载脚本文件
	LPCTSTR GetLanguage();         //获取脚本语言
	void SetLanguage(__in LPCTSTR szLanguage); //设置脚本语言
	int  GetMethodsCount() const;   //获取函数个数
	LPCTSTR GetNameAt(__in int index);   //获取对应索引的函数名
	_variant_t ExecFunc(__in LPCTSTR lpfunc ,__in _variant_t varParam);//执行函数
	LPCTSTR ExecFunc(__in LPCTSTR lpfunc ,__in LPCTSTR lpParam);//执行函数

private:
	bool Create(VARTYPE  vt, UINT  cDims, UINT lBound, UINT cCount);
	bool Destroy();
	UINT GetDimension();
	bool Attach(LPSAFEARRAY psa);
	bool AttachFromVariant(VARIANT* pVariant);
	LPSAFEARRAY Detach();
	LPSAFEARRAY GetArray();
	bool AccessData(void FAR* FAR* pvData);
	bool UnaccessData();
	bool Lock();
	bool Unlock();
	bool PutElement(long lIndices, void FAR* vData);
	bool GetElement(long lIndices, void FAR* vData);
	VARIANT GetAsVariant();

public:	
	void Reset();	
	bool AddScript(LPCTSTR szCode);
	LPCTSTR GetErrorString();
	bool ExecuteStatement(LPCTSTR szStatement);
	bool RunProcedure(LPCTSTR szProcName, SAFEARRAY** saParameters, VARIANT* varRet);


private:
	void CommonConstruct();
	bool GetMethodsName();
	LPCTSTR GetScriptFunction(LPCTSTR name);

	LPSAFEARRAY	m_pSA;
	IScriptControlPtr m_pScript;				// The one and only script control
	stl_string_list m_FunctionList;				// Function list
	TCHAR	m_szLanguage[LANGUAGE_NAME_LEN+1];	// Current language
	TCHAR	m_szError[ERROR_DESC_LEN+1];		// Description error	
};


Script.cpp

#include "StdAfx.h"
#include "Script.h"
CScript::CScript(void)
{
	m_pSA = NULL;
	memset(m_szError,0,ERROR_DESC_LEN);
	memset(m_szLanguage,0,LANGUAGE_NAME_LEN);
	
	if (!AfxOleInit())
	{
		return;
	}
	CommonConstruct();
}

CScript::~CScript(void)
{
	m_pScript = NULL;
	Destroy();
}
void CScript::CommonConstruct()
{
	HRESULT hr = m_pScript.CreateInstance(__uuidof(ScriptControl));
	_com_util::CheckError( hr ); // will throw an exception if failed

	// will not come here if exception
	_tcscpy_s(m_szLanguage,LANGUAGE_NAME_LEN+1, LANGUAGE_DEFAULT);
	m_pScript->PutAllowUI( VARIANT_FALSE );
	m_pScript->PutLanguage( _bstr_t(m_szLanguage ));
}

LPCTSTR CScript::GetLanguage()
{
	return m_szLanguage;
}


void CScript::SetLanguage(LPCTSTR szLanguage)
{
	_tcscpy_s(m_szLanguage,LANGUAGE_NAME_LEN+1, szLanguage);

	if (m_pScript != NULL)
	{
		m_pScript->PutLanguage( _bstr_t( szLanguage ) );
		m_pScript->Reset();
		m_FunctionList.clear();
	}
}

bool CScript::Create(VARTYPE  vt, UINT  cDims, UINT lBound, UINT cCount)
{
	Destroy();

	if (cDims == 1)	// this is somewhat faster...
		m_pSA = SafeArrayCreateVector(vt, lBound, cCount);
	else
	{
		SAFEARRAYBOUND rgsabound[1] = { 0 };
		rgsabound[0].lLbound = lBound;
		rgsabound[0].cElements = cCount;
		m_pSA = SafeArrayCreate(vt, cDims, rgsabound);
	}
	return (m_pSA != NULL);
}

bool CScript::Destroy()
{
	if (NULL != m_pSA)
	{
		// Maybe the object is locked!
		if (SUCCEEDED(SafeArrayDestroy( m_pSA )))
			m_pSA = NULL;
	}
	return (m_pSA == NULL);
}

LPSAFEARRAY CScript::GetArray()
{
	return m_pSA;
}

UINT CScript::GetDimension()
{
	UINT uDim = 0;
	if (NULL != m_pSA)
		uDim = SafeArrayGetDim( m_pSA );
	return uDim;
}

bool CScript::Attach(LPSAFEARRAY psa)
{
	if (NULL != psa)	// prevent 'destroy' for null pointer
	{
		Destroy();
		m_pSA = psa;
		return true;
	}
	return false;
}

LPSAFEARRAY CScript::Detach()
{
	if (NULL == m_pSA)
		return NULL;

	LPSAFEARRAY psa = m_pSA;
	m_pSA = NULL;
	return psa;
}

bool CScript::AttachFromVariant(VARIANT* pVariant)
{
	if (NULL != pVariant)
	{
		if (pVariant->vt & VT_ARRAY)
		{
			LPSAFEARRAY psa = pVariant->parray;
			if (pVariant->vt & VT_BYREF)	// VB use this...
				psa = *pVariant->pparray;
			return Attach( psa );
		}
	}
	return false;
}

VARIANT CScript::GetAsVariant()
{
	VARIANT var;
	VariantClear(&var);
	if (NULL != m_pSA)
	{
		var.vt = VT_ARRAY|VT_BYREF;
		var.pparray = &m_pSA;
		USHORT fFeatures = m_pSA->fFeatures;
		LONG cbElements = m_pSA->cbElements;
		if (fFeatures & FADF_BSTR)
			var.vt |= VT_BSTR;
		else if (fFeatures & FADF_UNKNOWN)
			var.vt |= VT_UNKNOWN;
		else if (fFeatures & FADF_DISPATCH)
			var.vt |= VT_DISPATCH;
		else if (fFeatures & FADF_VARIANT)
			var.vt |= VT_VARIANT;
		else if (fFeatures & FADF_RECORD)
			var.vt |= VT_RECORD;
		else if (fFeatures & FADF_HAVEVARTYPE)
		{
			// these are just guess based on size of element, may not be accurated...
			if (sizeof(char) == cbElements) // 1 byte
				var.vt |= VT_UI1;
			else if (sizeof(short) == cbElements) // 2 bytes
				var.vt |= VT_UI2;
			else if (sizeof(long) == cbElements) // 4 bytes -- or float (VT_R4)
				var.vt |= VT_UI4;
			else if (sizeof(double) == cbElements) // 8 bytes -- or Currency (VT_CY)
				var.vt |= VT_R8;
		}
	}
	return var;
}

bool CScript::AccessData(void FAR* FAR* pvData)
{
	if (NULL != m_pSA && NULL != pvData)
	{
		return (SafeArrayAccessData(m_pSA, pvData) == S_OK);
	}
	return false;
}

bool CScript::UnaccessData()
{
	if (NULL != m_pSA)
	{
		return (SafeArrayUnaccessData(m_pSA) == S_OK);
	}
	return false;
}

bool CScript::Lock()
{
	if (NULL != m_pSA)
	{
		return (SafeArrayLock(m_pSA) == S_OK);
	}
	return false;
}

bool CScript::Unlock()
{
	if (NULL != m_pSA)
	{
		return (SafeArrayUnlock(m_pSA) == S_OK);
	}
	return false;
}

bool CScript::PutElement(long lIndices, void FAR* vData)
{
	if (NULL != m_pSA)
	{
		return (SafeArrayPutElement(m_pSA, &lIndices, vData) == S_OK);
	}
	return false;
}

bool CScript::GetElement(long lIndices, void FAR* vData)
{
	if (NULL != m_pSA)
	{
		return (SafeArrayGetElement(m_pSA, &lIndices, vData) == S_OK);
	}
	return false;
}

int  CScript::GetMethodsCount() const
{
	return m_FunctionList.size();
}

LPCTSTR CScript::GetNameAt(int index)
{
	if( index >= 0 && index < (int)m_FunctionList.size())
	{
		stl_string_list::iterator iter = m_FunctionList.begin();
		while( index > 0)
		{
			iter++;
			index--;
		}
		return (*iter).c_str();
	}
	return TEXT("");
}

void CScript::Reset()
{
	if (m_pScript != NULL)
	{
		m_pScript->Reset();

		// empty list...
		m_FunctionList.clear();
	}
}

LPCTSTR CScript::GetErrorString()
{
	m_szError[0] = 0;
	if (m_pScript != NULL)
	{
		try{
			IScriptErrorPtr pError = m_pScript->GetError();
			if (pError != NULL)
			{
				_bstr_t desc  = _bstr_t("Error: ") + pError->GetDescription() + _bstr_t(", ");
				desc += pError->GetText() + _bstr_t("; in line ");
				desc += _bstr_t(pError->GetLine());
				int count = __min(desc.length(), ERROR_DESC_LEN); // string may be truncated...
				_tcsncpy_s(m_szError, (LPCTSTR) desc, count);
				m_szError[count] = 0;
				pError->Clear();
			}
		}
		catch(_com_error& e)
		{
			TRACE( (LPSTR)e.Description() );
			TRACE( (LPSTR)"\n" );
		}
	}
	return m_szError;
}

bool CScript::GetMethodsName()
{
	bool bResult = false;
	if (m_pScript != NULL)
	{
		IScriptProcedureCollectionPtr pIProcedures = m_pScript->GetProcedures();

		// empty list...
		m_FunctionList.clear();

		try{
			long count = pIProcedures->GetCount();
			for(long index=1; index <= count; index++)
			{
				IScriptProcedurePtr pIProcPtr = pIProcedures->GetItem( _variant_t(index) );
				_bstr_t name = pIProcPtr->GetName();
				m_FunctionList.insert(m_FunctionList.end(), (LPCTSTR) name );
				pIProcPtr = NULL;
			}

			bResult = true;
		}
		catch(...)
		{
			// Just catch the exception, call GetErrorString()
			// to retreive last error
		}

		pIProcedures = NULL;
	}
	return bResult;
}

LPCTSTR CScript::GetScriptFunction(LPCTSTR szName)
{
	stl_string_list::iterator iter = m_FunctionList.begin();
	while( iter != m_FunctionList.end() )
	{
		if ((*iter).compare(szName) == 0)
			return (*iter).c_str();
		iter++;
	}
	return TEXT("");
}

bool CScript::LoadScriptResource(LPCTSTR lpName, LPCTSTR lpType, HINSTANCE hInstance )
{
	try{
		if (m_pScript)
		{
			HRSRC res = ::FindResource(hInstance, lpName, lpType);
			ASSERT( res != NULL);
			BYTE* pbytes = (BYTE*) LockResource(LoadResource(hInstance, res ));
			ASSERT( pbytes != NULL);
			_bstr_t strCode = (LPCSTR) (pbytes);
			m_pScript->AddCode( strCode );
			GetMethodsName();
			return true;
		}
	}
	catch(...)
	{
		// Just catch the exception, call GetErrorString()
		// to retreive last error
	}
	return false;
}

bool CScript::LoadScript(LPCTSTR szFilename)
{
	HANDLE hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile != INVALID_HANDLE_VALUE)
	{
		DWORD dwSize = GetFileSize(hFile, NULL);
		if (0xFFFFFFFF != dwSize)
		{
			BYTE* pbytes = (BYTE*) GlobalAlloc(GPTR, dwSize+1);
			if (pbytes != NULL)
			{
				DWORD dwRead = 0;
				bool bResult = false;
				if (ReadFile(hFile, pbytes, dwSize, &dwRead, NULL))
				{
					try{
						if (m_pScript)
						{
							_bstr_t strCode = (LPCSTR) (pbytes);
							m_pScript->AddCode( strCode );
							GetMethodsName();
							bResult = true;
						}
					}
					catch(...)
					{
						// Just catch the exception, call GetErrorString()
						// to retreive last error
					}

					GlobalFree( (HGLOBAL) pbytes);
					CloseHandle(hFile);
					return bResult;
				}

				GlobalFree( (HGLOBAL) pbytes);
			}
		}

		CloseHandle(hFile);
		return false;
	}

	return false;
}

bool CScript::AddScript(LPCTSTR szCode)
{
	try {
		if (m_pScript != NULL)
		{
			ULONG ref = m_pScript->AddRef();
			_bstr_t strCode = szCode;
			m_pScript->AddCode( strCode );
			GetMethodsName();
			ref = m_pScript->Release();
			return true;
		}
	}
	catch(...)
	{
		// Just catch the exception, call GetErrorString()
		// to retreive last error
		ULONG ref = m_pScript->Release();
	}
	return false;
}

bool CScript::ExecuteStatement(LPCTSTR szStatement)
{
	try {
		if (m_pScript != NULL)
		{
			ULONG ref = m_pScript->AddRef();
			m_pScript->ExecuteStatement( _bstr_t(szStatement) );
			ref = m_pScript->Release();
			return true;
		}
	}
	catch(...)
	{
		// Just catch the exception, call GetErrorString()
		// to retreive last error
		ULONG ref = m_pScript->Release();
	}

	return false;
}

bool CScript::RunProcedure(LPCTSTR szProcName, SAFEARRAY** saParameters, VARIANT* varRet)
{
	// required argument
	ASSERT( saParameters != NULL);
	ASSERT( varRet  != NULL);

	try {
		if (m_pScript != NULL)
		{
			ULONG ref = m_pScript->AddRef();
			bool  bResult = false;
			_bstr_t szFunc  = GetScriptFunction(szProcName);
			if (szFunc.length() > 0)
			{
				*varRet = m_pScript->Run(szFunc, saParameters);
				bResult = true;
			}
			ref = m_pScript->Release();
			return bResult;
		}
	}
	catch(...)
	{
		// Just catch the exception, call GetErrorString()
		// to retreive last error
		ULONG ref = m_pScript->Release();
	}
	return false;
}


_variant_t CScript::ExecFunc(LPCTSTR lpfunc ,_variant_t varParam)
{
	try{
		_variant_t var;
		if (_tcsclen(lpfunc) <= 0)
			this->Create(VT_VARIANT, 1, 0, 0);	
		else
		{
			this->Create(VT_VARIANT, 1, 0, 1);	
			var = varParam;
		}
		this->PutElement(0, (void*)&var);// parameter1 -> index 0
		LPSAFEARRAY sa =  this->GetArray();
		_variant_t varRet;
		if (RunProcedure(lpfunc, &sa, &varRet))
			return varRet;
		else
		{
			return _bstr_t(GetErrorString());
		}
	}
	catch(...)
	{
		return _bstr_t(GetErrorString());
	}
}

LPCTSTR CScript::ExecFunc(__in LPCTSTR lpfunc ,__in LPCTSTR lpParam)
{
	try{
		_variant_t var;
		if (_tcsclen(lpfunc) <= 0)
			this->Create(VT_VARIANT, 1, 0, 0);	
		else
		{
			this->Create(VT_VARIANT, 1, 0, 1);	
			var = _bstr_t(lpParam);
		}
		this->PutElement(0, (void*)&var);// parameter1 -> index 0
		LPSAFEARRAY sa =  this->GetArray();
		_variant_t varRet;
		if (RunProcedure(lpfunc, &sa, &varRet))
			return (LPCTSTR)_bstr_t(varRet);
		else
		{
			return GetErrorString();
		}
	}
	catch(...)
	{
		return GetErrorString();
	}
}

调用sample:

CScript script;
        CString strpath = _T("C:\\encoding.js");
        script.LoadScript(strpath);
        CString strRet = script.ExecFunc(_T("encoding"),_T("测试项目"));


JS代码:

function encoding(str)
{
return encodeURI(str);
}


运行结果如下:

strRet = "%E6%B5%8B%E8%AF%95%E9%A1%B9%E7%9B%AE";