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 / query / object3.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  5KB  |  218 lines

  1. /*
  2.  * OBJECT3.CPP
  3.  *
  4.  * Object implementation using multiple inheritance.
  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 "query.h"
  15.  
  16.  
  17. //Message strings for the interface functions
  18. static TCHAR szMessage[]=TEXT("Message from ISampleOne::GetMessage");
  19. static TCHAR szString[] =TEXT("Message from ISampleTwo::GetString");
  20.  
  21.  
  22. /*
  23.  * CreateObject3
  24.  *
  25.  * Purpose:
  26.  *  Creates an instance of Object2 returning an IUnknown
  27.  *  interface.
  28.  *
  29.  * Parameters:
  30.  *  ppUnk           IUnknown ** in which to return the
  31.  *                  interface pointer.
  32.  *
  33.  * Return Value:
  34.  *  BOOL            TRUE if the function is successful,
  35.  *                  FALSE otherwise.
  36.  */
  37.  
  38. BOOL CreateObject3(IUnknown **ppUnk)
  39.     {
  40.     HRESULT     hr;
  41.     CObject3   *pObj;
  42.  
  43.     if (NULL==ppUnk)
  44.         return FALSE;
  45.  
  46.     //Create the new object, which gives us a C++ object pointer
  47.     pObj=new CObject3();
  48.  
  49.     if (NULL==pObj)
  50.         return FALSE;
  51.  
  52.     /*
  53.      * Now get the IUnknown interface to this object and make
  54.      * sure that it's reference count is correct.  We could either
  55.      * typecast pObj to IUnknown and call AddRef explicitly, or
  56.      * we can simply call pObj->QueryInterface and let it do the
  57.      * typecast and the AddRef for us.
  58.      */
  59.     hr=pObj->QueryInterface(IID_IUnknown, (PPVOID)ppUnk);
  60.     return SUCCEEDED(hr);
  61.     }
  62.  
  63.  
  64.  
  65.  
  66.  
  67. /*
  68.  * CObject3::CObject3
  69.  * CObject3::~CObject3
  70.  *
  71.  * Constructor Parameters:
  72.  *  None
  73.  */
  74.  
  75. CObject3::CObject3(void)
  76.     {
  77.     m_cRef=0;
  78.     return;
  79.     }
  80.  
  81. CObject3::~CObject3(void)
  82.     {
  83.     return;
  84.     }
  85.  
  86.  
  87.  
  88.  
  89.  
  90. /*
  91.  * CObject3::QueryInterface
  92.  *
  93.  * Purpose:
  94.  *  Manages the interfaces for this object which supports the
  95.  *  IUnknown, ISampleOne, and ISampleTwo interfaces.
  96.  *
  97.  * Parameters:
  98.  *  riid            REFIID of the interface to return.
  99.  *  ppv             PPVOID in which to store the pointer.
  100.  *
  101.  * Return Value:
  102.  *  HRESULT         NOERROR on success, E_NOINTERFACE if the
  103.  *                  interface is not supported.
  104.  */
  105.  
  106. STDMETHODIMP CObject3::QueryInterface(REFIID riid, PPVOID ppv)
  107.     {
  108.     //Always NULL the out-parameters
  109.     *ppv=NULL;
  110.  
  111.     /*
  112.      * Since all the interfaces are part of this same object,
  113.      * we *must* use typecasts to set up the right vtables from
  114.      * the 'this' pointer.  Casting to an interface will give
  115.      * us a pointer that points to exactly that interface vtable.
  116.      *
  117.      * Note that since we don't have an explicit IUnknown base,
  118.      * responding to IUnknown here simply return ISampleOne, which
  119.      * has the right IUnknown vtable anyway.
  120.      */
  121.     if (IID_IUnknown==riid || IID_ISampleOne==riid)
  122.         *ppv=(ISampleOne *)this;
  123.  
  124.     if (IID_ISampleTwo==riid)
  125.         *ppv=(ISampleTwo *)this;
  126.  
  127.     if (NULL==*ppv)
  128.         return ResultFromScode(E_NOINTERFACE);
  129.  
  130.     //AddRef any interface we'll return.
  131.     ((LPUNKNOWN)*ppv)->AddRef();
  132.     return NOERROR;
  133.     }
  134.  
  135.  
  136.  
  137. /*
  138.  * CObject3::AddRef
  139.  * CObject3::Release
  140.  *
  141.  * Reference counting members.  When Release sees a zero count
  142.  * the object destroys itself.
  143.  */
  144.  
  145. DWORD CObject3::AddRef(void)
  146.     {
  147.     return ++m_cRef;
  148.     }
  149.  
  150. DWORD CObject3::Release(void)
  151.     {
  152.     if (0!=--m_cRef)
  153.         return m_cRef;
  154.  
  155.     delete this;
  156.     return 0;
  157.     }
  158.  
  159.  
  160.  
  161.  
  162. /*
  163.  * CObject3::GetMessage
  164.  *
  165.  * Purpose:
  166.  *  Returns a string to the caller.  This is the implementation
  167.  *  of ISampleOne::GetMessage.
  168.  *
  169.  * Parameters:
  170.  *  psz             LPTSTR in which to store the string.
  171.  *  cch             UINT size of psz.
  172.  *
  173.  * Return Value:
  174.  *  HRESULT         NOERROR if the string is stored, E_OUTOFMEMORY
  175.  *                  if the buffer is too small.
  176.  */
  177.  
  178. STDMETHODIMP CObject3::GetMessage(LPTSTR psz, UINT cch)
  179.     {
  180.     if (NULL==psz)
  181.         return ResultFromScode(E_POINTER);
  182.  
  183.     if (cch < (UINT)lstrlen(szMessage))
  184.         return ResultFromScode(E_OUTOFMEMORY);
  185.  
  186.     lstrcpy(psz, szMessage);
  187.     return NOERROR;
  188.     }
  189.  
  190.  
  191. /*
  192.  * CObject3::GetString
  193.  *
  194.  * Purpose:
  195.  *  Returns a string to the caller.  This is the implementation
  196.  *  of ISampleTwo::GetString.
  197.  *
  198.  * Parameters:
  199.  *  psz             LPTSTR in which to store the string.
  200.  *  cch             UINT size of psz.
  201.  *
  202.  * Return Value:
  203.  *  HRESULT         NOERROR if the string is stored, E_OUTOFMEMORY
  204.  *                  if the buffer is too small.
  205.  */
  206.  
  207. STDMETHODIMP CObject3::GetString(LPTSTR psz, UINT cch)
  208.     {
  209.     if (NULL==psz)
  210.         return ResultFromScode(E_POINTER);
  211.  
  212.     if (cch < (UINT)lstrlen(szString))
  213.         return ResultFromScode(E_OUTOFMEMORY);
  214.  
  215.     lstrcpy(psz, szString);
  216.     return NOERROR;
  217.     }
  218.