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

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