IENUMFE.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:

Windows编程

开发平台:

Visual C++

  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. #include "ienumfe.h"
  15. /*
  16.  * CEnumFormatEtc::CEnumFormatEtc
  17.  * CEnumFormatEtc::~CEnumFormatEtc
  18.  *
  19.  * Parameters (Constructor):
  20.  *  cFE             ULONG number of FORMATETCs in pFE
  21.  *  prgFE           LPFORMATETC to the array to enumerate.
  22.  */
  23. CEnumFormatEtc::CEnumFormatEtc(ULONG cFE, LPFORMATETC prgFE)
  24.     {
  25.     UINT        i;
  26.     m_cRef=0;
  27.     m_iCur=0;
  28.     m_cfe=cFE;
  29.     m_prgfe=new FORMATETC[(UINT)cFE];
  30.     if (NULL!=m_prgfe)
  31.         {
  32.         for (i=0; i < cFE; i++)
  33.             m_prgfe[i]=prgFE[i];
  34.         }
  35.     return;
  36.     }
  37. CEnumFormatEtc::~CEnumFormatEtc(void)
  38.     {
  39.     if (NULL!=m_prgfe)
  40.         delete [] m_prgfe;
  41.     return;
  42.     }
  43. /*
  44.  * CEnumFormatEtc::QueryInterface
  45.  * CEnumFormatEtc::AddRef
  46.  * CEnumFormatEtc::Release
  47.  *
  48.  * Purpose:
  49.  *  IUnknown members for CEnumFormatEtc object.  For QueryInterface
  50.  *  we only return out own interfaces and not those of the data
  51.  *  object.  However, since enumerating formats only makes sense
  52.  *  when the data object is around, we insure that it stays as
  53.  *  long as we stay by calling an outer IUnknown for AddRef
  54.  *  and Release.  But since we are not controlled by the lifetime
  55.  *  of the outer object, we still keep our own reference count in
  56.  *  order to free ourselves.
  57.  */
  58. STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID riid
  59.     , LPVOID *ppv)
  60.     {
  61.     *ppv=NULL;
  62.     /*
  63.      * Enumerators are separate objects, not the data object, so
  64.      * we only need to support out IUnknown and IEnumFORMATETC
  65.      * interfaces here with no concern for aggregation.
  66.      */
  67.     if (IID_IUnknown==riid || IID_IEnumFORMATETC==riid)
  68.         *ppv=(LPVOID)this;
  69.     if (NULL!=*ppv)
  70.         {
  71.         ((LPUNKNOWN)*ppv)->AddRef();
  72.         return NOERROR;
  73.         }
  74.     return ResultFromScode(E_NOINTERFACE);
  75.     }
  76. STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
  77.     {
  78.     ++m_cRef;
  79.     return m_cRef;
  80.     }
  81. STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
  82.     {
  83.     if (0L!=--m_cRef)
  84.         return m_cRef;
  85.     delete this;
  86.     return 0;
  87.     }
  88. /*
  89.  * CEnumFormatEtc::Next
  90.  *
  91.  * Purpose:
  92.  *  Returns the next element in the enumeration.
  93.  *
  94.  * Parameters:
  95.  *  cFE             ULONG number of FORMATETCs to return.
  96.  *  pFE             LPFORMATETC in which to store the returned
  97.  *                  structures.
  98.  *  pulFE           ULONG * in which to return how many we
  99.  *                  enumerated.
  100.  *
  101.  * Return Value:
  102.  *  HRESULT         NOERROR if successful, S_FALSE otherwise,
  103.  */
  104. STDMETHODIMP CEnumFormatEtc::Next(ULONG cFE, LPFORMATETC pFE
  105.     , ULONG *pulFE)
  106.     {
  107.     ULONG               cReturn=0L;
  108.     if (NULL==m_prgfe)
  109.         return ResultFromScode(S_FALSE);
  110.     if (NULL==pulFE)
  111.         {
  112.         if (1L!=cFE)
  113.             return ResultFromScode(E_POINTER);
  114.         }
  115.     else
  116.         *pulFE=0L;
  117.     if (NULL==pFE || m_iCur >= m_cfe)
  118.         return ResultFromScode(S_FALSE);
  119.     while (m_iCur < m_cfe && cFE > 0)
  120.         {
  121.         *pFE++=m_prgfe[m_iCur++];
  122.         cReturn++;
  123.         cFE--;
  124.         }
  125.     if (NULL!=pulFE)
  126.         *pulFE=cReturn;
  127.     return NOERROR;
  128.     }
  129. /*
  130.  * CEnumFormatEtc::Skip
  131.  *
  132.  * Purpose:
  133.  *  Skips the next n elements in the enumeration.
  134.  *
  135.  * Parameters:
  136.  *  cSkip           ULONG number of elements to skip.
  137.  *
  138.  * Return Value:
  139.  *  HRESULT         NOERROR if successful, S_FALSE if we could not
  140.  *                  skip the requested number.
  141.  */
  142. STDMETHODIMP CEnumFormatEtc::Skip(ULONG cSkip)
  143.     {
  144.     if (((m_iCur+cSkip) >= m_cfe) || NULL==m_prgfe)
  145.         return ResultFromScode(S_FALSE);
  146.     m_iCur+=cSkip;
  147.     return NOERROR;
  148.     }
  149. /*
  150.  * CEnumFormatEtc::Reset
  151.  *
  152.  * Purpose:
  153.  *  Resets the current element index in the enumeration to zero.
  154.  *
  155.  * Parameters:
  156.  *  None
  157.  */
  158. STDMETHODIMP CEnumFormatEtc::Reset(void)
  159.     {
  160.     m_iCur=0;
  161.     return NOERROR;
  162.     }
  163. /*
  164.  * CEnumFormatEtc::Clone
  165.  *
  166.  * Purpose:
  167.  *  Returns another IEnumFORMATETC with the same state as ourselves.
  168.  *
  169.  * Parameters:
  170.  *  ppEnum          LPENUMFORMATETC * in which to return the
  171.  *                  new object.
  172.  */
  173. STDMETHODIMP CEnumFormatEtc::Clone(LPENUMFORMATETC *ppEnum)
  174.     {
  175.     PCEnumFormatEtc pNew;
  176.     *ppEnum=NULL;
  177.     //Create the clone
  178.     pNew=new CEnumFormatEtc(m_cfe, m_prgfe);
  179.     if (NULL==pNew)
  180.         return ResultFromScode(E_OUTOFMEMORY);
  181.     pNew->AddRef();
  182.     pNew->m_iCur=m_iCur;
  183.     *ppEnum=pNew;
  184.     return NOERROR;
  185.     }