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 / enumrect / enumcpp.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  6KB  |  307 lines

  1. /*
  2.  * ENUMCPP.CPP
  3.  * Enumerator in C++ Chapter 2
  4.  *
  5.  * Implements the CEnumRECT class
  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.  
  14.  
  15. #include "enumrect.h"
  16.  
  17.  
  18. /*
  19.  * CreateRECTEnumeratorCPP
  20.  *
  21.  * Purpose:
  22.  *  Creates an enumerator object returning an IEnumRECT interface.
  23.  *
  24.  * Parameters:
  25.  *  ppEnum          PENUMRECT * in which to return the
  26.  *                  interface pointer on the created object.
  27.  *
  28.  * Return Value:
  29.  *  BOOL            TRUE if the function is successful,
  30.  *                  FALSE otherwise.
  31.  */
  32.  
  33. BOOL CreateRECTEnumeratorCPP(PENUMRECT *ppEnum)
  34.     {
  35.     PCEnumRect  pER;
  36.     HRESULT     hr;
  37.  
  38.     if (NULL==ppEnum)
  39.         return FALSE;
  40.  
  41.     //Create the object
  42.     pER=new CEnumRect();
  43.  
  44.     if (NULL==pER)
  45.         return FALSE;
  46.  
  47.     //Get the interface, which calls AddRef
  48.     hr=pER->QueryInterface(IID_IEnumRECT, (void **)ppEnum);
  49.     return SUCCEEDED(hr);
  50.     }
  51.  
  52.  
  53.  
  54.  
  55.  
  56. /*
  57.  * CEnumRect::CEnumRect
  58.  * CEnumRect::~CEnumRect
  59.  *
  60.  * Constructor Parameters:
  61.  *  None
  62.  */
  63.  
  64. CEnumRect::CEnumRect(void)
  65.     {
  66.     UINT        i;
  67.  
  68.     //Initialize the array of rectangles
  69.     for (i=0; i < CRECTS; i++)
  70.         SetRect(&m_rgrc[i], i, i*2, i*3, i*4);
  71.  
  72.     //Ref counts always start at zero
  73.     m_cRef=0;
  74.  
  75.     //Current pointer is the first element.
  76.     m_iCur=0;
  77.  
  78.     return;
  79.     }
  80.  
  81.  
  82. CEnumRect::~CEnumRect(void)
  83.     {
  84.     return;
  85.     }
  86.  
  87.  
  88.  
  89.  
  90. /*
  91.  * CEnumRect::QueryInterface
  92.  *
  93.  * Purpose:
  94.  *  Manages interfaces for the CEnumRect object.
  95.  *
  96.  * Parameters:
  97.  *  riid            REFIID of the interface to return.
  98.  *  ppv             PPVOID in which to return the pointer.
  99.  *
  100.  * Return Value:
  101.  *  HRESULT         NOERROR if successful, E_NOINTERFACE if the
  102.  *                  interface is not supported.
  103.  */
  104.  
  105. STDMETHODIMP CEnumRect::QueryInterface(REFIID riid, PPVOID ppv)
  106.     {
  107.     //Always NULL the out-parameters
  108.     *ppv=NULL;
  109.  
  110.     /*
  111.      * No explicit typecast necessary since we singly derive
  112.      * from IEnumRECT.
  113.      */
  114.     if (IID_IUnknown==riid || IID_IEnumRECT==riid)
  115.         *ppv=this;
  116.  
  117.     if (NULL==*ppv)
  118.         return ResultFromScode(E_NOINTERFACE);
  119.  
  120.     //AddRef any interface we'll return.
  121.     ((LPUNKNOWN)*ppv)->AddRef();
  122.     return NOERROR;
  123.     }
  124.  
  125.  
  126.  
  127.  
  128. /*
  129.  * CEnumRect::AddRef
  130.  *
  131.  * Purpose:
  132.  *  Increments the reference count on the object.
  133.  *
  134.  * Parameters:
  135.  *  None
  136.  *
  137.  * Return Value:
  138.  *  ULONG           New reference count.
  139.  */
  140.  
  141. STDMETHODIMP_(ULONG) CEnumRect::AddRef(void)
  142.     {
  143.     return ++m_cRef;
  144.     }
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151. /*
  152.  * CEnumRect::Release
  153.  *
  154.  * Purpose:
  155.  *  Indicates that someone on whose behalf we once AddRef'd has
  156.  *  finished with the object.  We decrement our reference count
  157.  *  and if zero, we delete the object.
  158.  *
  159.  * Parameters:
  160.  *  None
  161.  *
  162.  * Return Value:
  163.  *  ULONG           Current reference count after decrement.  If
  164.  *                  this returns zero then the interface is no
  165.  *                  longer valid.
  166.  */
  167.  
  168. STDMETHODIMP_(ULONG) CEnumRect::Release(void)
  169.     {
  170.     if (0!=--m_cRef)
  171.         return m_cRef;
  172.  
  173.     delete this;
  174.     return 0;
  175.     }
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183. /*
  184.  * CEnumRect::Next
  185.  *
  186.  * Purpose:
  187.  *  Returns the next rectangle in the enumerator.
  188.  *
  189.  * Parameters:
  190.  *  cRect           DWORD number of RECTs to return
  191.  *  prc             LPRECT in which to store the returned RECT.
  192.  *  pdwRects        LPDWORD in which to store the number of
  193.  *                  structs returned.
  194.  *
  195.  * Return Value:
  196.  *  HRESULT         NOERROR if successful, S_FALSE otherwise,
  197.  */
  198.  
  199. STDMETHODIMP CEnumRect::Next(DWORD cRect, LPRECT prc, LPDWORD pdwRects)
  200.     {
  201.     DWORD           cRectReturn=0L;
  202.  
  203.     if (NULL==pdwRects)
  204.         {
  205.         if (1L!=cRect)
  206.             return ResultFromScode(S_FALSE);
  207.         }
  208.     else
  209.         *pdwRects=0L;
  210.  
  211.     if (NULL==prc || (m_iCur >= CRECTS))
  212.         return ResultFromScode(S_FALSE);
  213.  
  214.     while (m_iCur < CRECTS && cRect > 0)
  215.         {
  216.         *prc++=m_rgrc[m_iCur++];
  217.         cRectReturn++;
  218.         cRect--;
  219.         }
  220.  
  221.     if (NULL!=pdwRects)
  222.         *pdwRects=cRectReturn;
  223.  
  224.     return NOERROR;
  225.     }
  226.  
  227.  
  228.  
  229.  
  230.  
  231. /*
  232.  * CEnumRect::Skip
  233.  *
  234.  * Purpose:
  235.  *  Skips the next n elements in the enumerator.
  236.  *
  237.  * Parameters:
  238.  *  cSkip           DWORD number of elements to skip.
  239.  *
  240.  * Return Value:
  241.  *  HRESULT         NOERROR if successful, S_FALSE if we could not
  242.  *                  skip the requested number.
  243.  */
  244.  
  245. STDMETHODIMP CEnumRect::Skip(DWORD cSkip)
  246.     {
  247.     if ((m_iCur+cSkip) >= CRECTS)
  248.         return ResultFromScode(S_FALSE);
  249.  
  250.     m_iCur+=cSkip;
  251.     return NOERROR;
  252.     }
  253.  
  254.  
  255.  
  256.  
  257. /*
  258.  * CEnumRect::Reset
  259.  *
  260.  * Purpose:
  261.  *  Resets the current element in the enumerator to zero.
  262.  *
  263.  * Parameters:
  264.  *  None
  265.  *
  266.  * Return Value:
  267.  *  HRESULT         NOERROR
  268.  */
  269.  
  270. STDMETHODIMP CEnumRect::Reset(void)
  271.     {
  272.     m_iCur=0;
  273.     return NOERROR;
  274.     }
  275.  
  276.  
  277.  
  278.  
  279. /*
  280.  * CImpEnumRECT::Clone
  281.  *
  282.  * Purpose:
  283.  *  Creates a copy enumerator.
  284.  *
  285.  * Parameters:
  286.  *  ppEnum          PENUMRECT * in which to store the clone.
  287.  *
  288.  * Return Value:
  289.  *  HRESULT         NOERROR if successful, error code otherwise.
  290.  */
  291.  
  292. STDMETHODIMP CEnumRect::Clone(PENUMRECT *ppEnum)
  293.     {
  294.     if (CreateRECTEnumeratorCPP(ppEnum))
  295.         {
  296.         /*
  297.          * Copy the current index.  The typecast is safe because
  298.          * we know that the IEnumRECT from the creation function
  299.          * is really a CEnumRect pointer.
  300.          */
  301.         ((PCEnumRect)(*ppEnum))->m_iCur=m_iCur;
  302.         return NOERROR;
  303.         }
  304.  
  305.     return ResultFromScode(E_OUTOFMEMORY);
  306.     }
  307.