windows-nt/Source/XPSP1/NT/multimedia/directx/dmusic/dmscript/activescript.h
2020-09-26 16:20:57 +08:00

146 lines
5.6 KiB
C++

// Copyright (c) 1999 Microsoft Corporation. All rights reserved.
//
// Declaration of CActiveScriptManager.
//
// CActiveScriptManager handles interfacing with VBScript or any activeX scripting
// language. It intializes an IActiveScript object, sends it code, and sets and gets
// the values of variables. Used by CDirectMusicScript.
#pragma once
#include "ole2.h"
#include "activscp.h"
#include "scriptthread.h"
#include "..\shared\dmusicp.h"
// forward declaration
class CDirectMusicScript;
// little helper class to cache routine and variable names for EnumItem
class ScriptNames
{
public:
ScriptNames() : m_prgbstr(NULL) {}
~ScriptNames() { Clear(); }
HRESULT Init(bool fUseOleAut, DWORD cNames);
operator bool() { return !!m_prgbstr; }
DWORD size() { return m_dwSize; }
void Clear();
BSTR &operator[](DWORD dwIndex) { assert(m_prgbstr && dwIndex < m_dwSize); return m_prgbstr[dwIndex]; }
private:
bool m_fUseOleAut;
DWORD m_dwSize;
BSTR *m_prgbstr;
};
class CActiveScriptManager
: public IActiveScriptSite,
public ScriptManager
{
public:
CActiveScriptManager(
bool fUseOleAut,
const WCHAR *pwszLanguage,
const WCHAR *pwszSource,
CDirectMusicScript *pParentScript,
HRESULT *phr,
DMUS_SCRIPT_ERRORINFO *pErrorInfo);
HRESULT Start(DMUS_SCRIPT_ERRORINFO *pErrorInfo);
HRESULT CallRoutine(const WCHAR *pwszRoutineName, DMUS_SCRIPT_ERRORINFO *pErrorInfo);
HRESULT ScriptTrackCallRoutine(
const WCHAR *pwszRoutineName,
IDirectMusicSegmentState *pSegSt,
DWORD dwVirtualTrackID,
bool fErrorPMsgsEnabled,
__int64 i64IntendedStartTime,
DWORD dwIntendedStartTimeFlags);
HRESULT SetVariable(const WCHAR *pwszVariableName, VARIANT varValue, bool fSetRef, DMUS_SCRIPT_ERRORINFO *pErrorInfo);
HRESULT GetVariable(const WCHAR *pwszVariableName, VARIANT *pvarValue, DMUS_SCRIPT_ERRORINFO *pErrorInfo);
HRESULT EnumItem(bool fRoutine, DWORD dwIndex, WCHAR *pwszName, int *pcItems);
HRESULT DispGetIDsOfNames(REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId);
HRESULT DispInvoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr);
void Close(); // Releases all references in preparation for shutdown
// IUnknown
STDMETHOD(QueryInterface)(const IID &iid, void **ppv);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
// IActiveScriptSite
STDMETHOD(GetLCID)(/* [out] */ LCID __RPC_FAR *plcid);
STDMETHOD(GetItemInfo)(
/* [in] */ LPCOLESTR pstrName,
/* [in] */ DWORD dwReturnMask,
/* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppiunkItem,
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppti);
STDMETHOD(GetDocVersionString)(/* [out] */ BSTR __RPC_FAR *pbstrVersion);
STDMETHOD(OnScriptTerminate)(
/* [in] */ const VARIANT __RPC_FAR *pvarResult,
/* [in] */ const EXCEPINFO __RPC_FAR *pexcepinfo);
STDMETHOD(OnStateChange)(/* [in] */ SCRIPTSTATE ssScriptState);
STDMETHOD(OnScriptError)(/* [in] */ IActiveScriptError __RPC_FAR *pscripterror);
STDMETHOD(OnEnterScript)();
STDMETHOD(OnLeaveScript)();
// Retrieve context for the currently running script.
// Some automation model functions need access to the context from which the
// currently running routine was called. For example, they may need to operate
// on the implied global performance.
// Be sure to addref the returned pointer if holding onto it.
static IDirectMusicPerformance8 *GetCurrentPerformanceNoAssertWEAK();
static IDirectMusicPerformance8 *GetCurrentPerformanceWEAK() { IDirectMusicPerformance8 *pPerf = CActiveScriptManager::GetCurrentPerformanceNoAssertWEAK(); if (!pPerf) {assert(false);} return pPerf; }
static IDirectMusicObject *GetCurrentScriptObjectWEAK();
static IDirectMusicComposer8 *GetComposerWEAK();
static void GetCurrentTimingContext(__int64 *pi64IntendedStartTime, DWORD *pdwIntendedStartTimeFlags);
private:
// Functions
HRESULT GetIDOfName(const WCHAR *pwszName, DISPID *pdispid); // returns S_FALSE for unknown name
void ClearErrorInfo();
void SetErrorInfo(ULONG ulLineNumber, LONG ichCharPosition, BSTR bstrSourceLine, const EXCEPINFO &excepinfo);
void ContributeErrorInfo(const WCHAR *pwszActivity, const WCHAR *pwszSubject, const EXCEPINFO &excepinfo);
HRESULT ReturnErrorInfo(HRESULT hr, DMUS_SCRIPT_ERRORINFO *pErrorInfo);
static CActiveScriptManager *GetCurrentContext();
static HRESULT SetCurrentContext(CActiveScriptManager *pActiveScriptManager, CActiveScriptManager **ppActiveScriptManagerPrevious); // remember to restore the previous pointer after the call
HRESULT EnsureEnumItemsCached(bool fRoutine);
// Data
long m_cRef;
// Pointer back to the containing script object
CDirectMusicScript *m_pParentScript;
// Active Scripting
bool m_fUseOleAut;
IActiveScript *m_pActiveScript;
IDispatch *m_pDispatchScript;
// Errors (managed via ClearErrorInfo, SetErrorInfo, and ContributeErrorInfo)
bool m_fError;
HRESULT m_hrError;
ULONG m_ulErrorLineNumber;
LONG m_ichErrorCharPosition;
BSTR m_bstrErrorSourceComponent;
BSTR m_bstrErrorDescription;
BSTR m_bstrErrorSourceLineText;
BSTR m_bstrHelpFile;
// Context
struct ThreadContextPair
{
DWORD dwThreadId;
CActiveScriptManager *pActiveScriptManager;
};
static SmartRef::Vector<ThreadContextPair> ms_svecContext;
// Timing context for a routine call from a script track. (Sets the play/stop time of segments, songs, and playingsegments
// to the time of the routine in the script track.)
__int64 m_i64IntendedStartTime;
DWORD m_dwIntendedStartTimeFlags;
// cached names from enum methods
ScriptNames m_snamesRoutines;
ScriptNames m_snamesVariables;
};