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.

185 lines
3.2 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: fmtetc.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #pragma hdrstop
  12. #include "fmtetc.h"
  13. CEnumFormatEtc::CEnumFormatEtc(
  14. UINT cFormats,
  15. LPFORMATETC prgFormats
  16. ) : m_cRef(0),
  17. m_cFormats(0),
  18. m_iCurrent(0),
  19. m_prgFormats(NULL),
  20. m_hrCtor(NOERROR)
  21. {
  22. m_hrCtor = AddFormats(cFormats, prgFormats);
  23. }
  24. CEnumFormatEtc::CEnumFormatEtc(
  25. const CEnumFormatEtc& ef
  26. ) : m_cRef(0),
  27. m_cFormats(0),
  28. m_iCurrent(0),
  29. m_prgFormats(NULL),
  30. m_hrCtor(NOERROR)
  31. {
  32. m_hrCtor = AddFormats(ef.m_cFormats, ef.m_prgFormats);
  33. }
  34. CEnumFormatEtc::~CEnumFormatEtc(
  35. VOID
  36. )
  37. {
  38. delete[] m_prgFormats;
  39. }
  40. STDMETHODIMP
  41. CEnumFormatEtc::QueryInterface(
  42. REFIID riid,
  43. LPVOID *ppv
  44. )
  45. {
  46. static const QITAB qit[] = {
  47. QITABENT(CEnumFormatEtc, IEnumFORMATETC),
  48. { 0 },
  49. };
  50. return QISearch(this, qit, riid, ppv);
  51. }
  52. STDMETHODIMP_(ULONG)
  53. CEnumFormatEtc::AddRef(
  54. VOID
  55. )
  56. {
  57. InterlockedIncrement(&m_cRef);
  58. return m_cRef;
  59. }
  60. STDMETHODIMP_(ULONG)
  61. CEnumFormatEtc::Release(
  62. VOID
  63. )
  64. {
  65. if (0 != InterlockedDecrement(&m_cRef))
  66. return m_cRef;
  67. delete this;
  68. return 0;
  69. }
  70. STDMETHODIMP
  71. CEnumFormatEtc::Next(
  72. DWORD cFormats,
  73. LPFORMATETC pFormats,
  74. LPDWORD pcReturned
  75. )
  76. {
  77. HRESULT hr = S_OK;
  78. DWORD iFormats = 0;
  79. if (NULL == pFormats)
  80. return E_INVALIDARG;
  81. while(cFormats-- > 0)
  82. {
  83. if (m_iCurrent < m_cFormats)
  84. {
  85. *(pFormats + iFormats++) = m_prgFormats[m_iCurrent++];
  86. }
  87. else
  88. {
  89. hr = S_FALSE;
  90. break;
  91. }
  92. }
  93. if (NULL != pcReturned)
  94. *pcReturned = iFormats;
  95. return hr;
  96. }
  97. STDMETHODIMP
  98. CEnumFormatEtc::Skip(
  99. DWORD cFormats
  100. )
  101. {
  102. while((cFormats-- > 0) && (m_iCurrent < m_cFormats))
  103. m_iCurrent++;
  104. return cFormats == 0 ? S_OK : S_FALSE;
  105. }
  106. STDMETHODIMP
  107. CEnumFormatEtc::Reset(
  108. VOID
  109. )
  110. {
  111. m_iCurrent = 0;
  112. return S_OK;
  113. }
  114. STDMETHODIMP
  115. CEnumFormatEtc::Clone(
  116. IEnumFORMATETC **ppvOut
  117. )
  118. {
  119. HRESULT hr = E_OUTOFMEMORY;
  120. CEnumFormatEtc *pNew = new CEnumFormatEtc(*this);
  121. if (NULL != pNew)
  122. {
  123. hr = pNew->QueryInterface(IID_IEnumFORMATETC, (LPVOID *)ppvOut);
  124. }
  125. return hr;
  126. }
  127. HRESULT
  128. CEnumFormatEtc::AddFormats(
  129. UINT cFormats,
  130. LPFORMATETC pFormats
  131. )
  132. {
  133. HRESULT hr = E_OUTOFMEMORY;
  134. LPFORMATETC pNew = new FORMATETC[m_cFormats + cFormats];
  135. if (NULL != pNew)
  136. {
  137. FORMATETC *pSrc = m_prgFormats;
  138. FORMATETC *pDest = pNew;
  139. int i;
  140. for (i = 0; i < m_cFormats; i++)
  141. {
  142. *pDest++ = *pSrc++; // Copy original formats.
  143. }
  144. pSrc = pFormats;
  145. for (i = 0; i < int(cFormats); i++)
  146. {
  147. *pDest++ = *pSrc++; // Add new formats.
  148. }
  149. delete[] m_prgFormats;
  150. m_cFormats += cFormats;
  151. m_prgFormats = pNew;
  152. hr = NOERROR;
  153. }
  154. return hr;
  155. }