home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap02 / reuse / animal.cpp next >
C/C++ Source or Header  |  1995-08-24  |  5KB  |  245 lines

  1. /*
  2.  * ANIMAL.CPP
  3.  *
  4.  * Aggregatable Animal Object Implementation, Chapter 2
  5.  *
  6.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  7.  *
  8.  * Kraig Brockschmidt, Microsoft
  9.  * Internet  :  kraigb@microsoft.com
  10.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  11.  */
  12.  
  13. #include <windows.h>
  14. #include "reuse.h"
  15. #include "animal.h"
  16.  
  17.  
  18. /*
  19.  * CreateAnimal
  20.  *
  21.  * Purpose:
  22.  *  Creates an instance of Animal returning a requested interface
  23.  *  pointer.
  24.  *
  25.  * Parameters:
  26.  *  pUnkOuter       IUnknown * holding the outer unknown.  Can
  27.  *                  be NULL.
  28.  *  riid            REFIID interface requested by the caller.
  29.  *  ppv             void ** in which to return the interface pointer.
  30.  *
  31.  * Return Value:
  32.  *  HRESULT         NOERROR if successful, CLASS_E_NOAGREGATION if
  33.  *                  IUnknown is not requested with non-NULL pUnkOuter,
  34.  *                  or other error as appropriate.
  35.  */
  36.  
  37. HRESULT CreateAnimal(IUnknown *pUnkOuter, REFIID riid, void **ppv)
  38.     {
  39.     CAnimal    *pObj;
  40.  
  41.     //If aggregation is on, check riid==IID_IUnknown
  42.     if (NULL!=pUnkOuter && riid!=IID_IUnknown)
  43.         return ResultFromScode(CLASS_E_NOAGGREGATION);
  44.  
  45.     pObj=new CAnimal(pUnkOuter);
  46.  
  47.     if (NULL==pObj)
  48.         return E_OUTOFMEMORY;
  49.  
  50.     if (!pObj->Init())
  51.         return E_FAIL;
  52.  
  53.     return pObj->QueryInterface(riid, (PPVOID)ppv);
  54.     }
  55.  
  56.  
  57.  
  58.  
  59.  
  60. /*
  61.  * CAnimal::CAnimal
  62.  * CAnimal::~CAnimal
  63.  *
  64.  * Constructor Parameters:
  65.  *  pUnkOuter       IUnknown * holding the outer unknown.  Can
  66.  *                  be NULL.
  67.  */
  68.  
  69. CAnimal::CAnimal(IUnknown *pUnkOuter)
  70.     {
  71.     m_cRef=0;
  72.     m_pImpIAnimal=NULL;
  73.  
  74.     //No AddRef necessary if non-NULL as we're nested.
  75.     m_pUnkOuter=pUnkOuter;
  76.     return;
  77.     }
  78.  
  79. CAnimal::~CAnimal(void)
  80.     {
  81.     DeleteInterfaceImp(m_pImpIAnimal);
  82.     return;
  83.     }
  84.  
  85.  
  86.  
  87. /*
  88.  * CAnimal::Init
  89.  *
  90.  * Purpose:
  91.  *  Instantiates the interface implementations for this object.
  92.  *
  93.  * Parameters:
  94.  *  None
  95.  *
  96.  * Return Value:
  97.  *  BOOL            TRUE if initialization succeeds, FALSE otherwise.
  98.  */
  99.  
  100. BOOL CAnimal::Init(void)
  101.     {
  102.     IUnknown   *pUnkOuter=m_pUnkOuter;
  103.  
  104.     //Set up the right unknown for delegation
  105.     if (NULL==pUnkOuter)
  106.         pUnkOuter=this;
  107.  
  108.     m_pImpIAnimal=new CImpIAnimal_A(this, pUnkOuter);
  109.  
  110.     if (NULL==m_pImpIAnimal)
  111.         return FALSE;
  112.  
  113.     return TRUE;
  114.     }
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121. /*
  122.  * CAnimal::QueryInterface
  123.  * CAnimal::AddRef
  124.  * CAnimal::Release
  125.  *
  126.  * Purpose:
  127.  *  Non-delegating IUnknown implementation.
  128.  */
  129.  
  130. STDMETHODIMP CAnimal::QueryInterface(REFIID riid, PPVOID ppv)
  131.     {
  132.     *ppv=NULL;
  133.  
  134.     if (IID_IUnknown==riid)
  135.         *ppv=this;
  136.  
  137.     if (IID_IAnimal==riid)
  138.         *ppv=m_pImpIAnimal;
  139.  
  140.     if (NULL==*ppv)
  141.         return ResultFromScode(E_NOINTERFACE);
  142.  
  143.     ((LPUNKNOWN)*ppv)->AddRef();
  144.     return NOERROR;
  145.     }
  146.  
  147.  
  148. DWORD CAnimal::AddRef(void)
  149.     {
  150.     return ++m_cRef;
  151.     }
  152.  
  153. DWORD CAnimal::Release(void)
  154.     {
  155.     if (0!=--m_cRef)
  156.         return m_cRef;
  157.  
  158.     delete this;
  159.     return 0;
  160.     }
  161.  
  162.  
  163.  
  164.  
  165. //CImpIAnimal_A interface implementation
  166.  
  167.  
  168. /*
  169.  * CImpIAnimal_A::CImpIAnimal_A
  170.  * CImpIAnimal_A::~CImpIAnimal_A
  171.  *
  172.  * Constructor Parameters:
  173.  *  pObj            PCAnimal to the outer object
  174.  *  pUnkOuter       IUnknown * to which to delegate.
  175.  */
  176.  
  177. CImpIAnimal_A::CImpIAnimal_A(PCAnimal pObj, IUnknown *pUnkOuter)
  178.     {
  179.     m_cRef=0;
  180.     m_pObj=pObj;
  181.     m_pUnkOuter=pUnkOuter;  //No AddRef, we're nested
  182.     return;
  183.     }
  184.  
  185. CImpIAnimal_A::~CImpIAnimal_A(void)
  186.     {
  187.     return;
  188.     }
  189.  
  190.  
  191.  
  192. /*
  193.  * CImpIAnimal_A::QueryInterface
  194.  * CImpIAnimal_A::AddRef
  195.  * CImpIAnimal_A::Release
  196.  *
  197.  * IUnknown members that delegate to m_pUnkOuter, whatever it is.
  198.  */
  199.  
  200. STDMETHODIMP CImpIAnimal_A::QueryInterface(REFIID riid, PPVOID ppv)
  201.     {
  202.     return m_pUnkOuter->QueryInterface(riid, ppv);
  203.     }
  204.  
  205. DWORD CImpIAnimal_A::AddRef(void)
  206.     {
  207.     ++m_cRef;
  208.     return m_pUnkOuter->AddRef();
  209.     }
  210.  
  211. DWORD CImpIAnimal_A::Release(void)
  212.     {
  213.     --m_cRef;
  214.     return m_pUnkOuter->Release();
  215.     }
  216.  
  217.  
  218.  
  219. /*
  220.  * CImpIAnimal_A::Eat
  221.  * CImpIAnimal_A::Sleep
  222.  * CImpIAnimal_A::Procreate
  223.  *
  224.  * Purpose:
  225.  *  Empty sample functions, no parameters, return NOERROR
  226.  */
  227.  
  228. STDMETHODIMP CImpIAnimal_A::Eat(void)
  229.     {
  230.     ODS("Animal's IAnimal::Eat called");
  231.     return NOERROR;
  232.     }
  233.  
  234. STDMETHODIMP CImpIAnimal_A::Sleep(void)
  235.     {
  236.     ODS("Animal's IAnimal::Sleep called");
  237.     return NOERROR;
  238.     }
  239.  
  240. STDMETHODIMP CImpIAnimal_A::Procreate(void)
  241.     {
  242.     ODS("Animal's IAnimal::Procreate called");
  243.     return NOERROR;
  244.     }
  245.