Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
4.8 KiB

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