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

📄 object.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
字号:
/*
 * OBJECT.CPP
 *
 * Connectable Object implementation that supports the sample
 * interface IDuckEvents.
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  >INTERNET:kraigb@microsoft.com
 */


#include "connect.h"


/*
 * CConnObject::CConnObject
 * CConnObject::~CConnObject
 *
 * Constructor Parameters:
 *  None
 */

CConnObject::CConnObject(void)
    {
    UINT        i;

    m_cRef=0;

    for (i=0; i < CCONNPOINTS; i++)
        m_rgpConnPt[i]=NULL;

    return;
    }

CConnObject::~CConnObject(void)
    {
    UINT    i;

    for (i=0; i < CCONNPOINTS; i++)
        {
        if (NULL!=m_rgpConnPt[i])
            {
            if (NULL!=m_rgpConnPt[i])
                delete m_rgpConnPt[i];
            }
        }

    return;
    }



/*
 * CConnObject::Init
 *
 * Purpose:
 *  Instantiates the interface implementations for this object.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  BOOL            TRUE if initialization succeeds, FALSE otherwise.
 */

BOOL CConnObject::Init(void)
    {
    UINT    i;

    //Create our connection points
    for (i=0; i < CCONNPOINTS; i++)
        {
        m_rgpConnPt[i]=new CConnectionPoint(this, IID_IDuckEvents);

        if (NULL==m_rgpConnPt[i])
            return FALSE;

        m_rgpConnPt[i]->AddRef();
        }

    return TRUE;
    }



/*
 * CConnObject::QueryInterface
 *
 * Purpose:
 *  Manages the interfaces for this object which supports the
 *  IUnknown, ISampleOne, and ISampleTwo interfaces.
 *
 * Parameters:
 *  riid            REFIID of the interface to return.
 *  ppv             PPVOID in which to store the pointer.
 *
 * Return Value:
 *  HRESULT         NOERROR on success, E_NOINTERFACE if the
 *                  interface is not supported.
 */

STDMETHODIMP CConnObject::QueryInterface(REFIID riid, PPVOID ppv)
    {
    //Always NULL the out-parameters
    *ppv=NULL;

    if (IID_IUnknown==riid || IID_IConnectionPointContainer==riid)
        *ppv=this;

    if (NULL==*ppv)
        return ResultFromScode(E_NOINTERFACE);

    ((LPUNKNOWN)*ppv)->AddRef();
    return NOERROR;
    }



/*
 * CConnObject::AddRef
 * CConnObject::Release
 *
 * Reference counting members.  When Release sees a zero count
 * the object destroys itself.
 */

DWORD CConnObject::AddRef(void)
    {
    return ++m_cRef;
    }

DWORD CConnObject::Release(void)
    {
    if (0!=--m_cRef)
        return m_cRef;

    delete this;
    return 0;
    }



/*
 * CConnObject::EnumConnectionPoints
 *
 * Purpose:
 *  Creates and returns an enumerator object with the
 *  IEnumConnectionPoints interface that will enumerate the
 *  individual connection points supported in this object.
 *
 * Parameters:
 *  ppEnum          LPENUMCONNECTIONPOINTS in which to store the
 *                  IEnumConnectionPoints pointer.
 *
 * Return Value:
 *  HRESULT         NOERROR on success, E_OUTOFMEMORY on failure or
 *                  other error code.
 */

STDMETHODIMP CConnObject::EnumConnectionPoints
    (LPENUMCONNECTIONPOINTS *ppEnum)
    {
    IConnectionPoint       *rgCP[CCONNPOINTS];
    UINT                    i;
    PCEnumConnectionPoints  pEnum;

    *ppEnum=NULL;

    for (i=0; i < CCONNPOINTS; i++)
        rgCP[i]=(IConnectionPoint *)m_rgpConnPt[i];

    //Create the enumerator:  we only have one connection point
    pEnum=new CEnumConnectionPoints(this, CCONNPOINTS, rgCP);

    if (NULL==pEnum)
        return ResultFromScode(E_OUTOFMEMORY);

    pEnum->AddRef();
    *ppEnum=pEnum;
    return NOERROR;
    }



/*
 * CConnObject::FindConnectionPoint
 *
 * Purpose:
 *  Returns a pointer to the IConnectionPoint for a given
 *  outgoing IID.
 *
 * Parameters:
 *  riid            REFIID of the outgoing interface for which
 *                  a connection point is desired.
 *  ppCP            IConnectionPoint ** in which to return
 *                  the pointer after calling AddRef.
 *
 * Return Value:
 *  HRESULT         NOERROR if the connection point is found,
 *                  E_NOINTERFACE if it's not supported.
 */

STDMETHODIMP CConnObject::FindConnectionPoint(REFIID riid
    , IConnectionPoint **ppCP)
    {
    *ppCP=NULL;

    if (IID_IDuckEvents==riid)
        {
        return m_rgpConnPt[0]->QueryInterface(IID_IConnectionPoint
            , (PPVOID)ppCP);
        }

    return ResultFromScode(E_NOINTERFACE);
    }



/*
 * CConnObject::TriggerEvent
 *
 * Purpose:
 *  Functions to make each connection point generate calls
 *  to any connected sinks.  Since these functions are specific
 *  to IDuckEvents, they only deal with the connection point
 *  for that one interface
 *
 * Parameters:
 *  iEvent          UINT of the event to trigger, either
 *                  EVENT_QUACK, EVENT_FLAP, or EVENT_PADDLE.
 *
 * Return Value:
 *  BOOL            TRUE events are triggered, FALSE if there
 *                  are no connected sinks.
 */

BOOL CConnObject::TriggerEvent(UINT iEvent)
    {
    IEnumConnections   *pEnum;
    CONNECTDATA         cd;

    if (FAILED(m_rgpConnPt[0]->EnumConnections(&pEnum)))
        return FALSE;

    while (NOERROR==pEnum->Next(1, &cd, NULL))
        {
        IDuckEvents    *pDuck;

        if (SUCCEEDED(cd.pUnk->QueryInterface(IID_IDuckEvents
            , (PPVOID)&pDuck)))
            {
            switch (iEvent)
                {
                case EVENT_QUACK:
                    pDuck->Quack();
                    break;

                case EVENT_FLAP:
                    pDuck->Flap();
                    break;

                case EVENT_PADDLE:
                    pDuck->Paddle();
                    break;
                }

            pDuck->Release();
            }

        cd.pUnk->Release();
        }

    pEnum->Release();
    return TRUE;
    }







//Connection Point Enumerator follows


/*
 * CEnumConnectionPoints::CEnumConnectionPoints
 * CEnumConnectionPoints::~CEnumConnectionPoints
 *
 * Parameters (Constructor):
 *  pUnkRef         LPUNKNOWN to use for reference counting.
 *  cPoints         ULONG number of connection points in prgpCP
 *  rgpCP           IConnectionPoint** to the array to enumerate.
 */

CEnumConnectionPoints::CEnumConnectionPoints(LPUNKNOWN pUnkRef
    , ULONG cPoints, IConnectionPoint **rgpCP)
    {
    UINT        i;

    m_cRef=0;
    m_pUnkRef=pUnkRef;

    m_iCur=0;
    m_cPoints=cPoints;
    m_rgpCP=new IConnectionPoint *[(UINT)cPoints];

    if (NULL!=m_rgpCP)
        {
        for (i=0; i < cPoints; i++)
            {
            m_rgpCP[i]=rgpCP[i];
            m_rgpCP[i]->AddRef();
            }
        }

    return;
    }


CEnumConnectionPoints::~CEnumConnectionPoints(void)
    {
    if (NULL!=m_rgpCP)
        {
        UINT        i;

        for (i=0; i < m_cPoints; i++)
            m_rgpCP[i]->Release();

        delete [] m_rgpCP;
        }

    return;
    }




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

STDMETHODIMP CEnumConnectionPoints::QueryInterface(REFIID riid
    , LPVOID *ppv)
    {
    *ppv=NULL;

    if (IID_IUnknown==riid || IID_IEnumConnectionPoints==riid)
        *ppv=(LPVOID)this;

    if (NULL!=*ppv)
        {
        ((LPUNKNOWN)*ppv)->AddRef();
        return NOERROR;
        }

    return ResultFromScode(E_NOINTERFACE);
    }


STDMETHODIMP_(ULONG) CEnumConnectionPoints::AddRef(void)
    {
    ++m_cRef;
    m_pUnkRef->AddRef();
    return m_cRef;
    }

STDMETHODIMP_(ULONG) CEnumConnectionPoints::Release(void)
    {
    m_pUnkRef->Release();

    if (0L!=--m_cRef)
        return m_cRef;

    delete this;
    return 0;
    }





/*
 * CEnumConnectionPoints::Next
 *
 * Purpose:
 *  Returns the next element in the enumeration.
 *
 * Parameters:
 *  cPoints         ULONG number of connection points to return.
 *  ppCP            IConnectionPoint** in which to store the returned
 *                  pointers.
 *  pulEnum         ULONG * in which to return how many we
 *                  enumerated.
 *
 * Return Value:
 *  HRESULT         NOERROR if successful, S_FALSE otherwise,
 */

STDMETHODIMP CEnumConnectionPoints::Next(ULONG cPoints
    , IConnectionPoint **ppCP, ULONG *pulEnum)
    {
    ULONG               cReturn=0L;

    if (NULL==m_rgpCP)
        return ResultFromScode(S_FALSE);

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

    if (NULL==pulEnum)
        {
        if (1L!=cPoints)
            return ResultFromScode(E_POINTER);
        }
    else
        *pulEnum=0L;

    if (NULL==*ppCP || m_iCur >= m_cPoints)
        return ResultFromScode(S_FALSE);

    while (m_iCur < m_cPoints && cPoints > 0)
        {
        *ppCP=m_rgpCP[m_iCur++];

        if (NULL!=*ppCP)
            (*ppCP)->AddRef();

        ppCP++;
        cReturn++;
        cPoints--;
        }

    if (NULL!=pulEnum)
        *pulEnum=cReturn;

    return NOERROR;
    }







STDMETHODIMP CEnumConnectionPoints::Skip(ULONG cSkip)
    {
    if (((m_iCur+cSkip) >= m_cPoints) || NULL==m_rgpCP)
        return ResultFromScode(S_FALSE);

    m_iCur+=cSkip;
    return NOERROR;
    }


STDMETHODIMP CEnumConnectionPoints::Reset(void)
    {
    m_iCur=0;
    return NOERROR;
    }


STDMETHODIMP CEnumConnectionPoints::Clone
    (LPENUMCONNECTIONPOINTS *ppEnum)
    {
    PCEnumConnectionPoints   pNew;

    *ppEnum=NULL;

    //Create the clone
    pNew=new CEnumConnectionPoints(m_pUnkRef, m_cPoints, m_rgpCP);

    if (NULL==pNew)
        return ResultFromScode(E_OUTOFMEMORY);

    pNew->AddRef();
    pNew->m_iCur=m_iCur;

    *ppEnum=pNew;
    return NOERROR;
    }

⌨️ 快捷键说明

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