/////////////////////////////////////////////////////////////////////////////// /* File: oadisp.cpp Description: Provides reusable implementation of IDispatch. Revision History: Date Description Programmer -------- --------------------------------------------------- ---------- 05/22/97 Initial creation. BrianAu */ /////////////////////////////////////////////////////////////////////////////// #include "pch.h" #pragma hdrstop #include "oadisp.h" OleAutoDispatch::OleAutoDispatch( VOID ) : m_pObject(NULL), m_pTypeInfo(NULL) { } OleAutoDispatch::OleAutoDispatch( IDispatch *pObject, REFIID riidTypeLib, REFIID riidDispInterface, LPCTSTR pszTypeLib ) : m_pObject(NULL), m_pTypeInfo(NULL), m_strTypeLib(pszTypeLib) { Initialize(pObject, riidTypeLib, riidDispInterface, pszTypeLib); } OleAutoDispatch::~OleAutoDispatch( VOID ) { if (NULL != m_pTypeInfo) { m_pTypeInfo->Release(); } } HRESULT OleAutoDispatch::Initialize( IDispatch *pObject, REFIID riidTypeLib, REFIID riidDispInterface, LPCTSTR pszTypeLib ) { HRESULT hr = S_FALSE; // Assume already initialized. if (NULL == m_pObject) { // // Note that we DO NOT AddRef the object pointer. // We assume that the object will outlive the OleAutoDispatch. // If you do, you can get into a circular reference problem where // the object pointed to by pObject is the container for *this. // m_pObject = pObject; m_idTypeLib = riidTypeLib; m_idDispInterface = riidDispInterface; m_strTypeLib = pszTypeLib; hr = S_OK; } return hr; } HRESULT OleAutoDispatch::GetIDsOfNames( REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId ) { HRESULT hr; ITypeInfo *pTI; if (IID_NULL != riid) { return DISP_E_UNKNOWNINTERFACE; } hr = GetTypeInfo(0, lcid, &pTI); if (SUCCEEDED(hr)) { hr = DispGetIDsOfNames(pTI, rgszNames, cNames, rgDispId); pTI->Release(); } return hr; } HRESULT OleAutoDispatch::GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTypeInfo ) { HRESULT hr = NOERROR; ITypeLib *pTypeLib; ITypeInfo **ppTI; if (0 != iTInfo) return TYPE_E_ELEMENTNOTFOUND; if (NULL == ppTypeInfo) return E_INVALIDARG; *ppTypeInfo = NULL; switch(PRIMARYLANGID(lcid)) { case LANG_NEUTRAL: case LANG_ENGLISH: ppTI = &m_pTypeInfo; break; default: return DISP_E_UNKNOWNLCID; } if (NULL == *ppTI) { hr = LoadRegTypeLib(m_idTypeLib, 1, 0, PRIMARYLANGID(lcid), &pTypeLib); if (FAILED(hr)) { switch(PRIMARYLANGID(lcid)) { case LANG_NEUTRAL: case LANG_ENGLISH: hr = LoadTypeLib(m_strTypeLib, &pTypeLib); break; default: break; } } if (SUCCEEDED(hr)) { hr = pTypeLib->GetTypeInfoOfGuid(m_idDispInterface, ppTI); pTypeLib->Release(); } } if (SUCCEEDED(hr)) { (*ppTI)->AddRef(); *ppTypeInfo = *ppTI; } return hr; } HRESULT OleAutoDispatch::GetTypeInfoCount( UINT *pctinfo ) { // // 1 = "We implement GetTypeInfo" // *pctinfo = 1; return NOERROR; } HRESULT OleAutoDispatch::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr ) { HRESULT hr; ITypeInfo *pTI; if (IID_NULL != riid) { return DISP_E_UNKNOWNINTERFACE; } hr = GetTypeInfo(0, lcid, &pTI); if (SUCCEEDED(hr)) { hr = pTI->Invoke(m_pObject, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); pTI->Release(); } return hr; }