Click here to Skip to main content
16,012,468 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C++
#pragma once
#include <objbase.h>

//#define LOCALE_SCRIPT_DEFAULT	(MAKELCID(LANG_ENGLISH_NEUTRAL, SORT_DEFAULT))

class CScriptHost : public IActiveScriptSite,
	public IActiveScriptSiteWindow
{
public:
	CScriptHost(LPUNKNOWN lpUnkCtrl, LPCOLESTR pNamedItem, HWND hWnd);
	virtual ~CScriptHost();

	HRESULT CreateScriptEngine();
	HRESULT ParseFile(const char* pszFileName,LPCOLESTR pstrItemName);
public:
	//IUnknown members
	STDMETHOD(QueryInterface)(REFIID riid,void** ppvObj);
	STDMETHOD_(unsigned long,AddRef)(void);
	STDMETHOD_(unsigned long,Release)();

	//IActiveScriptSite members
	STDMETHOD(GetLCID)(LCID  *plcid) ;
	STDMETHOD(GetItemInfo)(LPCOLESTR pstrName,DWORD dwReturnMask,
		IUnknown  * *ppiunkItem,ITypeInfo  * *ppti) ;
	STDMETHOD(GetDocVersionString)(BSTR  *pbstrVersion) ;
	STDMETHOD(OnScriptTerminate)(const VARIANT  *pvarResult,const EXCEPINFO  *pexcepinfo) ;
	STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState) ;
	STDMETHOD(OnScriptError)(IActiveScriptError  *pscripterror) ;
	STDMETHOD(OnEnterScript)(void) ;
	STDMETHOD(OnLeaveScript)(void) ;
	//IActiveScriptSiteWindow members
	STDMETHOD(GetWindow)(HWND  *phwnd) ;
	STDMETHOD(EnableModeless)(BOOL fEnable);
public:
	IActiveScript* m_ps;
	IActiveScriptParse* m_psp;
private:
	LONG m_cRef;
	CLSID m_clsidEngine;
	LPUNKNOWN m_lpUnkCtrl;
	LPOLESTR m_pNamedItem;
	HWND m_Wnd;
};


#include "StdAfx.h"
#include "ScriptHost.h"

#include <sys/stat.h>

//类CScriptHost通过多继承的方法实现了两个接口,并负责脚本引擎的创建和维护工作。其数据成员m_ps和m_psp用于保存引擎的IActiveScript和IActiveScriptParse接口指针;数据成员m_clsidEngine记录了引擎的类ID;m_Wnd记录了应用系统提供给引擎的主窗口;m_lpUnkCtrl记录了应用系统的唯一的一个受控对象,m_pNamedItem记录了受控对象的名字。在CScriptHost类的构造函数中初始设置m_lpUnkCtrl、m_pNamedItem和m_Wnd成员变量。构造函数和析构函数代码如下:
CScriptHost::CScriptHost(LPUNKNOWN lpUnkCtrl, LPCOLESTR pNamedItem , HWND hWnd) 
: m_ps(NULL),m_psp(NULL),m_cRef(0)
{
	m_lpUnkCtrl = lpUnkCtrl;
	m_pNamedItem = const_cast<LPOLESTR>(pNamedItem);
	m_Wnd = hWnd;
	// the clsid of VBScript Engine
	static CLSID const clsid = 
	{0xb54f3741, 0x5b07, 0x11cf, {0xa4, 0xb0, 0x0, 0xaa, 0x0, 0x4a, 0x55, 0xe8}};

	// Default to VBScript
	m_clsidEngine = clsid;
}

CScriptHost::~CScriptHost()
{
	if(m_psp)
		m_psp->Release();
	// we must first close the script engine
	if(m_ps)
	{
		m_ps->Close();
		m_ps->Release();
	}
}

HRESULT CScriptHost::CreateScriptEngine()
{
	HRESULT hr = S_OK;

	hr = ::CoCreateInstance(m_clsidEngine, NULL, CLSCTX_INPROC_SERVER, 
		IID_IActiveScript,(void**)&m_ps);
	if ( SUCCEEDED( hr ) )
	{
		// QI the IActiveScriptParse pointer
		hr = m_ps->QueryInterface(IID_IActiveScriptParse, (void**)&m_psp);
		if (FAILED(hr) )
		{
			m_ps->Release();
			return hr;
		}
		// set the script site
		IActiveScriptSite* Iass = static_cast<IActiveScriptSite*>(this);

		hr = m_ps->SetScriptSite(Iass);
		if ( FAILED( hr ) )
			return hr;
		m_ps->SetScriptState(SCRIPTSTATE_INITIALIZED);
		// initiate the script engine
		hr = m_psp->InitNew();
		if ( FAILED( hr ) )
			return hr;
		hr = m_ps->AddNamedItem(m_pNamedItem,
			SCRIPTITEM_ISVISIBLE  |  SCRIPTITEM_ISSOURCE);

	}

	return hr;
}

HRESULT CScriptHost::ParseFile(const char * pszFileName, LPCOLESTR pstrItemName)
{
	HRESULT hr = S_OK;

	struct _stat stat;
	size_t cch;
	EXCEPINFO ei;
	FILE *pfile; 
	if(::_stat(pszFileName,&stat))
		return E_FAIL;
	cch = stat.st_size;
	char* pszAlloc = new char[cch + 1];
	pszAlloc[cch] = '\0';// this is vitally important
	if(pszAlloc == NULL)
		return E_OUTOFMEMORY;
	memset(pszAlloc,0,cch);
	// get the script text into a memory block
	pfile = fopen(pszFileName,"rb");
	if ( !pfile ) 
	{
		hr = E_FAIL;
		return hr;
	}
	fread(pszAlloc,cch,1,pfile);
	fclose(pfile);
	LPOLESTR pwszCode;

	int CharCount = MultiByteToWideChar(CP_ACP,0,pszAlloc,-1,NULL,0);
	pwszCode = new WCHAR[CharCount];
	MultiByteToWideChar(CP_ACP,0,pszAlloc,-1,pwszCode,CharCount);
	size_t t = wcslen(pwszCode);
	hr = m_psp->ParseScriptText(pwszCode, pstrItemName,NULL, NULL, 0,0,0L,NULL,&ei);
	delete []pwszCode;
	delete []pszAlloc;
	return hr;
}

STDMETHODIMP CScriptHost::GetItemInfo(LPCOLESTR pstrName,DWORD dwReturnMask,
									  IUnknown  **ppiunkItem, ITypeInfo  **ppti) 
{
	HRESULT hr = S_OK;
	// initialize the sent-in pointers
	if(dwReturnMask & SCRIPTINFO_ITYPEINFO)
	{
		if(ppti == NULL)
			return E_INVALIDARG;
		*ppti = NULL;
	}
	if(dwReturnMask & SCRIPTINFO_IUNKNOWN)
	{  
		if(ppiunkItem == NULL)
			return E_INVALIDARG;
		*ppiunkItem = NULL;
	}
	if(!_wcsicmp(m_pNamedItem, pstrName))
	{
		if(dwReturnMask & SCRIPTINFO_IUNKNOWN)
		{
			// give out the object's IUnknown pointer
			*ppiunkItem = m_lpUnkCtrl;
			static_cast<IUnknown*>(*ppiunkItem)->AddRef();
		}

		if(dwReturnMask & SCRIPTINFO_ITYPEINFO)
		{
			IProvideClassInfo* pClsInfo = NULL;
			hr = m_lpUnkCtrl->QueryInterface(IID_IProvideClassInfo, (void**)&pClsInfo);

			if(pClsInfo != NULL)
			{
				hr = pClsInfo->GetClassInfo(ppti);
				pClsInfo->Release();
			}
		}
	}
	return hr;
}


HRESULT CScriptHost::GetWindow(HWND  *phwnd)
{
	if (m_Wnd != NULL)
	{
		*phwnd = m_Wnd;
		return S_OK;
	} 
	else
	{
		return E_FAIL;
	}
}

STDMETHODIMP CScriptHost::GetLCID(LCID  *plcid) 
{
	//*plcid = LOCALE_SCRIPT_DEFAULT;	// Default LCID: english-neutral
	return E_NOTIMPL;
}

STDMETHODIMP CScriptHost::GetDocVersionString(BSTR  *pbstrVersion)
{
	return E_NOTIMPL;
}

STDMETHODIMP CScriptHost::OnScriptTerminate(const VARIANT  *pvarResult,const EXCEPINFO  *pexcepinfo)
{
	return S_OK;
}

STDMETHODIMP CScriptHost::OnStateChange(SCRIPTSTATE ssScriptState)
{
	return S_OK;
}

STDMETHODIMP CScriptHost::OnScriptError(IActiveScriptError  *pscripterror)
{
	return S_OK;
}

STDMETHODIMP CScriptHost::OnEnterScript(void)
{
	return S_OK;

}
	
STDMETHODIMP CScriptHost::OnLeaveScript(void)
{
	return S_OK;

}


STDMETHODIMP CScriptHost::EnableModeless(BOOL fEnable)
{
	return S_OK;
}

ULONG CScriptHost::AddRef()
{
	::InterlockedIncrement(&m_cRef);
	return m_cRef;
}


ULONG CScriptHost::Release()
{
	::InterlockedDecrement(&m_cRef);
	return m_cRef;
}

STDMETHODIMP CScriptHost::QueryInterface(REFIID riid,void** ppvObj)
{

	return S_OK;
}



When function "SetScriptSite" is called in function "CreateScriptEngine", error occurs:
Unhandled exception at 0x7327c96b in CScriptTest.exe: 0xC0000005: Access violation reading location 0x00000000.

I have just got to ActiveX Scripting, i have googled a lot, still i can't solve the problem.

Who can tell me where it is wrong?
Posted

1 solution

It was embarrassing.
I have solved the prolem by changing the return value in QueryInterface from S_OK to E_NOTIMPL;

So it appears well now.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900