?? activescripthost.cpp
字號:
///////////////////////////////////////////////////////////////////////////////
// File: ActiveScriptHost.cpp
// Version: 1.1
//
// Author: Ernest Laurentin
// E-mail: elaurentin@sympatico.ca
//
// This class implements an Active Script Hosting
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// An email letting me know how you are using it would be nice as well.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this c++ class may cause.
//
// Version history
// v1.01 : Bug fix with accessing object info (ITypeInfo)
// v1.1 : Add 'InvokeFuncHelper' allows to call script function directly from c++
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <afxconv.h> // or <atlconv.h>
#include "ActiveScriptHost.h"
#pragma warning(disable: 4290) // C++ Exception Specification ignored
struct HRESULT_EXCEPTION
{
HRESULT_EXCEPTION(HRESULT hr)
{ if (FAILED(hr)) throw hr; }
HRESULT operator = (HRESULT hr)
{ if (FAILED(hr)) throw hr; return hr; }
static inline void CheckError(HRESULT hr) throw(HRESULT)
{
if (FAILED(hr))
throw hr;
}
};
HRESULT LoadTypeInfoFromModule(REFIID riid, ITypeInfo **ppti);
//BEGIN_DISPATCH_MAP(CActiveScriptHost, CCmdTarget)
//END_DISPATCH_MAP()
BEGIN_INTERFACE_MAP(CActiveScriptHost, CCmdTarget)
INTERFACE_PART(CActiveScriptHost, IID_IActiveScriptSite, ActiveScriptSite)
INTERFACE_PART(CActiveScriptHost, IID_IActiveScriptSiteWindow, ActiveScriptSiteWindow)
END_INTERFACE_MAP()
IMPLEMENT_DYNAMIC(CActiveScriptHost, CCmdTarget)
///////////////////////////////////////////////////////////////////////////////
// Construction
CActiveScriptHost::CActiveScriptHost()
: m_pAxsParse(NULL), m_pAxsScript(NULL),
m_hHostWnd(NULL)
{
m_xActiveScriptSite.m_running = FALSE;
}
CActiveScriptHost::~CActiveScriptHost()
{
ReleaseObjects();
}
///////////////////////////////////////////////////////////////////////////////
// CommonConstruct
void CActiveScriptHost::CommonConstruct()
{
m_hHostWnd = ::GetDesktopWindow();
}
///////////////////////////////////////////////////////////////////////////////
// ReleaseObjects
void CActiveScriptHost::ReleaseObjects()
{
if (m_pAxsParse)
{
m_pAxsParse->Release();
m_pAxsParse = NULL;
}
if (m_pAxsScript)
{
m_pAxsScript->Close();
m_pAxsScript->Release();
m_pAxsScript = NULL;
}
}
///////////////////////////////////////////////////////////////////////////////
// Members
///////////////////////////////////////////////////////////////////////////////
// SetHostWindow
BOOL CActiveScriptHost::SetHostWindow(HWND hWnd)
{
m_hHostWnd = hWnd;
if (!::IsWindow(hWnd))
m_hHostWnd = GetDesktopWindow();
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// CreateEngine
BOOL CActiveScriptHost::CreateEngine(LPCOLESTR pstrProgID)
{
CLSID clsid;
HRESULT hr;
try {
// Auto deletion of script engine
ReleaseObjects();
// Search for LanguageID and create instance of script engine
if (SUCCEEDED(CLSIDFromProgID(pstrProgID, &clsid)))
{
// If this happens, the scripting engine is probably not properly registered
hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IActiveScript, (void **)&m_pAxsScript);
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
// Script Engine must support IActiveScriptParse for us to use it
hr = m_pAxsScript->QueryInterface(IID_IActiveScriptParse, (void **)&m_pAxsParse);
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
hr = m_pAxsScript->SetScriptSite(&m_xActiveScriptSite); // Our MFC-OLE interface implementation
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
// InitNew the object:
hr = m_pAxsParse->InitNew();
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
USES_CONVERSION;
LPCTSTR activsHost = OLE2CT(ACTIVS_HOST);
mapNamedItems[activsHost] = GetIDispatch(FALSE);
// Add Top-level Global Named Item
hr = m_pAxsScript->AddNamedItem(ACTIVS_HOST, SCRIPTITEM_NAMEDITEM);
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
hr = m_pAxsScript->SetScriptState(SCRIPTSTATE_STARTED);
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
return TRUE;
}
}
catch(HRESULT hr){
TRACE("### Script Error: %x ###", hr);
ReleaseObjects();
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// AddScriptItem
BOOL CActiveScriptHost::AddScriptItem(LPCOLESTR pstrNamedItem, LPUNKNOWN lpUnknown,
DWORD dwFlags /* = SCRIPTITEM_NAMEDITEM*/)
{
try {
// Add Top-level Global Named Item
if (m_pAxsScript != NULL && lpUnknown != NULL)
{
HRESULT hr;
USES_CONVERSION;
LPCTSTR szNamedItem = OLE2CT(pstrNamedItem);
mapNamedItems[szNamedItem] = lpUnknown;
hr = m_pAxsScript->AddNamedItem(pstrNamedItem, dwFlags);
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
// Connected to object sink-interface
hr = m_pAxsScript->SetScriptState(SCRIPTSTATE_CONNECTED);
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
return TRUE;
}
}
catch(HRESULT hr){
TRACE("### Script Error: %x ###", hr);
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// AddScriptCode
BOOL CActiveScriptHost::AddScriptCode(LPCOLESTR pstrScriptCode)
{
m_xActiveScriptSite.m_running = TRUE; //script will run
try {
if (m_pAxsParse != NULL)
{
HRESULT hr;
EXCEPINFO ei = { 0 };
hr = m_pAxsParse->ParseScriptText(pstrScriptCode, 0, 0, 0, 0, 0,
SCRIPTTEXT_ISPERSISTENT|SCRIPTTEXT_ISVISIBLE,
0, &ei);
HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
// Force script to Connected
//hr = m_pAxsScript->SetScriptState(SCRIPTSTATE_CONNECTED);
//HRESULT_EXCEPTION::CheckError( hr ); // will throw an exception if failed
return TRUE;
}
}
catch(HRESULT hr){
m_xActiveScriptSite.m_running = FALSE; //script will not be running
TRACE("### Script Error: %x ###", hr);
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// AddScriptlet
BOOL CActiveScriptHost::AddScriptlet(LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode,
LPCOLESTR pstrItemName, LPCOLESTR pstrEventName)
{
try {
// Add Top-level Global Named Item
if (m_pAxsParse != NULL)
{
HRESULT hr;
EXCEPINFO ei = { 0 };
BSTR bstrName = NULL;
hr = m_pAxsParse->AddScriptlet(pstrDefaultName,
pstrCode,
pstrItemName, // name object
pstrItemName, // no subobject - same as object
pstrEventName, // event name - attach to 'pstrItemName'
L"",
0,
0,
0,
&bstrName,
&ei);
SysFreeString(bstrName);
}
}
catch(HRESULT hr){
TRACE("### Script Error: %x ###", hr);
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// Helper functions
///////////////////////////////////////////////////////////////////////////////
// CreateObjectHelper
LPDISPATCH CActiveScriptHost::CreateObjectHelper(LPCOLESTR bstrProgID)
{
USES_CONVERSION;
HRESULT hr = S_OK;
LPDISPATCH lpObject = NULL;
TRACE( "Calling CreateObjectHelper()\n" );
CLSID clsidObject;
hr = CLSIDFromProgID(bstrProgID, &clsidObject );
if( SUCCEEDED( hr ) )
{
// Only Local-Server is safe (run as separated process)
hr = CoCreateInstance(clsidObject, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&lpObject );
if (FAILED(hr))
{
CString strProgID;
strProgID = bstrProgID;
TRACE("Failed to create object '%s'.\nReturn = 0x%x\n", strProgID, hr);
}
}
else
{
CString strProgID;
strProgID = bstrProgID;
TRACE("Invalid ProgID '%s'\n",strProgID);
}
return lpObject;
}
///////////////////////////////////////////////////////////////////////////////
// ReadTextFileHelper
WCHAR* CActiveScriptHost::ReadTextFileHelper(LPCOLESTR strFileName)
{
WCHAR *pwszResult = NULL;
char szFileNameA[MAX_PATH];
if (wcstombs(szFileNameA, strFileName, MAX_PATH) == -1)
return pwszResult;
HANDLE hfile = CreateFileA(szFileNameA, GENERIC_READ,
FILE_SHARE_READ, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (hfile != INVALID_HANDLE_VALUE)
{
DWORD cch = GetFileSize(hfile, 0);
char *psz = (char*)CoTaskMemAlloc(cch + 1);
if (psz)
{
DWORD cb;
ReadFile(hfile, psz, cch, &cb, 0);
pwszResult = (WCHAR*)CoTaskMemAlloc((cch + 1)*sizeof(WCHAR));
if (pwszResult)
mbstowcs(pwszResult, psz, cch + 1);
pwszResult[cch] = 0;
CoTaskMemFree(psz);
}
CloseHandle(hfile);
}
return pwszResult;
}
///////////////////////////////////////////////////////////////////////////////
// DestroyDataHelper
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -