/** * @file XTPActiveScriptEngine.h * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ /** @cond */ #if !defined(__XTPACTIVESCRIPTENGINE_H__) # define __XTPACTIVESCRIPTENGINE_H__ /** @endcond */ # if _MSC_VER > 1000 # pragma once # endif // _MSC_VER > 1000 # include "Common/Base/Diagnostic/XTPDisableAdvancedWarnings.h" # include # include "Common/Base/Diagnostic/XTPEnableAdvancedWarnings.h" # include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" class CXTPActiveScriptEngine; /** * @brief * Wrapper around scriptable object. */ class _XTP_EXT_CLASS CXTPActiveScriptObjectContext { friend class CXTPActiveScriptEngine; private: /** * @brief * Constructs scriptable object context. * @param pEngine Scripting engine to which an object belongs. * @param pObject Object's IDispatch pointer. */ CXTPActiveScriptObjectContext(CXTPActiveScriptEngine* pEngine, IDispatch* pObject); /** * @brief * Handles scriptable object context deallocation. */ ~CXTPActiveScriptObjectContext(); public: /** * @brief * Increments context reference count. * @return * Current number of references. */ ULONG AddRef(); /** * @brief * Decrements context reference count. * @return * Current number of references. */ ULONG Release(); /** * @brief * Obtains parent scripting engine instance pointer. * @return * A pointer to a CXTPActiveScriptEngine object. */ CXTPActiveScriptEngine* GetEngine(); /** * @brief * Obtains parent scripting engine instance pointer. * @return * A pointer to a CXTPActiveScriptEngine object. */ const CXTPActiveScriptEngine* GetEngine() const; /** * @brief * Obtains named property value. * @param lpszName Object's property name. * @param pvtResult A pointer to a value that receives property value. * @return * S_OK if successful or standard COM error code. */ HRESULT GetValue(LPCWSTR lpszName, CComVariant* pvtResult); /** * @brief * Sets named property value. * @param lpszName Object's property name. * @param vtValue New property value. * @return * S_OK if successful or standard COM error code. */ HRESULT SetValue(LPCWSTR lpszName, VARIANT vtValue); /** * @brief * Invokes a function object. * @param lpArguments Pointer to an array of function arguments. * @param nCount Number of arguments pointed by lpArguments. * @param pvtResult Optional pointer to value that revceives a value returned * from function. * @return * S_OK if successful or standard COM error code. */ HRESULT InvokeWithArgs(VARIANT* lpArguments, UINT nCount, VARIANT* pvtResult = NULL); /** * @brief * Invokes a function object with no arguments. * @param pvtResult Optional pointer to value that revceives a value returned * from function. * @return * S_OK if successful or standard COM error code. */ HRESULT Invoke(VARIANT* pvtResult = NULL); /** * @brief * Invokes a function object with 1 argument. * @param arg1 The only function argument. * @param pvtResult Optional pointer to value that revceives a value returned * from function. * @return * S_OK if successful or standard COM error code. */ template HRESULT Invoke(A1 arg1, VARIANT* pvtResult = NULL); /** * @brief * Invokes a function object with 1 argument. * @param arg1 1st function argument. * @param arg2 2nd function argument. * @param pvtResult Optional pointer to value that revceives a value returned * from function. * @return * S_OK if successful or standard COM error code. */ template HRESULT Invoke(A1 arg1, A2 arg2, VARIANT* pvtResult = NULL); /** * @brief * Invokes a function object with 1 argument. * @param arg1 1st function argument. * @param arg2 2nd function argument. * @param arg3 3rd function argument. * @param pvtResult Optional pointer to value that revceives a value returned * from function. * @return * S_OK if successful or standard COM error code. */ template HRESULT Invoke(A1 arg1, A2 arg2, A3 arg3, VARIANT* pvtResult = NULL); /** * @brief * Invokes a function object with 1 argument. * @param arg1 1st function argument. * @param arg2 2nd function argument. * @param arg3 3rd function argument. * @param arg4 4th function argument. * @param pvtResult Optional pointer to value that revceives a value returned * from function. * @return * S_OK if successful or standard COM error code. */ template HRESULT Invoke(A1 arg1, A2 arg2, A3 arg3, A4 arg4, VARIANT* pvtResult = NULL); /** * @brief * Invokes a function object with 1 argument. * @param arg1 1st function argument. * @param arg2 2nd function argument. * @param arg3 3rd function argument. * @param arg4 4th function argument. * @param arg5 5th function argument. * @param pvtResult Optional pointer to value that revceives a value returned * from function. * @return * S_OK if successful or standard COM error code. */ template HRESULT Invoke(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, VARIANT* pvtResult = NULL); /** * @brief * Obtains context object's property or function. * @param lpszName Name of object's property or function. * @return * A pointer to new context object or NULL if failed. */ CXTPActiveScriptObjectContext* GetContext(LPCWSTR lpszName); private: HRESULT ProcessNamedItem(LPCWSTR lpszName, WORD wFlags, VARIANT* lpArguments, UINT nCount, VARIANT* pvtResult = NULL); private: ULONG m_nRefs; CXTPActiveScriptEngine* m_pEngine; IDispatch* m_pObject; }; /** @cond */ AFX_INLINE CXTPActiveScriptEngine* CXTPActiveScriptObjectContext::GetEngine() { return m_pEngine; } AFX_INLINE const CXTPActiveScriptEngine* CXTPActiveScriptObjectContext::GetEngine() const { return m_pEngine; } AFX_INLINE HRESULT CXTPActiveScriptObjectContext::Invoke(VARIANT* pvtResult /*= NULL*/) { return InvokeWithArgs(NULL, 0, pvtResult); } template AFX_INLINE HRESULT CXTPActiveScriptObjectContext::Invoke(A1 arg1, VARIANT* pvtResult /*= NULL*/) { CComVariant va(arg1); return InvokeWithArgs(&va, 1, pvtResult); } template AFX_INLINE HRESULT CXTPActiveScriptObjectContext::Invoke(A1 arg1, A2 arg2, VARIANT* pvtResult /*= NULL*/) { CComVariant va[] = { CComVariant(arg1), CComVariant(arg2) }; return InvokeWithArgs(va, _countof(va), pvtResult); } template AFX_INLINE HRESULT CXTPActiveScriptObjectContext::Invoke(A1 arg1, A2 arg2, A3 arg3, VARIANT* pvtResult /*= NULL*/) { CComVariant va[] = { CComVariant(arg1), CComVariant(arg2), CComVariant(arg3) }; return InvokeWithArgs(va, _countof(va), pvtResult); } template AFX_INLINE HRESULT CXTPActiveScriptObjectContext::Invoke(A1 arg1, A2 arg2, A3 arg3, A4 arg4, VARIANT* pvtResult /*= NULL*/) { CComVariant va[] = { CComVariant(arg1), CComVariant(arg2), CComVariant(arg3), CComVariant(arg4) }; return InvokeWithArgs(va, _countof(va), pvtResult); } template AFX_INLINE HRESULT CXTPActiveScriptObjectContext::Invoke(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, VARIANT* pvtResult /*= NULL*/) { CComVariant va[] = { CComVariant(arg1), CComVariant(arg2), CComVariant(arg3), CComVariant(arg4), CComVariant(arg5) }; return InvokeWithArgs(va, _countof(va), pvtResult); } /** @endcond */ /** * @brief * Implements ActiveScript engine component. */ class _XTP_EXT_CLASS CXTPActiveScriptEngine : public CXTPCmdTarget { DECLARE_DYNAMIC(CXTPActiveScriptEngine); friend class CXTPActiveScriptObjectContext; public: /** * @brief * Constructs scripting engine object. */ CXTPActiveScriptEngine(); /** * @brief * Handles scripting engine deallocation. */ virtual ~CXTPActiveScriptEngine(); public: struct ExceptionData { EXCEPINFO info; BSTR strCodeLine; ULONG nLine; LONG nCharPos; DWORD dwErrCtx; }; /** * @brief * Initializes scripting engine. * @param lpszEngineProgId ProgID of scripting language to initialize scripting * engine for. Standard ProgIDs are JScript and VBScript. * More language providers can be installed if necessary. * @param pSite An optional pointer to an engine site interface that receives * notifications and requests from the scripting engine. * @return * S_OK if successful. */ HRESULT Initialize(LPCWSTR lpszEngineProgId, IActiveScriptSite* pSite = NULL); /** * @brief * Uninitializes scripting engine. */ void Uninitialize(); /** * @brief * Loads a chunk of code into execution context. Number of * chunks of code in one execution context is unlimited. * @param lpszCode Chunk code. * @return * S_OK if successful. */ HRESULT LoadCode(LPCWSTR lpszCode); /** * @brief * Runs execution context. * @return * S_OK if successful. */ HRESULT Run(); /** * @brief * Obtains global object's context instance. * @return * Global object's context instance pointer or NULL if failed. */ CXTPActiveScriptObjectContext* GetGlobalContext() const; /** * @brief * This member is called to create a context instance pointer. * @param pDispObject Points to a DISPATCH object. * @return * A pointer to a CXTPActiveScriptObjectContext object. */ CXTPActiveScriptObjectContext* CreateContext(LPDISPATCH pDispObject) const; /** * @brief * Information about the last unhandled exception. * @return * The last unhandled exception data pointer or NULL. */ const ExceptionData* GetExceptionData() const; /** * @brief * Information about the last unhandled exception. * @return * The last unhandled exception data pointer or NULL. */ const EXCEPINFO* GetExceptionInfo() const; /** * @brief * Adds named item name and data into execution context. * @param lpszName Item name pointer. * @param lpItemData Opional item data pointer. * @param dwFlags Item flags. For all available values refer to * IActiveScript::AddNamedItem Win32 SDK documentation. * @return * S_OK if successful. */ HRESULT AddNamedItem(LPCWSTR lpszName, LPVOID lpItemData = NULL, DWORD dwFlags = SCRIPTITEM_ISVISIBLE); /** * @brief * Obtains data pointer associated with named item. * @param lpszName Item name pointer. * @return * Item data pointer value or NULL if not specified. */ LPVOID GetNamedItemData(LPCWSTR lpszName) const; private: void SetExceptionInfo(const EXCEPINFO* pExcepInfo = NULL, BSTR strCodeLine = NULL, ULONG nLine = 0, LONG nCharPos = 0, DWORD dwErrCtx = 0); # ifdef _DEBUG void DumpCode(ULONG nLine) const; # endif DECLARE_INTERFACE_MAP(); # pragma warning(push) // C4616: #pragma warning : warning number '...' out of range, must be between '4001' and '4999' // C4619: #pragma warning : there is no warning number 'number' // C5204: '...': class has virtual functions, but its trivial destructor is not virtual; instances // of objects derived from this class may not be destructed correctly # pragma warning(disable : 4616 4619 5204) BEGIN_INTERFACE_PART(ActiveScriptSite, IActiveScriptSite) 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)(); STDMETHOD(OnLeaveScript)(); END_INTERFACE_PART(ActiveScriptSite); # pragma warning(pop) private: IActiveScriptSite* m_pSite; IActiveScript* m_pEngine; IActiveScriptParse* m_pParser; ExceptionData* m_pExceptionData; CMap m_NamedItemDataMap; # ifdef _DEBUG CComBSTR m_strLoadedCode; # endif }; /** @cond */ AFX_INLINE const CXTPActiveScriptEngine::ExceptionData* CXTPActiveScriptEngine::GetExceptionData() const { return m_pExceptionData; } AFX_INLINE const EXCEPINFO* CXTPActiveScriptEngine::GetExceptionInfo() const { return (NULL != m_pExceptionData ? &m_pExceptionData->info : NULL); } /** @endcond */ /** * @brief * Implements standard scripting runtime library. */ class _XTP_EXT_CLASS CXTPActiveScriptStdRuntime : public CXTPCmdTarget { DECLARE_DYNAMIC(CXTPActiveScriptStdRuntime); class TimeoutTask; class TimeoutTaskRegistry; public: /** * @brief * Constructs scripting runtime library. */ CXTPActiveScriptStdRuntime(); /** * @brief * Constructs scripting runtime library. * @param pSite Active script site pointer that is needed for named items access requested by * 'getObject' handler. * @param bAddSiteRef If TRUE then pSite reference counter will be incremented. */ CXTPActiveScriptStdRuntime(IActiveScriptSite* pSite, BOOL bAddSiteRef = TRUE); /** * @brief * Handles standard scripting runtime library deallocation. */ ~CXTPActiveScriptStdRuntime(); /** * @brief * Releases all used resources. */ void Shutdown(); private: DECLARE_DISPATCH_MAP(); afx_msg UINT OleSetTimeout(LPDISPATCH lpDispCallback, UINT nTimeout); afx_msg void OleClearTimeout(UINT nTimeoutId); afx_msg void OleDebugLog(const VARIANT& message); afx_msg LPDISPATCH OleGetObject(LPCTSTR lpszName); static void CALLBACK TimeoutProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); private: CMap m_TimeoutTaskMap; IActiveScriptSite* m_pSite; BOOL m_bAddSiteRef; }; # include "Common/Base/Diagnostic/XTPEnableNoisyWarnings.h" /** @cond */ #endif // !defined(__XTPACTIVESCRIPTENGINE_H__) /** @endcond */