ENUMVAR.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // enumvar.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include "stdafx.h"
  13. #include "inproc.h"
  14. #include "enumvar.h"
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char BASED_CODE THIS_FILE[] = __FILE__;
  18. #endif
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CEnumVariant
  21. IMPLEMENT_DYNCREATE(CEnumVariant, CCmdTarget)
  22. CEnumVariant::CEnumVariant()
  23. {
  24. m_nIndex = 0;
  25. m_nCount = 0;
  26. m_pContents = NULL;
  27. m_pClonedFrom = NULL;
  28. // To keep the application running as long as an OLE automation
  29. //  object is active, the constructor calls AfxOleLockApp.
  30. AfxOleLockApp();
  31. }
  32. CEnumVariant::~CEnumVariant()
  33. {
  34. if (m_pClonedFrom != NULL)
  35. {
  36. m_pClonedFrom->ExternalRelease();
  37. }
  38. else
  39. {
  40. for (int i = 0; i < m_nCount; ++i)
  41. VariantClear(&m_pContents[i]);
  42. delete[] m_pContents;
  43. }
  44. // To terminate the application when all objects created with
  45. //  with OLE automation, the destructor calls AfxOleUnlockApp.
  46. AfxOleUnlockApp();
  47. }
  48. void CEnumVariant::OnFinalRelease()
  49. {
  50. // When the last reference for an automation object is released
  51. //  OnFinalRelease is called.  This implementation deletes the
  52. //  object.  Add additional cleanup required for your object before
  53. //  deleting it from memory.
  54. delete this;
  55. }
  56. void CEnumVariant::SetContents(VARIANT* pContents, int nCount, int nIndex)
  57. {
  58. ASSERT(nIndex < nCount);
  59. ASSERT(nCount == 0 || pContents != NULL);
  60. ASSERT(pContents == NULL ||
  61. AfxIsValidAddress(pContents, sizeof(VARIANT)*nCount, FALSE));
  62. m_nCount = nCount;
  63. m_pContents = pContents;
  64. m_nIndex = nIndex;
  65. }
  66. BEGIN_MESSAGE_MAP(CEnumVariant, CCmdTarget)
  67. //{{AFX_MSG_MAP(CEnumVariant)
  68. // NOTE - the ClassWizard will add and remove mapping macros here.
  69. //}}AFX_MSG_MAP
  70. END_MESSAGE_MAP()
  71. /////////////////////////////////////////////////////////////////////////////
  72. // CEnumVariant interfaces
  73. static void CopyVariantArray(VARIANT* pDest, VARIANT* pSrc, int nCount)
  74. {
  75. for (int i = 0; i < nCount; ++i)
  76. VariantInit(&pDest[i]);
  77. for (i = 0; i < nCount; ++i)
  78. {
  79. SCODE sc = GetScode(VariantCopy(&pDest[i], &pSrc[i]));
  80. if (sc != NOERROR)
  81. {
  82. while (--i >= 0)
  83. VariantClear(&pDest[i]);
  84. AfxThrowMemoryException();
  85. }
  86. }
  87. }
  88. BEGIN_INTERFACE_MAP(CEnumVariant, CCmdTarget)
  89. INTERFACE_PART(CEnumVariant, IID_IEnumVARIANT, EnumVARIANT)
  90. END_INTERFACE_MAP()
  91. STDMETHODIMP_(ULONG) CEnumVariant::XEnumVARIANT::AddRef()
  92. {
  93. METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
  94. return pThis->ExternalAddRef();
  95. }
  96. STDMETHODIMP_(ULONG) CEnumVariant::XEnumVARIANT::Release()
  97. {
  98. METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
  99. return pThis->ExternalRelease();
  100. }
  101. STDMETHODIMP CEnumVariant::XEnumVARIANT::QueryInterface(REFIID iid, void** ppvObj)
  102. {
  103. METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
  104. return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj) ;
  105. }
  106. STDMETHODIMP CEnumVariant::XEnumVARIANT::Next(ULONG celt, VARIANT* rgvar, ULONG* pceltFetched)
  107. {
  108. METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
  109. ASSERT(celt > 0);
  110. ASSERT(celt == 1 || pceltFetched != NULL);
  111. if (pceltFetched != NULL)
  112. *pceltFetched = 0;
  113. int nFetched = min(pThis->m_nCount - pThis->m_nIndex, (int)celt);
  114. TRY
  115. {
  116. CopyVariantArray(rgvar, pThis->m_pContents + pThis->m_nIndex, nFetched);
  117. }
  118. CATCH_ALL(e)
  119. {
  120. return E_OUTOFMEMORY;
  121. }
  122. END_CATCH_ALL
  123. pThis->m_nIndex += nFetched;
  124. if (pceltFetched != NULL)
  125. *pceltFetched = nFetched;
  126. return nFetched == (int)celt ? NOERROR : S_FALSE;
  127. }
  128. STDMETHODIMP CEnumVariant::XEnumVARIANT::Skip(unsigned long celt)
  129. {
  130. METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
  131. int nSkip = (int)celt;
  132. if (nSkip + pThis->m_nIndex > pThis->m_nCount)
  133. nSkip = pThis->m_nCount - pThis->m_nIndex;
  134. pThis->m_nIndex += nSkip;
  135. return nSkip == (int)celt ? NOERROR : S_FALSE;
  136. }
  137. STDMETHODIMP CEnumVariant::XEnumVARIANT::Reset()
  138. {
  139. METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
  140. pThis->m_nIndex = 0;
  141. return NOERROR;
  142. }
  143. STDMETHODIMP CEnumVariant::XEnumVARIANT::Clone(IEnumVARIANT** ppenum)
  144. {
  145. METHOD_PROLOGUE(CEnumVariant, EnumVARIANT)
  146. CEnumVariant* pClone;
  147. TRY
  148. {
  149. pClone = new CEnumVariant;
  150. pClone->SetContents(pThis->m_pContents, pThis->m_nCount, pThis->m_nIndex);
  151. pClone->m_pClonedFrom = pThis;
  152. pThis->ExternalAddRef();
  153. }
  154. CATCH_ALL(e)
  155. {
  156. return E_OUTOFMEMORY;
  157. }
  158. END_CATCH_ALL
  159. *ppenum = &pClone->m_xEnumVARIANT;
  160. return NOERROR;
  161. }
  162. /////////////////////////////////////////////////////////////////////////////
  163. // CEnumVariant message handlers