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.

308 lines
8.1 KiB

  1. /*************************************************************************
  2. **
  3. ** OLE 2 Utility Code
  4. **
  5. ** enumfetc.c
  6. **
  7. ** This file contains a standard implementation of IEnumFormatEtc
  8. ** interface.
  9. ** This file is part of the OLE 2.0 User Interface support library.
  10. **
  11. ** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
  12. **
  13. *************************************************************************/
  14. #define STRICT 1
  15. #include "ole2ui.h"
  16. #include "enumfetc.h"
  17. typedef struct tagOleStdEnumFmtEtc {
  18. IEnumFORMATETCVtbl FAR* lpVtbl;
  19. ULONG m_dwRefs; /* referance count */
  20. ULONG m_nIndex; /* current index in list */
  21. ULONG m_nCount; /* how many items in list */
  22. LPFORMATETC m_lpEtc; /* list of formatetc */
  23. } OLESTDENUMFMTETC, FAR* LPOLESTDENUMFMTETC;
  24. VOID OleStdEnumFmtEtc_Destroy(LPOLESTDENUMFMTETC pEtc);
  25. STDMETHODIMP OleStdEnumFmtEtc_QueryInterface(
  26. LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* ppobj);
  27. STDMETHODIMP_(ULONG) OleStdEnumFmtEtc_AddRef(LPENUMFORMATETC lpThis);
  28. STDMETHODIMP_(ULONG) OleStdEnumFmtEtc_Release(LPENUMFORMATETC lpThis);
  29. STDMETHODIMP OleStdEnumFmtEtc_Next(LPENUMFORMATETC lpThis, ULONG celt,
  30. LPFORMATETC rgelt, ULONG FAR* pceltFetched);
  31. STDMETHODIMP OleStdEnumFmtEtc_Skip(LPENUMFORMATETC lpThis, ULONG celt);
  32. STDMETHODIMP OleStdEnumFmtEtc_Reset(LPENUMFORMATETC lpThis);
  33. STDMETHODIMP OleStdEnumFmtEtc_Clone(LPENUMFORMATETC lpThis,
  34. LPENUMFORMATETC FAR* ppenum);
  35. static IEnumFORMATETCVtbl g_EnumFORMATETCVtbl = {
  36. OleStdEnumFmtEtc_QueryInterface,
  37. OleStdEnumFmtEtc_AddRef,
  38. OleStdEnumFmtEtc_Release,
  39. OleStdEnumFmtEtc_Next,
  40. OleStdEnumFmtEtc_Skip,
  41. OleStdEnumFmtEtc_Reset,
  42. OleStdEnumFmtEtc_Clone,
  43. };
  44. /////////////////////////////////////////////////////////////////////////////
  45. STDAPI_(LPENUMFORMATETC)
  46. OleStdEnumFmtEtc_Create(ULONG nCount, LPFORMATETC lpEtc)
  47. //----------------------------------------------------------------------------
  48. //
  49. //----------------------------------------------------------------------------
  50. {
  51. LPMALLOC lpMalloc=NULL;
  52. LPOLESTDENUMFMTETC lpEF=NULL;
  53. DWORD dwSize;
  54. WORD i;
  55. HRESULT hRes;
  56. hRes = CoGetMalloc(MEMCTX_TASK, &lpMalloc);
  57. if (hRes != NOERROR) {
  58. return NULL;
  59. }
  60. lpEF = (LPOLESTDENUMFMTETC)lpMalloc->lpVtbl->Alloc(lpMalloc,
  61. sizeof(OLESTDENUMFMTETC));
  62. if (lpEF == NULL) {
  63. goto errReturn;
  64. }
  65. lpEF->lpVtbl = &g_EnumFORMATETCVtbl;
  66. lpEF->m_dwRefs = 1;
  67. lpEF->m_nCount = nCount;
  68. lpEF->m_nIndex = 0;
  69. dwSize = sizeof(FORMATETC) * lpEF->m_nCount;
  70. lpEF->m_lpEtc = (LPFORMATETC)lpMalloc->lpVtbl->Alloc(lpMalloc, dwSize);
  71. if (lpEF->m_lpEtc == NULL)
  72. goto errReturn;
  73. lpMalloc->lpVtbl->Release(lpMalloc);
  74. for (i=0; i<nCount; i++) {
  75. OleStdCopyFormatEtc(
  76. (LPFORMATETC)&(lpEF->m_lpEtc[i]), (LPFORMATETC)&(lpEtc[i]));
  77. }
  78. return (LPENUMFORMATETC)lpEF;
  79. errReturn:
  80. if (lpEF != NULL)
  81. lpMalloc->lpVtbl->Free(lpMalloc, lpEF);
  82. if (lpMalloc != NULL)
  83. lpMalloc->lpVtbl->Release(lpMalloc);
  84. return NULL;
  85. } /* OleStdEnumFmtEtc_Create()
  86. */
  87. VOID
  88. OleStdEnumFmtEtc_Destroy(LPOLESTDENUMFMTETC lpEF)
  89. //----------------------------------------------------------------------------
  90. //
  91. //----------------------------------------------------------------------------
  92. {
  93. LPMALLOC lpMalloc=NULL;
  94. WORD i;
  95. if (lpEF != NULL) {
  96. if (CoGetMalloc(MEMCTX_TASK, &lpMalloc) == NOERROR) {
  97. /* OLE2NOTE: we MUST free any memory that was allocated for
  98. ** TARGETDEVICES contained within the FORMATETC elements.
  99. */
  100. for (i=0; i<lpEF->m_nCount; i++) {
  101. OleStdFree(lpEF->m_lpEtc[i].ptd);
  102. }
  103. if (lpEF->m_lpEtc != NULL) {
  104. lpMalloc->lpVtbl->Free(lpMalloc, lpEF->m_lpEtc);
  105. }
  106. lpMalloc->lpVtbl->Free(lpMalloc, lpEF);
  107. lpMalloc->lpVtbl->Release(lpMalloc);
  108. }
  109. }
  110. } /* OleStdEnumFmtEtc_Destroy()
  111. */
  112. STDMETHODIMP
  113. OleStdEnumFmtEtc_QueryInterface(
  114. LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* ppobj)
  115. //----------------------------------------------------------------------------
  116. //
  117. //----------------------------------------------------------------------------
  118. {
  119. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  120. *ppobj = NULL;
  121. if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IEnumFORMATETC)){
  122. *ppobj = (LPVOID)lpEF;
  123. }
  124. if (*ppobj == NULL) return ResultFromScode(E_NOINTERFACE);
  125. else{
  126. OleStdEnumFmtEtc_AddRef(lpThis);
  127. return NOERROR;
  128. }
  129. } /* OleStdEnumFmtEtc_QueryInterface()
  130. */
  131. STDMETHODIMP_(ULONG)
  132. OleStdEnumFmtEtc_AddRef(LPENUMFORMATETC lpThis)
  133. //----------------------------------------------------------------------------
  134. //
  135. //----------------------------------------------------------------------------
  136. {
  137. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  138. return lpEF->m_dwRefs++;
  139. } /* OleStdEnumFmtEtc_AddRef()
  140. */
  141. STDMETHODIMP_(ULONG)
  142. OleStdEnumFmtEtc_Release(LPENUMFORMATETC lpThis)
  143. //----------------------------------------------------------------------------
  144. //
  145. //----------------------------------------------------------------------------
  146. {
  147. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  148. DWORD dwRefs = --lpEF->m_dwRefs;
  149. if (dwRefs == 0)
  150. OleStdEnumFmtEtc_Destroy(lpEF);
  151. return dwRefs;
  152. } /* OleStdEnumFmtEtc_Release()
  153. */
  154. STDMETHODIMP
  155. OleStdEnumFmtEtc_Next(LPENUMFORMATETC lpThis, ULONG celt, LPFORMATETC rgelt,
  156. ULONG FAR* pceltFetched)
  157. //----------------------------------------------------------------------------
  158. //
  159. //----------------------------------------------------------------------------
  160. {
  161. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  162. ULONG i=0;
  163. ULONG nOffset;
  164. if (rgelt == NULL) {
  165. return ResultFromScode(E_INVALIDARG);
  166. }
  167. while (i < celt) {
  168. nOffset = lpEF->m_nIndex + i;
  169. if (nOffset < lpEF->m_nCount) {
  170. OleStdCopyFormatEtc(
  171. (LPFORMATETC)&(rgelt[i]), (LPFORMATETC)&(lpEF->m_lpEtc[nOffset]));
  172. i++;
  173. }else{
  174. break;
  175. }
  176. }
  177. lpEF->m_nIndex += (WORD)i;
  178. if (pceltFetched != NULL) {
  179. *pceltFetched = i;
  180. }
  181. if (i != celt) {
  182. return ResultFromScode(S_FALSE);
  183. }
  184. return NOERROR;
  185. } /* OleStdEnumFmtEtc_Next()
  186. */
  187. STDMETHODIMP
  188. OleStdEnumFmtEtc_Skip(LPENUMFORMATETC lpThis, ULONG celt)
  189. //----------------------------------------------------------------------------
  190. //
  191. //----------------------------------------------------------------------------
  192. {
  193. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  194. ULONG i=0;
  195. ULONG nOffset;
  196. while (i < celt) {
  197. nOffset = lpEF->m_nIndex + i;
  198. if (nOffset < lpEF->m_nCount) {
  199. i++;
  200. }else{
  201. break;
  202. }
  203. }
  204. lpEF->m_nIndex += (WORD)i;
  205. if (i != celt) {
  206. return ResultFromScode(S_FALSE);
  207. }
  208. return NOERROR;
  209. } /* OleStdEnumFmtEtc_Skip()
  210. */
  211. STDMETHODIMP
  212. OleStdEnumFmtEtc_Reset(LPENUMFORMATETC lpThis)
  213. //----------------------------------------------------------------------------
  214. //
  215. //----------------------------------------------------------------------------
  216. {
  217. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  218. lpEF->m_nIndex = 0;
  219. return NOERROR;
  220. } /* OleStdEnumFmtEtc_Reset()
  221. */
  222. STDMETHODIMP
  223. OleStdEnumFmtEtc_Clone(LPENUMFORMATETC lpThis, LPENUMFORMATETC FAR* ppenum)
  224. //----------------------------------------------------------------------------
  225. //
  226. //----------------------------------------------------------------------------
  227. {
  228. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  229. if (ppenum == NULL) {
  230. return ResultFromScode(E_INVALIDARG);
  231. }
  232. *ppenum = OleStdEnumFmtEtc_Create(lpEF->m_nCount, lpEF->m_lpEtc);
  233. // make sure cloned enumerator has same index state as the original
  234. if (*ppenum) {
  235. LPOLESTDENUMFMTETC lpEFClone = (LPOLESTDENUMFMTETC)*ppenum;
  236. lpEFClone->m_nIndex = lpEF->m_nIndex;
  237. return NOERROR;
  238. } else
  239. return ResultFromScode(E_OUTOFMEMORY);
  240. } /* OleStdEnumFmtEtc_Clone()
  241. */