⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 autobase.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
字号:
/*
 * AUTOBASE.CPP
 * Cosmo Chapter 14
 *
 * Base object for Cosmo's OLE Automation support.  This class
 * provides the implementation of IDispatch as well as the code
 * that loads the appropriate type information.  This leaves
 * each specific object to implement it's specific interface and
 * little else.
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Right Reserved.
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  INTERNET>kraigb@microsoft.com
 */


#include "cosmo.h"


/*
 * CAutoBase::CAutoBase
 * CAutoBase::~CAutoBase
 *
 * Constructor Parameters:
 *  pv              void * to the frame or document object that
 *                  derived classes will use to access the functions
 *                  they need to implemenet their interface.
 *  hInst           HINSTANCE of the application (for loading
 *                  resources)
 *  riid            REFIID of the interface that this object
 *                  should expose.
 *  rdiid           REFIID of the dispinterface that this
 *                  object should expose.
 *  pfnDestroy      PFNDESTROYED to call when the object
 *                  is destroyed.
 */

CAutoBase::CAutoBase(void *pv, HINSTANCE hInst, REFIID riid
    , REFIID rdiid, PFNDESTROYED pfnDestroy)
    {
    m_cRef=0L;
    m_pfnDestroy=pfnDestroy;

    m_pObj=pv;
    m_hInst=hInst;

    m_iid=riid;
    m_diid=rdiid;

    m_pImpIDispatch=NULL;
    m_pImpIExtConn=NULL;
    return;
    }


CAutoBase::~CAutoBase(void)
    {
    DeleteInterfaceImp(m_pImpIExtConn);
    DeleteInterfaceImp(m_pImpIDispatch);
    return;
    }


/*
 * CAutoBase::Init
 *
 * Purpose:
 *  Performs any intiailization of CAutoBase that's prone to failure
 *  that we also use internally before exposing the object outside.
 *
 * Parameters:
 *  fExtConn        BOOL indicating if we care about external
 *                  connections for shutdown.
 *
 * Return Value:
 *  BOOL            TRUE if the function is successful,
 *                  FALSE otherwise.
 */

BOOL CAutoBase::Init(BOOL fExtConn)
    {
    //The derived class has to supply the IUnknown implementation
    m_pImpIDispatch=new CImpIDispatch(this
        , (IUnknown *)VTableInterface());

    if (NULL==m_pImpIDispatch)
        return FALSE;

    if (fExtConn)
        {
        m_pImpIExtConn=new CImpIExtConn
            ((IUnknown *)VTableInterface());

        if (NULL==m_pImpIExtConn)
            return FALSE;
        }

    return TRUE;
    }



//IDispatch interface implementation

/*
 * CImpIDispatch::CImpIDispatch
 * CImpIDispatch::~CImpIDispatch
 *
 * Parameters (Constructor):
 *  pObj            PCAutoBase to the containing object.
 *  pUnkOuter       LPUNKNOWN to which we delegate.
 */

CImpIDispatch::CImpIDispatch(PCAutoBase pObj, LPUNKNOWN pUnkOuter)
    {
    m_cRef=0;
    m_pObj=pObj;
    m_pUnkOuter=pUnkOuter;
    m_pITypeInfo=NULL;
    return;
    }

CImpIDispatch::~CImpIDispatch(void)
    {
    ReleaseInterface(m_pITypeInfo);
    return;
    }



/*
 * CImpIDispatch::QueryInterface
 * CImpIDispatch::AddRef
 * CImpIDispatch::Release
 *
 * Purpose:
 *  IUnknown members for CImpIDispatch object.
 */

STDMETHODIMP CImpIDispatch::QueryInterface(REFIID riid, PPVOID ppv)
    {
    return m_pUnkOuter->QueryInterface(riid, ppv);
    }


STDMETHODIMP_(ULONG) CImpIDispatch::AddRef(void)
    {
    ++m_cRef;
    return m_pUnkOuter->AddRef();
    }

STDMETHODIMP_(ULONG) CImpIDispatch::Release(void)
    {
    --m_cRef;
    return m_pUnkOuter->Release();
    }



/*
 * CImpIDispatch::GetTypeInfoCount
 * CImpIDispatch::GetTypeInfo
 */

STDMETHODIMP CImpIDispatch::GetTypeInfoCount(UINT *pctInfo)
    {
    //We implement GetTypeInfo so return 1
    *pctInfo=1;
    return NOERROR;
    }

STDMETHODIMP CImpIDispatch::GetTypeInfo(UINT itInfo, LCID lcid
    , ITypeInfo **ppITypeInfo)
    {
    HRESULT     hr;
    ITypeLib   *pITypeLib;
    ITypeInfo **ppITI=NULL;

    if (0!=itInfo)
        return ResultFromScode(TYPE_E_ELEMENTNOTFOUND);

    if (NULL==ppITypeInfo)
        return ResultFromScode(E_POINTER);

    *ppITypeInfo=NULL;

    /*
     * This switch statement is nicely extensible for other
     * languages and other m_pITypeInfo variables (such as it
     * was used in Beeper #2 (see ..\beeper2\beeper.cpp)
     */
    switch (PRIMARYLANGID(lcid))
        {
        case LANG_NEUTRAL:
        case LANG_ENGLISH:
            ppITI=&m_pITypeInfo;
            break;

        default:
            return ResultFromScode(DISP_E_UNKNOWNLCID);
        }

    //Load a type lib if we don't have the information already.
    if (NULL==*ppITI)
        {
        hr=LoadRegTypeLib(LIBID_CosmoTypeLibrary, 1, 0
            , PRIMARYLANGID(lcid), &pITypeLib);

        /*
         * If LoadRegTypeLib fails, try loading directly from
         * our module with LoadTypeLib.
         */
        if (FAILED(hr))
            {
            const int   cch=512;
            TCHAR       szModule[cch];

            GetModuleFileName(m_pObj->m_hInst, szModule, cch);

            switch (PRIMARYLANGID(lcid))
                {
                case LANG_NEUTRAL:
                case LANG_ENGLISH:
                   #ifdef WIN32ANSI
                    OLECHAR szTemp[512];
                    MultiByteToWideChar(CP_ACP, 0, szModule, -1, szTemp, 512);
                    hr=LoadTypeLib(szTemp, &pITypeLib);
                   #else
                    hr=LoadTypeLib(szModule, &pITypeLib);
                   #endif
                    break;

                /*
                 * Easily extensible with additional languages.
                 * Use LoadTypeLibFromResource or specify
                 * separate .TLB files instead of the module name.
                 * Be sure to use your DIR registry key to find
                 * the right path.
                 */
                }
            }

        if (FAILED(hr))
            return hr;

        //Got the type lib, get type info for the interface we want
        hr=pITypeLib->GetTypeInfoOfGuid(m_pObj->m_iid, ppITI);
        pITypeLib->Release();

        if (FAILED(hr))
            return hr;
        }

    //Ref on ITypeInfo holds type library in memory
    (*ppITI)->AddRef();
    *ppITypeInfo=*ppITI;
    return NOERROR;
    }



/*
 * CImpIDispatch::GetIDsOfNames
 * CImpIDispatch::Invoke
 */

STDMETHODIMP CImpIDispatch::GetIDsOfNames(REFIID riid
    , OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgDispID)
    {
    HRESULT     hr;
    ITypeInfo  *pTI;

    if (IID_NULL!=riid)
        return ResultFromScode(DISP_E_UNKNOWNINTERFACE);

    hr=GetTypeInfo(0, lcid, &pTI);

    if (SUCCEEDED(hr))
        {
        hr=DispGetIDsOfNames(pTI, rgszNames, cNames, rgDispID);
        pTI->Release();
        }

    return hr;
    }

STDMETHODIMP CImpIDispatch::Invoke(DISPID dispID, REFIID riid
    , LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams
    , VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
    {
    HRESULT     hr;
    ITypeInfo  *pTI;

    if (IID_NULL!=riid)
        return ResultFromScode(DISP_E_UNKNOWNINTERFACE);

    //Get the ITypeInfo for lcid
    hr=GetTypeInfo(0, lcid, &pTI);

    if (FAILED(hr))
        return hr;

    //Note:  this sample doesn't do anything with exceptions.

    //The VTableInterface function gets us the right pointer
    hr=pTI->Invoke(m_pObj->VTableInterface(), dispID, wFlags
        , pDispParams, pVarResult, pExcepInfo, puArgErr);

    pTI->Release();
    return hr;
    }




//IExternalConnection implementation

/*
 * CImpIExtConn::CImpIExtConn
 * CImpIExtConn::~CImpIExtConn
 *
 * Parameters (Constructor):
 *  pUnkOuter       LPUNKNOWN to which we delegate.
 */

CImpIExtConn::CImpIExtConn(LPUNKNOWN pUnkOuter)
    {
    m_cRef=0;
    m_pUnkOuter=pUnkOuter;
    m_cStrong=0;
    return;
    }

CImpIExtConn::~CImpIExtConn(void)
    {
    return;
    }



/*
 * CImpIExtConn::QueryInterface
 * CImpIExtConn::AddRef
 * CImpIExtConn::Release
 *
 * Purpose:
 *  Delegating IUnknown members for CImpIExtConn.
 */

STDMETHODIMP CImpIExtConn::QueryInterface(REFIID riid
    , LPVOID *ppv)
    {
    return m_pUnkOuter->QueryInterface(riid, ppv);
    }


STDMETHODIMP_(ULONG) CImpIExtConn::AddRef(void)
    {
    ++m_cRef;
    return m_pUnkOuter->AddRef();
    }

STDMETHODIMP_(ULONG) CImpIExtConn::Release(void)
    {
    --m_cRef;
    return m_pUnkOuter->Release();
    }




/*
 * CImpIExtConn::AddConnection
 *
 * Purpose:
 *  Informs the object that a connection has been made to it.  We
 *  count only strong references.
 *
 * Parameters:
 *  dwConn          DWORD identifying the type of connection, taken
 *                  from the EXTCONN enumeration.
 *  dwReserved      DWORD reserved.  This is used inside OLE and
 *                  should not be validated.
 *
 * Return Value:
 *  DWORD           The number of connection counts on the
 *                  object, used for debugging purposes only.
 */

STDMETHODIMP_(DWORD) CImpIExtConn::AddConnection
    (DWORD dwConn, DWORD dwReserved)
    {
    if (EXTCONN_STRONG==dwConn)
        {
        m_cStrong++;
        return m_cStrong;
        }

    return 0L;
    }






/*
 * CImpIExtConn::ReleaseConnection
 *
 * Purpose:
 *  Informs an object that a connection has been taken away from
 *  it in which case the object may need to shut down.
 *
 * Parameters:
 *  dwConn              DWORD identifying the type of connection,
 *                      taken from the EXTCONN enumeration.
 *  dwReserved          DWORD reserved.  This is used inside OLE and
 *                      should not be validated.
 *  fLastReleaseCloses  BOOL indicating if the last call to this
 *                      function should close the object.
 *
 * Return Value:
 *  DWORD           The number of remaining connection counts on
 *                  the object, used for debugging purposes only.
 */

STDMETHODIMP_(DWORD) CImpIExtConn::ReleaseConnection
    (DWORD dwConn, DWORD dwReserved, BOOL fLastReleaseCloses)
    {
    DWORD       dw=0L;

    if (EXTCONN_STRONG==dwConn)
        {
        dw=--m_cStrong;

        /*
         * Note that in the way we're using this interface we
         * don't care about fLastReleaseCloses.
         */
        if (0L==m_cStrong)
            m_pUnkOuter->Release();     //Closes app or doc
        }

    return dw;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -