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 / interfac / ienumunk.cpp < prev    next >
C/C++ Source or Header  |  1996-05-21  |  5KB  |  255 lines

  1. /*
  2.  * IENUMUNK.CPP
  3.  *
  4.  * Standard implementation of an IUnknown enumerator with the
  5.  * IEnumUnknown interface that will generally not need
  6.  * modification.
  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 "ienumunk.h"
  17.  
  18.  
  19. /*
  20.  * CEnumUnknown::CEnumUnknown
  21.  * CEnumUnknown::~CEnumUnknown
  22.  *
  23.  * Parameters (Constructor):
  24.  *  pUnkRef         LPUNKNOWN to use for reference counting.
  25.  *  cUnk            ULONG number of LPUNKNOWNs in prgUnk
  26.  *  prgUnk          LPUNKNOWN * to the array to enumerate.
  27.  */
  28.  
  29. CEnumUnknown::CEnumUnknown(LPUNKNOWN pUnkRef, ULONG cUnk
  30.     , LPUNKNOWN *prgUnk)
  31.     {
  32.     UINT        i;
  33.  
  34.     m_cRef=0;
  35.     m_pUnkRef=pUnkRef;
  36.  
  37.     m_iCur=0;
  38.     m_cUnk=cUnk;
  39.     m_prgUnk=new LPUNKNOWN[(UINT)cUnk];
  40.  
  41.     if (NULL!=m_prgUnk)
  42.         {
  43.         for (i=0; i < cUnk; i++)
  44.             m_prgUnk[i]=prgUnk[i];
  45.         }
  46.  
  47.     return;
  48.     }
  49.  
  50.  
  51. CEnumUnknown::~CEnumUnknown(void)
  52.     {
  53.     if (NULL!=m_prgUnk)
  54.         delete [] m_prgUnk;
  55.  
  56.     return;
  57.     }
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64. /*
  65.  * CEnumUnknown::QueryInterface
  66.  * CEnumUnknown::AddRef
  67.  * CEnumUnknown::Release
  68.  *
  69.  * Purpose:
  70.  *  IUnknown members for CEnumUnknown object.
  71.  */
  72.  
  73. STDMETHODIMP CEnumUnknown::QueryInterface(REFIID riid
  74.     , LPVOID *ppv)
  75.     {
  76.     *ppv=NULL;
  77.  
  78.     /*
  79.      * Enumerators are separate objects with their own
  80.      * QueryInterface behavior.
  81.      */
  82.     if (IID_IUnknown==riid || IID_IEnumUnknown==riid)
  83.         *ppv=(LPVOID)this;
  84.  
  85.     if (NULL!=*ppv)
  86.         {
  87.         ((LPUNKNOWN)*ppv)->AddRef();
  88.         return NOERROR;
  89.         }
  90.  
  91.     return ResultFromScode(E_NOINTERFACE);
  92.     }
  93.  
  94.  
  95. STDMETHODIMP_(ULONG) CEnumUnknown::AddRef(void)
  96.     {
  97.     ++m_cRef;
  98.     m_pUnkRef->AddRef();
  99.     return m_cRef;
  100.     }
  101.  
  102. STDMETHODIMP_(ULONG) CEnumUnknown::Release(void)
  103.     {
  104.     m_pUnkRef->Release();
  105.  
  106.     if (0L!=--m_cRef)
  107.         return m_cRef;
  108.  
  109.     delete this;
  110.     return 0;
  111.     }
  112.  
  113.  
  114.  
  115.  
  116.  
  117. /*
  118.  * CEnumUnknown::Next
  119.  *
  120.  * Purpose:
  121.  *  Returns the next element in the enumeration.
  122.  *
  123.  * Parameters:
  124.  *  cUnk            ULONG number of LPUNKNOWNs to return.
  125.  *  ppUnk           LPUNKNOWN * in which to store the returned
  126.  *                  pointer.
  127.  *  pulUnk          ULONG * in which to return how many we
  128.  *                  enumerated.
  129.  *
  130.  * Return Value:
  131.  *  HRESULT         NOERROR if successful, S_FALSE otherwise,
  132.  */
  133.  
  134. STDMETHODIMP CEnumUnknown::Next(ULONG cUnk, LPUNKNOWN *ppUnk
  135.     , ULONG *pulUnk)
  136.     {
  137.     ULONG               cReturn=0L;
  138.  
  139.     if (NULL==m_prgUnk)
  140.         return ResultFromScode(S_FALSE);
  141.  
  142.     if (NULL==pulUnk)
  143.         {
  144.         if (1L!=cUnk)
  145.             return ResultFromScode(E_POINTER);
  146.         }
  147.     else
  148.         *pulUnk=0L;
  149.  
  150.     if (NULL==ppUnk || m_iCur >= m_cUnk)
  151.         return ResultFromScode(S_FALSE);
  152.  
  153.     while (m_iCur < m_cUnk && cUnk > 0)
  154.         {
  155.         *ppUnk=m_prgUnk[m_iCur++];
  156.  
  157.         if (NULL!=*ppUnk)
  158.             (*ppUnk)->AddRef();
  159.  
  160.         ppUnk++;
  161.         cReturn++;
  162.         cUnk--;
  163.         }
  164.  
  165.     if (NULL!=pulUnk)
  166.         *pulUnk=cReturn;
  167.  
  168.     return NOERROR;
  169.     }
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177. /*
  178.  * CEnumUnknown::Skip
  179.  *
  180.  * Purpose:
  181.  *  Skips the next n elements in the enumeration.
  182.  *
  183.  * Parameters:
  184.  *  cSkip           ULONG number of elements to skip.
  185.  *
  186.  * Return Value:
  187.  *  HRESULT         NOERROR if successful, S_FALSE if we could not
  188.  *                  skip the requested number.
  189.  */
  190.  
  191. STDMETHODIMP CEnumUnknown::Skip(ULONG cSkip)
  192.     {
  193.     if (((m_iCur+cSkip) >= m_cUnk) || NULL==m_prgUnk)
  194.         return ResultFromScode(S_FALSE);
  195.  
  196.     m_iCur+=cSkip;
  197.     return NOERROR;
  198.     }
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205. /*
  206.  * CEnumUnknown::Reset
  207.  *
  208.  * Purpose:
  209.  *  Resets the current element index in the enumeration to zero.
  210.  *
  211.  * Parameters:
  212.  *  None
  213.  */
  214.  
  215. STDMETHODIMP CEnumUnknown::Reset(void)
  216.     {
  217.     m_iCur=0;
  218.     return NOERROR;
  219.     }
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226. /*
  227.  * CEnumUnknown::Clone
  228.  *
  229.  * Purpose:
  230.  *  Returns another IEnumUnknown with the same state as ourselves.
  231.  *
  232.  * Parameters:
  233.  *  ppEnum          LPENUMUNKNOWN * in which to return the
  234.  *                  new object.
  235.  */
  236.  
  237. STDMETHODIMP CEnumUnknown::Clone(LPENUMUNKNOWN *ppEnum)
  238.     {
  239.     PCEnumUnknown   pNew;
  240.  
  241.     *ppEnum=NULL;
  242.  
  243.     //Create the clone
  244.     pNew=new CEnumUnknown(m_pUnkRef, m_cUnk, m_prgUnk);
  245.  
  246.     if (NULL==pNew)
  247.         return ResultFromScode(E_OUTOFMEMORY);
  248.  
  249.     pNew->AddRef();
  250.     pNew->m_iCur=m_iCur;
  251.  
  252.     *ppEnum=pNew;
  253.     return NOERROR;
  254.     }
  255.