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.

233 lines
3.9 KiB

  1. #ifndef _NMENUM_H_
  2. #define _NMENUM_H_
  3. #include "oblist.h"
  4. // IEnumNmX
  5. //
  6. template <class IEnumNmX, const IID* piidEnumNmX, class INmX, class CNmX>
  7. class CEnumNmX : public IEnumNmX
  8. {
  9. private:
  10. INmX **m_pList; // The list
  11. int m_iCurr; // Current index number
  12. int m_iMax; // Maximum index
  13. ULONG m_cRef;
  14. public:
  15. CEnumNmX(COBLIST * pList, int cItems) :
  16. m_iCurr(0),
  17. m_iMax(0),
  18. m_pList(NULL),
  19. m_cRef(1)
  20. {
  21. if ((NULL != pList) && (0 != cItems))
  22. {
  23. m_pList = new INmX* [cItems];
  24. if (NULL != m_pList)
  25. {
  26. POSITION pos = pList->GetHeadPosition();
  27. while ((NULL != pos) && (m_iMax < cItems))
  28. {
  29. INmX *pINmX = (INmX *) (CNmX *) pList->GetNext(pos);
  30. ASSERT(NULL != pINmX);
  31. pINmX->AddRef();
  32. m_pList[m_iMax] = pINmX;
  33. m_iMax++;
  34. }
  35. }
  36. }
  37. // ApiDebugMsg(("CEnumNmX - Constructed(%08X)", this));
  38. }
  39. CEnumNmX(COBLIST * pList)
  40. {
  41. int cItems = 0;
  42. if (NULL != pList)
  43. {
  44. POSITION pos = pList->GetHeadPosition();
  45. while (NULL != pos)
  46. {
  47. pList->GetNext(pos);
  48. cItems++;
  49. }
  50. }
  51. CEnumNmX(pList, cItems);
  52. }
  53. CEnumNmX(CNmX **rgpNmX, ULONG cItems) :
  54. m_iCurr(0),
  55. m_iMax(0),
  56. m_pList(NULL),
  57. m_cRef(1)
  58. {
  59. if (NULL != rgpNmX)
  60. {
  61. m_pList = new INmX* [cItems];
  62. if (NULL != m_pList)
  63. {
  64. m_iMax = cItems;
  65. for (int i = 0; i < m_iMax; ++i)
  66. {
  67. ASSERT(NULL != rgpNmX[i]);
  68. rgpNmX[i]->AddRef();
  69. m_pList[i] = rgpNmX[i];
  70. }
  71. }
  72. }
  73. // ApiDebugMsg(("CEnumNmX - Constructed(%08X)", this));
  74. }
  75. ~CEnumNmX(void)
  76. {
  77. for (int i = 0; i < m_iMax; ++i)
  78. {
  79. ASSERT(NULL != m_pList[i]);
  80. m_pList[i]->Release();
  81. }
  82. delete m_pList;
  83. // ApiDebugMsg(("CEnumNmX - Destructed (%08X)", this));
  84. }
  85. STDMETHODIMP_(ULONG) AddRef(void)
  86. {
  87. return ++m_cRef;
  88. }
  89. STDMETHODIMP_(ULONG) Release(void)
  90. {
  91. ASSERT(m_cRef > 0);
  92. if (m_cRef > 0)
  93. {
  94. m_cRef--;
  95. }
  96. ULONG cRef = m_cRef;
  97. if (0 == cRef)
  98. {
  99. delete this;
  100. }
  101. return cRef;
  102. }
  103. STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv)
  104. {
  105. HRESULT hr = S_OK;
  106. if ((riid == *piidEnumNmX) || (riid == IID_IUnknown))
  107. {
  108. *ppv = (IEnumNmX *)this;
  109. // ApiDebugMsg(("CEnumNmX::QueryInterface(): Returning IEnumNmX."));
  110. }
  111. else
  112. {
  113. hr = E_NOINTERFACE;
  114. *ppv = NULL;
  115. // ApiDebugMsg(("CEnumNmX::QueryInterface(): Called on unknown interface."));
  116. }
  117. if (S_OK == hr)
  118. {
  119. AddRef();
  120. }
  121. return hr;
  122. }
  123. STDMETHODIMP Next(ULONG cItem, INmX **rgpNmX, ULONG *pcFetched)
  124. {
  125. ULONG cCopied = 0;
  126. if ((0 == cItem) && (NULL == rgpNmX) && (NULL != pcFetched))
  127. {
  128. // Return the number of remaining elements
  129. *pcFetched = m_iMax - m_iCurr;
  130. return S_OK;
  131. }
  132. if ((NULL == rgpNmX) || ((NULL == pcFetched) && (cItem != 1)))
  133. return E_POINTER;
  134. if (NULL != m_pList)
  135. {
  136. while ((cCopied < cItem) && (m_iCurr < m_iMax))
  137. {
  138. *rgpNmX = m_pList[m_iCurr];
  139. ASSERT(NULL != *rgpNmX);
  140. (*rgpNmX)->AddRef();
  141. rgpNmX++;
  142. cCopied++;
  143. m_iCurr++;
  144. }
  145. }
  146. if (pcFetched != NULL)
  147. *pcFetched = cCopied;
  148. return ((cItem == cCopied) ? S_OK : S_FALSE);
  149. }
  150. STDMETHODIMP Skip(ULONG cItem)
  151. {
  152. m_iCurr += cItem;
  153. if (m_iCurr >= m_iMax)
  154. {
  155. // Past the end of the list
  156. m_iCurr = m_iMax;
  157. return S_FALSE;
  158. }
  159. return S_OK;
  160. }
  161. STDMETHODIMP Reset()
  162. {
  163. m_iCurr = 0;
  164. return S_OK;
  165. }
  166. STDMETHODIMP Clone(IEnumNmX **ppEnum)
  167. {
  168. if (NULL == ppEnum)
  169. return E_POINTER;
  170. HRESULT hr = S_OK;
  171. CEnumNmX * pEnum = new CEnumNmX(NULL, 0);
  172. if (NULL == pEnum)
  173. {
  174. hr = E_OUTOFMEMORY;
  175. }
  176. else if (NULL != m_pList)
  177. {
  178. pEnum->m_pList = new INmX*[m_iMax];
  179. if (NULL == pEnum->m_pList)
  180. {
  181. delete pEnum;
  182. pEnum = NULL;
  183. hr = E_OUTOFMEMORY;
  184. }
  185. else
  186. {
  187. pEnum->m_iCurr = m_iCurr;
  188. pEnum->m_iMax = m_iMax;
  189. for (int i = 0; i < m_iMax; ++i)
  190. {
  191. ASSERT(NULL != m_pList[i]);
  192. m_pList[i]->AddRef();
  193. pEnum->m_pList[i] = m_pList[i];
  194. }
  195. }
  196. }
  197. *ppEnum = pEnum;
  198. return hr;
  199. }
  200. };
  201. #endif // _NMENUM_H_