Leaked source code of windows server 2003
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.

186 lines
3.4 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. return InterlockedIncrement(&m_cRef);
  58. }
  59. STDMETHODIMP_(ULONG)
  60. CEnumFormatEtc::Release(
  61. VOID
  62. )
  63. {
  64. ASSERT( 0 != m_cRef );
  65. ULONG cRef = InterlockedDecrement(&m_cRef);
  66. if (0 == cRef )
  67. {
  68. delete this;
  69. }
  70. return cRef;
  71. }
  72. STDMETHODIMP
  73. CEnumFormatEtc::Next(
  74. DWORD cFormats,
  75. LPFORMATETC pFormats,
  76. LPDWORD pcReturned
  77. )
  78. {
  79. HRESULT hr = S_OK;
  80. DWORD iFormats = 0;
  81. if (NULL == pFormats)
  82. return E_INVALIDARG;
  83. while(cFormats-- > 0)
  84. {
  85. if (m_iCurrent < m_cFormats)
  86. {
  87. *(pFormats + iFormats++) = m_prgFormats[m_iCurrent++];
  88. }
  89. else
  90. {
  91. hr = S_FALSE;
  92. break;
  93. }
  94. }
  95. if (NULL != pcReturned)
  96. *pcReturned = iFormats;
  97. return hr;
  98. }
  99. STDMETHODIMP
  100. CEnumFormatEtc::Skip(
  101. DWORD cFormats
  102. )
  103. {
  104. while((cFormats-- > 0) && (m_iCurrent < m_cFormats))
  105. m_iCurrent++;
  106. return cFormats == 0 ? S_OK : S_FALSE;
  107. }
  108. STDMETHODIMP
  109. CEnumFormatEtc::Reset(
  110. VOID
  111. )
  112. {
  113. m_iCurrent = 0;
  114. return S_OK;
  115. }
  116. STDMETHODIMP
  117. CEnumFormatEtc::Clone(
  118. IEnumFORMATETC **ppvOut
  119. )
  120. {
  121. HRESULT hr = E_OUTOFMEMORY;
  122. CEnumFormatEtc *pNew = new CEnumFormatEtc(*this);
  123. if (NULL != pNew)
  124. {
  125. hr = pNew->QueryInterface(IID_IEnumFORMATETC, (LPVOID *)ppvOut);
  126. }
  127. return hr;
  128. }
  129. HRESULT
  130. CEnumFormatEtc::AddFormats(
  131. UINT cFormats,
  132. LPFORMATETC pFormats
  133. )
  134. {
  135. HRESULT hr = E_OUTOFMEMORY;
  136. LPFORMATETC pNew = new FORMATETC[m_cFormats + cFormats];
  137. if (NULL != pNew)
  138. {
  139. FORMATETC *pSrc = m_prgFormats;
  140. FORMATETC *pDest = pNew;
  141. int i;
  142. for (i = 0; i < m_cFormats; i++)
  143. {
  144. *pDest++ = *pSrc++; // Copy original formats.
  145. }
  146. pSrc = pFormats;
  147. for (i = 0; i < int(cFormats); i++)
  148. {
  149. *pDest++ = *pSrc++; // Add new formats.
  150. }
  151. delete[] m_prgFormats;
  152. m_cFormats += cFormats;
  153. m_prgFormats = pNew;
  154. hr = NOERROR;
  155. }
  156. return hr;
  157. }