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 / chap10 / ddataobj / ienumfe.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  5KB  |  260 lines

  1. /*
  2.  * IENUMFE.CPP
  3.  * Data Object Chapter 10
  4.  *
  5.  * Standard implementation of a FORMATETC enumerator with the
  6.  * IEnumFORMATETC interface that will generally not need
  7.  * modification.
  8.  *
  9.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Microsoft
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #include "dataobj.h"
  18.  
  19.  
  20. /*
  21.  * CEnumFormatEtc::CEnumFormatEtc
  22.  * CEnumFormatEtc::~CEnumFormatEtc
  23.  *
  24.  * Parameters (Constructor):
  25.  *  cFE             ULONG number of FORMATETCs in pFE
  26.  *  prgFE           LPFORMATETC to the array to enumerate.
  27.  */
  28.  
  29. CEnumFormatEtc::CEnumFormatEtc(ULONG cFE, LPFORMATETC prgFE)
  30.     {
  31.     UINT        i;
  32.  
  33.     m_cRef=0;
  34.     m_iCur=0;
  35.     m_cfe=cFE;
  36.     m_prgfe=new FORMATETC[(UINT)cFE];
  37.  
  38.     if (NULL!=m_prgfe)
  39.         {
  40.         for (i=0; i < cFE; i++)
  41.             m_prgfe[i]=prgFE[i];
  42.         }
  43.  
  44.     return;
  45.     }
  46.  
  47.  
  48. CEnumFormatEtc::~CEnumFormatEtc(void)
  49.     {
  50.     if (NULL!=m_prgfe)
  51.         delete [] m_prgfe;
  52.  
  53.     return;
  54.     }
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61. /*
  62.  * CEnumFormatEtc::QueryInterface
  63.  * CEnumFormatEtc::AddRef
  64.  * CEnumFormatEtc::Release
  65.  *
  66.  * Purpose:
  67.  *  IUnknown members for CEnumFormatEtc object.  For QueryInterface
  68.  *  we only return out own interfaces and not those of the data
  69.  *  object.  However, since enumerating formats only makes sense
  70.  *  when the data object is around, we insure that it stays as
  71.  *  long as we stay by calling an outer IUnknown for AddRef
  72.  *  and Release.  But since we are not controlled by the lifetime
  73.  *  of the outer object, we still keep our own reference count in
  74.  *  order to free ourselves.
  75.  */
  76.  
  77. STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID riid, PPVOID ppv)
  78.     {
  79.     *ppv=NULL;
  80.  
  81.     /*
  82.      * Enumerators are separate objects, not the data object, so
  83.      * we only need to support out IUnknown and IEnumFORMATETC
  84.      * interfaces here with no concern for aggregation.
  85.      */
  86.     if (IID_IUnknown==riid || IID_IEnumFORMATETC==riid)
  87.         *ppv=this;
  88.  
  89.     //AddRef any interface we'll return.
  90.     if (NULL!=*ppv)
  91.         {
  92.         ((LPUNKNOWN)*ppv)->AddRef();
  93.         return NOERROR;
  94.         }
  95.  
  96.     return ResultFromScode(E_NOINTERFACE);
  97.     }
  98.  
  99.  
  100. STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
  101.     {
  102.     ++m_cRef;
  103.     return m_cRef;
  104.     }
  105.  
  106. STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
  107.     {
  108.     if (0!=--m_cRef)
  109.         return m_cRef;
  110.  
  111.     delete this;
  112.     return 0;
  113.     }
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121. /*
  122.  * CEnumFormatEtc::Next
  123.  *
  124.  * Purpose:
  125.  *  Returns the next element in the enumeration.
  126.  *
  127.  * Parameters:
  128.  *  cFE             ULONG number of FORMATETCs to return.
  129.  *  pFE             LPFORMATETC in which to store the returned
  130.  *                  structures.
  131.  *  pulFE           ULONG * in which to return how many we
  132.  *                  enumerated.
  133.  *
  134.  * Return Value:
  135.  *  HRESULT         NOERROR if successful, S_FALSE otherwise,
  136.  */
  137.  
  138. STDMETHODIMP CEnumFormatEtc::Next(ULONG cFE, LPFORMATETC pFE
  139.     , ULONG *pulFE)
  140.     {
  141.     ULONG               cReturn=0L;
  142.  
  143.     if (NULL==m_prgfe)
  144.         return ResultFromScode(S_FALSE);
  145.  
  146.     if (NULL==pulFE)
  147.         {
  148.         if (1L!=cFE)
  149.             return ResultFromScode(E_POINTER);
  150.         }
  151.     else
  152.         *pulFE=0L;
  153.  
  154.     if (NULL==pFE || m_iCur >= m_cfe)
  155.         return ResultFromScode(S_FALSE);
  156.  
  157.     while (m_iCur < m_cfe && cFE > 0)
  158.         {
  159.         *pFE++=m_prgfe[m_iCur++];
  160.         cReturn++;
  161.         cFE--;
  162.         }
  163.  
  164.     if (NULL!=pulFE)
  165.         *pulFE=cReturn;
  166.  
  167.     return NOERROR;
  168.     }
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. /*
  177.  * CEnumFormatEtc::Skip
  178.  *
  179.  * Purpose:
  180.  *  Skips the next n elements in the enumeration.
  181.  *
  182.  * Parameters:
  183.  *  cSkip           ULONG number of elements to skip.
  184.  *
  185.  * Return Value:
  186.  *  HRESULT         NOERROR if successful, S_FALSE if we could not
  187.  *                  skip the requested number.
  188.  */
  189.  
  190. STDMETHODIMP CEnumFormatEtc::Skip(ULONG cSkip)
  191.     {
  192.     if (((m_iCur+cSkip) >= m_cfe) || NULL==m_prgfe)
  193.         return ResultFromScode(S_FALSE);
  194.  
  195.     m_iCur+=cSkip;
  196.     return NOERROR;
  197.     }
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204. /*
  205.  * CEnumFormatEtc::Reset
  206.  *
  207.  * Purpose:
  208.  *  Resets the current element index in the enumeration to zero.
  209.  *
  210.  * Parameters:
  211.  *  None
  212.  *
  213.  * Return Value:
  214.  *  HRESULT         NOERROR
  215.  */
  216.  
  217. STDMETHODIMP CEnumFormatEtc::Reset(void)
  218.     {
  219.     m_iCur=0;
  220.     return NOERROR;
  221.     }
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228. /*
  229.  * CEnumFormatEtc::Clone
  230.  *
  231.  * Purpose:
  232.  *  Returns another IEnumFORMATETC with the same state as ourselves.
  233.  *
  234.  * Parameters:
  235.  *  ppEnum          LPENUMFORMATETC * in which to return the
  236.  *                  new object.
  237.  *
  238.  * Return Value:
  239.  *  HRESULT         NOERROR or a general error value.
  240.  */
  241.  
  242. STDMETHODIMP CEnumFormatEtc::Clone(LPENUMFORMATETC *ppEnum)
  243.     {
  244.     PCEnumFormatEtc     pNew;
  245.  
  246.     *ppEnum=NULL;
  247.  
  248.     //Create the clone
  249.     pNew=new CEnumFormatEtc(m_cfe, m_prgfe);
  250.  
  251.     if (NULL==pNew)
  252.         return ResultFromScode(E_OUTOFMEMORY);
  253.  
  254.     pNew->AddRef();
  255.     pNew->m_iCur=m_iCur;
  256.  
  257.     *ppEnum=pNew;
  258.     return NOERROR;
  259.     }
  260.