OBJECT.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2.  * OBJECT.CPP
  3.  *
  4.  * Connectable Object implementation that supports the sample
  5.  * interface IDuckEvents.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13. #include "connect.h"
  14. /*
  15.  * CConnObject::CConnObject
  16.  * CConnObject::~CConnObject
  17.  *
  18.  * Constructor Parameters:
  19.  *  None
  20.  */
  21. CConnObject::CConnObject(void)
  22.     {
  23.     UINT        i;
  24.     m_cRef=0;
  25.     for (i=0; i < CCONNPOINTS; i++)
  26.         m_rgpConnPt[i]=NULL;
  27.     return;
  28.     }
  29. CConnObject::~CConnObject(void)
  30.     {
  31.     UINT    i;
  32.     for (i=0; i < CCONNPOINTS; i++)
  33.         {
  34.         if (NULL!=m_rgpConnPt[i])
  35.             {
  36.             if (NULL!=m_rgpConnPt[i])
  37.                 delete m_rgpConnPt[i];
  38.             }
  39.         }
  40.     return;
  41.     }
  42. /*
  43.  * CConnObject::Init
  44.  *
  45.  * Purpose:
  46.  *  Instantiates the interface implementations for this object.
  47.  *
  48.  * Parameters:
  49.  *  None
  50.  *
  51.  * Return Value:
  52.  *  BOOL            TRUE if initialization succeeds, FALSE otherwise.
  53.  */
  54. BOOL CConnObject::Init(void)
  55.     {
  56.     UINT    i;
  57.     //Create our connection points
  58.     for (i=0; i < CCONNPOINTS; i++)
  59.         {
  60.         m_rgpConnPt[i]=new CConnectionPoint(this, IID_IDuckEvents);
  61.         if (NULL==m_rgpConnPt[i])
  62.             return FALSE;
  63.         m_rgpConnPt[i]->AddRef();
  64.         }
  65.     return TRUE;
  66.     }
  67. /*
  68.  * CConnObject::QueryInterface
  69.  *
  70.  * Purpose:
  71.  *  Manages the interfaces for this object which supports the
  72.  *  IUnknown, ISampleOne, and ISampleTwo interfaces.
  73.  *
  74.  * Parameters:
  75.  *  riid            REFIID of the interface to return.
  76.  *  ppv             PPVOID in which to store the pointer.
  77.  *
  78.  * Return Value:
  79.  *  HRESULT         NOERROR on success, E_NOINTERFACE if the
  80.  *                  interface is not supported.
  81.  */
  82. STDMETHODIMP CConnObject::QueryInterface(REFIID riid, PPVOID ppv)
  83.     {
  84.     //Always NULL the out-parameters
  85.     *ppv=NULL;
  86.     if (IID_IUnknown==riid || IID_IConnectionPointContainer==riid)
  87.         *ppv=this;
  88.     if (NULL==*ppv)
  89.         return ResultFromScode(E_NOINTERFACE);
  90.     ((LPUNKNOWN)*ppv)->AddRef();
  91.     return NOERROR;
  92.     }
  93. /*
  94.  * CConnObject::AddRef
  95.  * CConnObject::Release
  96.  *
  97.  * Reference counting members.  When Release sees a zero count
  98.  * the object destroys itself.
  99.  */
  100. DWORD CConnObject::AddRef(void)
  101.     {
  102.     return ++m_cRef;
  103.     }
  104. DWORD CConnObject::Release(void)
  105.     {
  106.     if (0!=--m_cRef)
  107.         return m_cRef;
  108.     delete this;
  109.     return 0;
  110.     }
  111. /*
  112.  * CConnObject::EnumConnectionPoints
  113.  *
  114.  * Purpose:
  115.  *  Creates and returns an enumerator object with the
  116.  *  IEnumConnectionPoints interface that will enumerate the
  117.  *  individual connection points supported in this object.
  118.  *
  119.  * Parameters:
  120.  *  ppEnum          LPENUMCONNECTIONPOINTS in which to store the
  121.  *                  IEnumConnectionPoints pointer.
  122.  *
  123.  * Return Value:
  124.  *  HRESULT         NOERROR on success, E_OUTOFMEMORY on failure or
  125.  *                  other error code.
  126.  */
  127. STDMETHODIMP CConnObject::EnumConnectionPoints
  128.     (LPENUMCONNECTIONPOINTS *ppEnum)
  129.     {
  130.     IConnectionPoint       *rgCP[CCONNPOINTS];
  131.     UINT                    i;
  132.     PCEnumConnectionPoints  pEnum;
  133.     *ppEnum=NULL;
  134.     for (i=0; i < CCONNPOINTS; i++)
  135.         rgCP[i]=(IConnectionPoint *)m_rgpConnPt[i];
  136.     //Create the enumerator:  we only have one connection point
  137.     pEnum=new CEnumConnectionPoints(this, CCONNPOINTS, rgCP);
  138.     if (NULL==pEnum)
  139.         return ResultFromScode(E_OUTOFMEMORY);
  140.     pEnum->AddRef();
  141.     *ppEnum=pEnum;
  142.     return NOERROR;
  143.     }
  144. /*
  145.  * CConnObject::FindConnectionPoint
  146.  *
  147.  * Purpose:
  148.  *  Returns a pointer to the IConnectionPoint for a given
  149.  *  outgoing IID.
  150.  *
  151.  * Parameters:
  152.  *  riid            REFIID of the outgoing interface for which
  153.  *                  a connection point is desired.
  154.  *  ppCP            IConnectionPoint ** in which to return
  155.  *                  the pointer after calling AddRef.
  156.  *
  157.  * Return Value:
  158.  *  HRESULT         NOERROR if the connection point is found,
  159.  *                  E_NOINTERFACE if it's not supported.
  160.  */
  161. STDMETHODIMP CConnObject::FindConnectionPoint(REFIID riid
  162.     , IConnectionPoint **ppCP)
  163.     {
  164.     *ppCP=NULL;
  165.     if (IID_IDuckEvents==riid)
  166.         {
  167.         return m_rgpConnPt[0]->QueryInterface(IID_IConnectionPoint
  168.             , (PPVOID)ppCP);
  169.         }
  170.     return ResultFromScode(E_NOINTERFACE);
  171.     }
  172. /*
  173.  * CConnObject::TriggerEvent
  174.  *
  175.  * Purpose:
  176.  *  Functions to make each connection point generate calls
  177.  *  to any connected sinks.  Since these functions are specific
  178.  *  to IDuckEvents, they only deal with the connection point
  179.  *  for that one interface
  180.  *
  181.  * Parameters:
  182.  *  iEvent          UINT of the event to trigger, either
  183.  *                  EVENT_QUACK, EVENT_FLAP, or EVENT_PADDLE.
  184.  *
  185.  * Return Value:
  186.  *  BOOL            TRUE events are triggered, FALSE if there
  187.  *                  are no connected sinks.
  188.  */
  189. BOOL CConnObject::TriggerEvent(UINT iEvent)
  190.     {
  191.     IEnumConnections   *pEnum;
  192.     CONNECTDATA         cd;
  193.     if (FAILED(m_rgpConnPt[0]->EnumConnections(&pEnum)))
  194.         return FALSE;
  195.     while (NOERROR==pEnum->Next(1, &cd, NULL))
  196.         {
  197.         IDuckEvents    *pDuck;
  198.         if (SUCCEEDED(cd.pUnk->QueryInterface(IID_IDuckEvents
  199.             , (PPVOID)&pDuck)))
  200.             {
  201.             switch (iEvent)
  202.                 {
  203.                 case EVENT_QUACK:
  204.                     pDuck->Quack();
  205.                     break;
  206.                 case EVENT_FLAP:
  207.                     pDuck->Flap();
  208.                     break;
  209.                 case EVENT_PADDLE:
  210.                     pDuck->Paddle();
  211.                     break;
  212.                 }
  213.             pDuck->Release();
  214.             }
  215.         cd.pUnk->Release();
  216.         }
  217.     pEnum->Release();
  218.     return TRUE;
  219.     }
  220. //Connection Point Enumerator follows
  221. /*
  222.  * CEnumConnectionPoints::CEnumConnectionPoints
  223.  * CEnumConnectionPoints::~CEnumConnectionPoints
  224.  *
  225.  * Parameters (Constructor):
  226.  *  pUnkRef         LPUNKNOWN to use for reference counting.
  227.  *  cPoints         ULONG number of connection points in prgpCP
  228.  *  rgpCP           IConnectionPoint** to the array to enumerate.
  229.  */
  230. CEnumConnectionPoints::CEnumConnectionPoints(LPUNKNOWN pUnkRef
  231.     , ULONG cPoints, IConnectionPoint **rgpCP)
  232.     {
  233.     UINT        i;
  234.     m_cRef=0;
  235.     m_pUnkRef=pUnkRef;
  236.     m_iCur=0;
  237.     m_cPoints=cPoints;
  238.     m_rgpCP=new IConnectionPoint *[(UINT)cPoints];
  239.     if (NULL!=m_rgpCP)
  240.         {
  241.         for (i=0; i < cPoints; i++)
  242.             {
  243.             m_rgpCP[i]=rgpCP[i];
  244.             m_rgpCP[i]->AddRef();
  245.             }
  246.         }
  247.     return;
  248.     }
  249. CEnumConnectionPoints::~CEnumConnectionPoints(void)
  250.     {
  251.     if (NULL!=m_rgpCP)
  252.         {
  253.         UINT        i;
  254.         for (i=0; i < m_cPoints; i++)
  255.             m_rgpCP[i]->Release();
  256.         delete [] m_rgpCP;
  257.         }
  258.     return;
  259.     }
  260. /*
  261.  * CEnumConnectionPoints::QueryInterface
  262.  * CEnumConnectionPoints::AddRef
  263.  * CEnumConnectionPoints::Release
  264.  *
  265.  * Purpose:
  266.  *  IUnknown members for CEnumConnectionPoints object.
  267.  */
  268. STDMETHODIMP CEnumConnectionPoints::QueryInterface(REFIID riid
  269.     , LPVOID *ppv)
  270.     {
  271.     *ppv=NULL;
  272.     if (IID_IUnknown==riid || IID_IEnumConnectionPoints==riid)
  273.         *ppv=(LPVOID)this;
  274.     if (NULL!=*ppv)
  275.         {
  276.         ((LPUNKNOWN)*ppv)->AddRef();
  277.         return NOERROR;
  278.         }
  279.     return ResultFromScode(E_NOINTERFACE);
  280.     }
  281. STDMETHODIMP_(ULONG) CEnumConnectionPoints::AddRef(void)
  282.     {
  283.     ++m_cRef;
  284.     m_pUnkRef->AddRef();
  285.     return m_cRef;
  286.     }
  287. STDMETHODIMP_(ULONG) CEnumConnectionPoints::Release(void)
  288.     {
  289.     m_pUnkRef->Release();
  290.     if (0L!=--m_cRef)
  291.         return m_cRef;
  292.     delete this;
  293.     return 0;
  294.     }
  295. /*
  296.  * CEnumConnectionPoints::Next
  297.  *
  298.  * Purpose:
  299.  *  Returns the next element in the enumeration.
  300.  *
  301.  * Parameters:
  302.  *  cPoints         ULONG number of connection points to return.
  303.  *  ppCP            IConnectionPoint** in which to store the returned
  304.  *                  pointers.
  305.  *  pulEnum         ULONG * in which to return how many we
  306.  *                  enumerated.
  307.  *
  308.  * Return Value:
  309.  *  HRESULT         NOERROR if successful, S_FALSE otherwise,
  310.  */
  311. STDMETHODIMP CEnumConnectionPoints::Next(ULONG cPoints
  312.     , IConnectionPoint **ppCP, ULONG *pulEnum)
  313.     {
  314.     ULONG               cReturn=0L;
  315.     if (NULL==m_rgpCP)
  316.         return ResultFromScode(S_FALSE);
  317.     if (NULL==ppCP)
  318.         return ResultFromScode(E_POINTER);
  319.     if (NULL==pulEnum)
  320.         {
  321.         if (1L!=cPoints)
  322.             return ResultFromScode(E_POINTER);
  323.         }
  324.     else
  325.         *pulEnum=0L;
  326.     if (NULL==*ppCP || m_iCur >= m_cPoints)
  327.         return ResultFromScode(S_FALSE);
  328.     while (m_iCur < m_cPoints && cPoints > 0)
  329.         {
  330.         *ppCP=m_rgpCP[m_iCur++];
  331.         if (NULL!=*ppCP)
  332.             (*ppCP)->AddRef();
  333.         ppCP++;
  334.         cReturn++;
  335.         cPoints--;
  336.         }
  337.     if (NULL!=pulEnum)
  338.         *pulEnum=cReturn;
  339.     return NOERROR;
  340.     }
  341. STDMETHODIMP CEnumConnectionPoints::Skip(ULONG cSkip)
  342.     {
  343.     if (((m_iCur+cSkip) >= m_cPoints) || NULL==m_rgpCP)
  344.         return ResultFromScode(S_FALSE);
  345.     m_iCur+=cSkip;
  346.     return NOERROR;
  347.     }
  348. STDMETHODIMP CEnumConnectionPoints::Reset(void)
  349.     {
  350.     m_iCur=0;
  351.     return NOERROR;
  352.     }
  353. STDMETHODIMP CEnumConnectionPoints::Clone
  354.     (LPENUMCONNECTIONPOINTS *ppEnum)
  355.     {
  356.     PCEnumConnectionPoints   pNew;
  357.     *ppEnum=NULL;
  358.     //Create the clone
  359.     pNew=new CEnumConnectionPoints(m_pUnkRef, m_cPoints, m_rgpCP);
  360.     if (NULL==pNew)
  361.         return ResultFromScode(E_OUTOFMEMORY);
  362.     pNew->AddRef();
  363.     pNew->m_iCur=m_iCur;
  364.     *ppEnum=pNew;
  365.     return NOERROR;
  366.     }