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 / chap06 / ekoala4 / koala.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  10KB  |  481 lines

  1. /*
  2.  * KOALA.CPP
  3.  * Koala Object with Custom Interface, Chapter 6
  4.  *
  5.  * Implementation of the CKoala object with a custom interface
  6.  * to demonstrate local/remote transparency.
  7.  *
  8.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Microsoft
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #include "koala.h"
  17.  
  18.  
  19. /*
  20.  * CKoala::CKoala
  21.  * CKoala::~CKoala
  22.  *
  23.  * Parameters (Constructor):
  24.  *  pUnkOuter       LPUNKNOWN of a controlling unknown.
  25.  *  pfnDestroy      PFNDESTROYED to call when an object
  26.  *                  is destroyed.
  27.  */
  28.  
  29. CKoala::CKoala(LPUNKNOWN pUnkOuter, PFNDESTROYED pfnDestroy)
  30.     {
  31.     m_cRef=0;
  32.     m_pUnkOuter=pUnkOuter;
  33.     m_pfnDestroy=pfnDestroy;
  34.  
  35.     //CHAPTER6MOD
  36.     m_pImpIAnimal=NULL;
  37.     m_pImpIKoala=NULL;
  38.  
  39.     m_fJustAte=FALSE;
  40.     m_cSleepAfterEat=0;
  41.     //End CHAPTER6MOD
  42.  
  43.     return;
  44.     }
  45.  
  46.  
  47. CKoala::~CKoala(void)
  48.     {
  49.     //CHAPTER6MOD
  50.     DeleteInterfaceImp(m_pImpIKoala);
  51.     DeleteInterfaceImp(m_pImpIAnimal);
  52.     //End CHAPTER6MOD
  53.     return;
  54.     }
  55.  
  56.  
  57.  
  58. /*
  59.  * CKoala::Init
  60.  *
  61.  * Purpose:
  62.  *  Performs any intiailization of a CKoala that's prone to failure
  63.  *  that we also use internally before exposing the object outside.
  64.  *
  65.  * Parameters:
  66.  *  None
  67.  *
  68.  * Return Value:
  69.  *  BOOL            TRUE if the function is successful,
  70.  *                  FALSE otherwise.
  71.  */
  72.  
  73. BOOL CKoala::Init(void)
  74.     {
  75.     //CHAPTER6MOD
  76.     IUnknown   *pUnkOuter=m_pUnkOuter;
  77.  
  78.     if (NULL==pUnkOuter)
  79.         pUnkOuter=this;
  80.  
  81.     m_pImpIAnimal=new CImpIAnimal(this, pUnkOuter);
  82.  
  83.     if (NULL==m_pImpIAnimal)
  84.         return FALSE;
  85.  
  86.     m_pImpIKoala=new CImpIKoala(this, pUnkOuter);
  87.  
  88.     if (NULL==m_pImpIKoala)
  89.         return FALSE;
  90.     //End CHAPTER6MOD
  91.  
  92.     return TRUE;
  93.     }
  94.  
  95.  
  96.  
  97.  
  98. /*
  99.  * CKoala::QueryInterface
  100.  * CKoala::AddRef
  101.  * CKoala::Release
  102.  *
  103.  * Purpose:
  104.  *  IUnknown members for CKoala object.
  105.  */
  106.  
  107. STDMETHODIMP CKoala::QueryInterface(REFIID riid, PPVOID ppv)
  108.     {
  109.     *ppv=NULL;
  110.  
  111.     /*
  112.      * The only calls for IUnknown are either in a nonaggregated
  113.      * case or when created in an aggregation, so in either case
  114.      * always return our IUnknown for IID_IUnknown.
  115.      */
  116.     if (IID_IUnknown==riid)
  117.         *ppv=this;
  118.  
  119.     //CHAPTER6MOD
  120.     if (IID_IAnimal==riid)
  121.         *ppv=m_pImpIAnimal;
  122.  
  123.     if (IID_IKoala==riid)
  124.         *ppv=m_pImpIKoala;
  125.     //End CHAPTER6MOD
  126.  
  127.     if (NULL!=*ppv)
  128.         {
  129.         ((LPUNKNOWN)*ppv)->AddRef();
  130.         return NOERROR;
  131.         }
  132.  
  133.     return ResultFromScode(E_NOINTERFACE);
  134.     }
  135.  
  136.  
  137. STDMETHODIMP_(ULONG) CKoala::AddRef(void)
  138.     {
  139.     return ++m_cRef;
  140.     }
  141.  
  142.  
  143. STDMETHODIMP_(ULONG) CKoala::Release(void)
  144.     {
  145.     if (0L!=--m_cRef)
  146.         return m_cRef;
  147.  
  148.     if (NULL!=m_pfnDestroy)
  149.         (*m_pfnDestroy)();
  150.  
  151.     delete this;
  152.     return 0;
  153.     }
  154.  
  155.  
  156.  
  157.  
  158. //CHAPTER6MOD
  159.  
  160. //IAnimal implementation
  161.  
  162.  
  163. /*
  164.  * CImpIAnimal::CImpIAnimal
  165.  * CImpIAnimal::~CImpIAnimal
  166.  *
  167.  * Constructor Parameters:
  168.  *  pObj            PCKoala of the object containing us.
  169.  *  pUnkOuter       LPUNKNOWN to which we blindly delegate
  170.  *                  all IUnknown calls.
  171.  */
  172.  
  173. CImpIAnimal::CImpIAnimal(PCKoala pObj, LPUNKNOWN pUnkOuter)
  174.     {
  175.     m_cRef=0;
  176.     m_pObj=pObj;
  177.     m_pUnkOuter=pUnkOuter;
  178.     return;
  179.     }
  180.  
  181. CImpIAnimal::~CImpIAnimal(void)
  182.     {
  183.     return;
  184.     }
  185.  
  186.  
  187.  
  188. /*
  189.  * CImpIAnimal::QueryInterface
  190.  * CImpIAnimal::AddRef
  191.  * CImpIAnimal::Release
  192.  *
  193.  * Purpose:
  194.  *  Delegating IUnknown members for interface implementation.
  195.  */
  196.  
  197. STDMETHODIMP CImpIAnimal::QueryInterface(REFIID riid
  198.     , LPVOID *ppv)
  199.     {
  200.     return m_pUnkOuter->QueryInterface(riid, ppv);
  201.     }
  202.  
  203. STDMETHODIMP_(ULONG) CImpIAnimal::AddRef(void)
  204.     {
  205.     ++m_cRef;
  206.     return m_pUnkOuter->AddRef();
  207.     }
  208.  
  209. STDMETHODIMP_(ULONG) CImpIAnimal::Release(void)
  210.     {
  211.     --m_cRef;
  212.     return m_pUnkOuter->Release();
  213.     }
  214.  
  215.  
  216.  
  217. /*
  218.  * CImpIAnimal::Eat
  219.  *
  220.  * Purpose:
  221.  *  Instructs the animal to eat something, returning what the animal
  222.  *  actually ate which usually goes against recommendation (which is
  223.  *  true for the human animal, too).
  224.  *
  225.  * Parameters:
  226.  *  pszFoodRecommended  LPTSTR describing the food that the animal
  227.  *                      should eat.
  228.  *  pszFoodEaten        LPTSTR describing the food the animal actually
  229.  *                      ate, which may not, of course, be the same as
  230.  *                      what it should eat.
  231.  *  cchEaten            short containing the lenght of pszFoodEaten.
  232.  *
  233.  * Return Value:
  234.  *  HRESULT             NOERROR if food is eaten, S_FALSE if not.
  235.  */
  236.  
  237. STDMETHODIMP CImpIAnimal::Eat(LPTSTR pszFoodRecommended
  238.     , LPTSTR pszFoodEaten, short cchEaten)
  239.     {
  240.     //Koalas aren't don't care what you tell them, they eat one thing
  241.    #ifdef WIN32ANSI
  242.     lstrcpyn(pszFoodEaten, "Eucalyptus Leaves", cchEaten);
  243.    #else
  244.     _tcsncpy(pszFoodEaten, TEXT("Eucalyptus Leaves"), cchEaten);
  245.    #endif
  246.     m_pObj->m_fJustAte=TRUE;
  247.     return NOERROR;
  248.     }
  249.  
  250.  
  251.  
  252. /*
  253.  * CImpIAnimal::Sleep
  254.  *
  255.  * Purpose:
  256.  *  Instructs the animal to sleep for a while.
  257.  *
  258.  * Parameters:
  259.  *  pcMinutes      short * (in-out) containing the number of
  260.  *                 minutes to sleep on entry, then number of
  261.  *                 minutes actually slept on exit
  262.  *
  263.  * Return Value:
  264.  *  HRESULT        NOERROR if sleep taken, S_FALSE if not, where
  265.  *                 *pcMinutes should be zero.
  266.  */
  267.  
  268. STDMETHODIMP CImpIAnimal::Sleep(short *pcMinutes)
  269.     {
  270.     /*
  271.      * Koalas welcome the opportunity to sleep, and will probably
  272.      * sleep longer than you tell them, so return more time than
  273.      * we were told based on IKoala::SleepAfterEating.
  274.      */
  275.     *pcMinutes=*pcMinutes+m_pObj->m_cSleepAfterEat;
  276.     m_pObj->m_fJustAte=FALSE;     //Probably want to eat again
  277.     return NOERROR;
  278.     }
  279.  
  280.  
  281.  
  282. /*
  283.  * CImpIAnimal::Procreate
  284.  *
  285.  * Purpose:
  286.  *  Instructs the animal to procreate.  On entry, the number of
  287.  *  offstring is unknown, so that's an out parameter.
  288.  *
  289.  * Parameters:
  290.  *  pcOffspring     short * (out) in which to store the number
  291.  *                  of new offspring.
  292.  *
  293.  * Return Value:
  294.  *  HRESULT         NOERROR if offspring created, S_FALSE if not
  295.  *                  where *pcOffspring should be zero.
  296.  */
  297.  
  298. STDMETHODIMP CImpIAnimal::Procreate(short *pcOffspring)
  299.     {
  300.     DWORD       dw;
  301.     SCODE       sc=S_FALSE;
  302.  
  303.     /*
  304.      * Koalas like to reproduce when they damn well please and
  305.      * not when someone else tells them, so we'll just check
  306.      * the current time, and if it's appropriate, we'll reproduce.
  307.      * (Simulation:  use GetTickCount to get the system time, then
  308.      * divide by 100 to filter out resolution concerns, then see if
  309.      * the result is an even multiple of 10).
  310.      *
  311.      * Also, Koalas only produce one offspring at a time.  If
  312.      * this was a rabbit, we might get anywhere from 2-20 offspring.
  313.      */
  314.  
  315.     dw=GetTickCount()/100;
  316.  
  317.     if ((dw/10)*10==dw)
  318.         {
  319.         *pcOffspring=1;
  320.         sc=S_OK;
  321.         }
  322.     else
  323.         *pcOffspring=0;
  324.  
  325.     return ResultFromScode(sc);
  326.     }
  327.  
  328.  
  329.  
  330.  
  331. /*
  332.  * CImpIAnimal::WhatKindOfAnimal
  333.  *
  334.  * Purpose:
  335.  *  Returns the IID of the specific animal interface that describes
  336.  *  the type of animal this really is (a much more complex
  337.  *  classification scheme might have IAnimal::WhatGenus and
  338.  *  IGenus::WhatSpecies, etc., but we're just being simple here).
  339.  *
  340.  * Parameters:
  341.  *  pIID            IID * in which to store the specific
  342.  *                  animal IID.
  343.  *
  344.  * Return Value:
  345.  *  HRESULT         NOERROR if the animal type is known,
  346.  *                  S_FALSE if not with *pIID set to IID_NULL.
  347.  */
  348.  
  349. STDMETHODIMP CImpIAnimal::WhatKindOfAnimal(IID *pIID)
  350.     {
  351.     *pIID=IID_IKoala;
  352.     return NOERROR;
  353.     }
  354.  
  355.  
  356.  
  357.  
  358.  
  359. //IKoala implementation
  360.  
  361.  
  362. /*
  363.  * CImpIKoala::CImpIKoala
  364.  * CImpIKoala::~CImpIKoala
  365.  *
  366.  * Constructor Parameters:
  367.  *  pObj            PCKoala of the object containing us.
  368.  *  pUnkOuter       LPUNKNOWN to which we blindly delegate
  369.  *                  all IUnknown calls.
  370.  */
  371.  
  372. CImpIKoala::CImpIKoala(PCKoala pObj, LPUNKNOWN pUnkOuter)
  373.     {
  374.     m_cRef=0;
  375.     m_pObj=pObj;
  376.     m_pUnkOuter=pUnkOuter;
  377.     return;
  378.     }
  379.  
  380. CImpIKoala::~CImpIKoala(void)
  381.     {
  382.     return;
  383.     }
  384.  
  385.  
  386.  
  387. /*
  388.  * CImpIKoala::QueryInterface
  389.  * CImpIKoala::AddRef
  390.  * CImpIKoala::Release
  391.  *
  392.  * Purpose:
  393.  *  Delegating IUnknown members for interface implementation.
  394.  */
  395.  
  396. STDMETHODIMP CImpIKoala::QueryInterface(REFIID riid
  397.     , LPVOID *ppv)
  398.     {
  399.     return m_pUnkOuter->QueryInterface(riid, ppv);
  400.     }
  401.  
  402. STDMETHODIMP_(ULONG) CImpIKoala::AddRef(void)
  403.     {
  404.     ++m_cRef;
  405.     return m_pUnkOuter->AddRef();
  406.     }
  407.  
  408. STDMETHODIMP_(ULONG) CImpIKoala::Release(void)
  409.     {
  410.     --m_cRef;
  411.     return m_pUnkOuter->Release();
  412.     }
  413.  
  414.  
  415.  
  416. /*
  417.  * CImpIKoala::ClimbEucalyptusTree
  418.  *
  419.  * Purpose:
  420.  *  Tells the Koala to go climb a tree, which means eating, which
  421.  *  a koala is probably more than happy to do.
  422.  *
  423.  * Parameters:
  424.  *  iTree           short identifying the tree to climb.
  425.  *
  426.  * Return Value:
  427.  *  HRESULT         NOERROR if tree climbed, S_FALSE if not.
  428.  */
  429.  
  430. STDMETHODIMP CImpIKoala::ClimbEucalyptusTree(short iTree)
  431.     {
  432.     //Nothing to demonstrate...
  433.     return NOERROR;
  434.     }
  435.  
  436.  
  437.  
  438. /*
  439.  * CImpIKoala::PouchOpensDown
  440.  *
  441.  * Purpose:
  442.  *  Do-nothing function to demonstrate a void argument list.
  443.  *
  444.  * Parameters:
  445.  *  None
  446.  *
  447.  * Return Value:
  448.  *  HRESULT             NOERROR
  449.  */
  450.  
  451. STDMETHODIMP CImpIKoala::PouchOpensDown(void)
  452.     {
  453.     //Nothing to demonstrate...
  454.     return NOERROR;
  455.     }
  456.  
  457.  
  458.  
  459. /*
  460.  * CImpIKoala::SleepAfterEating
  461.  *
  462.  * Purpose:
  463.  *  Tells the Koala to sleep an additional number of minutes after
  464.  *  eating.
  465.  *
  466.  * Parameters:
  467.  *  cMinutes        short * (in) containing the number of
  468.  *                  extra minutes to sleep after eating.
  469.  *
  470.  * Return Value:
  471.  *  HRESULT         NOERROR
  472.  */
  473.  
  474. STDMETHODIMP CImpIKoala::SleepAfterEating(short cMinutes)
  475.     {
  476.     m_pObj->m_cSleepAfterEat=cMinutes;
  477.     return NOERROR;
  478.     }
  479.  
  480. //End CHAPTER6MOD
  481.