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

Windows编程

开发平台:

Visual C++

  1. /*** 
  2. *cenumpt.cpp
  3. *
  4. *  This is a part of the Microsoft Source Code Samples.
  5. *
  6. *  Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
  7. *
  8. *  This source code is only intended as a supplement to Microsoft Development
  9. *  Tools and/or WinHelp documentation.  See these sources for detailed
  10. *  information regarding the Microsoft samples programs.
  11. *
  12. *Purpose:
  13. *  This module implements the CEnumPoint class.
  14. *
  15. *
  16. *Implementation Notes:
  17. *
  18. *****************************************************************************/
  19. #include "hostenv.h"
  20. #include "cenumpt.h"
  21. CEnumPoint::CEnumPoint()
  22. {
  23.     m_refs = 0;
  24.     m_psa = NULL;
  25.     m_celts = 0;
  26.     m_iCurrent = 0;
  27. }
  28. /***
  29. *HRESULT CEnumPoint::Create(SAFEARRAY*, CEnumPoint**)
  30. *Purpose:
  31. *  This routine creates a CPoint enumerator from the given
  32. *  (1 X N) SafeArray of CPoint IDispatch pointers.
  33. *
  34. *Entry:
  35. *  psa = pointer to a SafeArray of VARIANTs
  36. *
  37. *Exit:
  38. *  return value = HRESULT
  39. *
  40. *  *ppenum = pointer to a CPoint enumerator
  41. *
  42. ***********************************************************************/
  43. HRESULT
  44. CEnumPoint::Create(SAFEARRAY FAR* psa, CEnumPoint FAR* FAR* ppenum)
  45. {
  46.     long lBound;
  47.     HRESULT hresult;
  48.     CEnumPoint FAR* penum;
  49.     // Verify that the SafeArray is the proper shape.
  50.     //
  51.     if(SafeArrayGetDim(psa) != 1)
  52.       return E_INVALIDARG;
  53.     hresult = SafeArrayGetLBound(psa, 1, &lBound);
  54.     if(FAILED(hresult))
  55.       return hresult;
  56.     if(lBound != 0)
  57.       return E_INVALIDARG;
  58.     penum = new FAR CEnumPoint();
  59.     if(penum == NULL)
  60.       return E_OUTOFMEMORY;
  61.     penum->AddRef();
  62.     hresult = SafeArrayGetUBound(psa, 1, &lBound);
  63.     if(FAILED(hresult))
  64.       goto LError0;
  65.     penum->m_psa = psa;
  66.     penum->m_celts = lBound + 1;
  67.     *ppenum = penum;
  68.     return NOERROR;
  69. LError0:;
  70.     penum->Release();
  71.     return hresult;
  72. }
  73. //---------------------------------------------------------------------
  74. //                        IUnknown methods
  75. //---------------------------------------------------------------------
  76. STDMETHODIMP
  77. CEnumPoint::QueryInterface(REFIID riid, void FAR* FAR* ppv)
  78. {
  79.     if(IsEqualIID(riid, IID_IEnumVARIANT) || IsEqualIID(riid, IID_IUnknown)){
  80.       *ppv = this;
  81.       AddRef();
  82.       return NOERROR;
  83.     }
  84.     *ppv = NULL;
  85.     return E_NOINTERFACE;
  86. }
  87. STDMETHODIMP_(unsigned long)
  88. CEnumPoint::AddRef()
  89. {
  90.     return ++m_refs;
  91. }
  92. STDMETHODIMP_(unsigned long)
  93. CEnumPoint::Release()
  94. {
  95.     if(--m_refs == 0){
  96.       if(m_psa != NULL)
  97. SafeArrayDestroy(m_psa);
  98.       delete this;
  99.       return 0;
  100.     }
  101.     return m_refs;
  102. }
  103. //---------------------------------------------------------------------
  104. //                        IEnumVARIANT methods
  105. //---------------------------------------------------------------------
  106. /***
  107. *HRESULT CEnumPoint::Next(unsigned long, VARIANT*, unsigned long*)
  108. *Purpose:
  109. *  Attempt to get the next 'celt' items in the enumeration sequence.
  110. *
  111. *Entry:
  112. *  celt = the number of elements to get
  113. *
  114. *Exit:
  115. *  return value = HRESULT
  116. *    S_OK
  117. *    S_FALSE - the end of the sequence was reached
  118. *
  119. *  rgvar = array of the next 'celt' items
  120. *  *pceltFetched = count of the elements actually fetched.
  121. *
  122. ***********************************************************************/
  123. STDMETHODIMP
  124. CEnumPoint::Next(
  125.     unsigned long celt,
  126.     VARIANT FAR* rgvar,
  127.     unsigned long FAR* pceltFetched)
  128. {
  129.     long ix;
  130.     unsigned int i;
  131.     HRESULT hresult;
  132.     for(i = 0; i < celt; ++i)
  133.       VariantInit(&rgvar[i]);
  134.     for(i = 0; i < celt; ++i){
  135.       if(m_iCurrent == m_celts){
  136.         hresult = S_FALSE;
  137. goto LDone;
  138.       }
  139.       ix = m_iCurrent++;
  140.       hresult = SafeArrayGetElement(m_psa, &ix, &rgvar[i]);
  141.       if(FAILED(hresult))
  142. goto LError0;
  143.     }
  144.     hresult = NOERROR;
  145. LDone:;
  146.     if (pceltFetched != NULL)
  147.       *pceltFetched = i;
  148.     return hresult;
  149. LError0:;
  150.     for(i = 0; i < celt; ++i)
  151.       VariantClear(&rgvar[i]);
  152.     return hresult;
  153. }
  154. /***
  155. *HRESULT CEnumPoint::Skip(unsigned long)
  156. *Purpose:
  157. *  Attempt to skip over the next 'celt' elements in the enumeration
  158. *  sequence.
  159. *
  160. *Entry:
  161. *  celt = the count of elements to skip
  162. *
  163. *Exit:
  164. *  return value = HRESULT
  165. *    S_OK
  166. *    S_FALSE -  the end of the sequence was reached
  167. *
  168. ***********************************************************************/
  169. STDMETHODIMP
  170. CEnumPoint::Skip(unsigned long celt)
  171. {
  172.     m_iCurrent += celt;
  173.     if(m_iCurrent > m_celts)
  174.      m_iCurrent = m_celts;
  175.     return (m_iCurrent == m_celts)
  176.       ? S_FALSE : NOERROR;
  177. }
  178. /***
  179. *HRESULT CEnumPoint::Reset(void)
  180. *Purpose:
  181. *  Reset the enumeration sequence back to the beginning.
  182. *
  183. *Entry:
  184. *  None
  185. *
  186. *Exit:
  187. *  return value = SHRESULT CODE
  188. *    S_OK
  189. *
  190. ***********************************************************************/
  191. STDMETHODIMP
  192. CEnumPoint::Reset()
  193. {
  194.     m_iCurrent = 0;
  195.     return NOERROR; 
  196. }
  197. /***
  198. *HRESULT CEnumPoint::Clone(IEnumVARIANT**)
  199. *Purpose:
  200. *  Retrun a CPoint enumerator with exactly the same state as the
  201. *  current one.
  202. *
  203. *Entry:
  204. *  None
  205. *
  206. *Exit:
  207. *  return value = HRESULT
  208. *    S_OK
  209. *    E_OUTOFMEMORY
  210. *
  211. ***********************************************************************/
  212. STDMETHODIMP
  213. CEnumPoint::Clone(IEnumVARIANT FAR* FAR* ppenum)
  214. {
  215.     HRESULT hresult;
  216.     SAFEARRAY FAR* psa;
  217.     CEnumPoint FAR* penum;
  218.     hresult = SafeArrayCopy(m_psa, &psa);
  219.     if(FAILED(hresult))
  220.       return hresult;
  221.     hresult = CEnumPoint::Create(psa, &penum);
  222.     if(FAILED(hresult))
  223.       goto LError0;
  224.     // Assert(penum->m_celts == m_celts);
  225.     penum->m_iCurrent = m_iCurrent;
  226.     *ppenum = penum;
  227.     return NOERROR;
  228. LError0:
  229.     SafeArrayDestroy(psa);
  230.     return hresult;
  231. }