home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / oleaut / spoly2 / cenumpt.cpp next >
C/C++ Source or Header  |  1997-08-01  |  6KB  |  288 lines

  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.  
  20. #include "hostenv.h"
  21. #include "cenumpt.h"
  22.  
  23.  
  24. CEnumPoint::CEnumPoint()
  25. {
  26.     m_refs = 0;
  27.  
  28.     m_psa = NULL;
  29.     m_celts = 0;
  30.     m_iCurrent = 0;
  31. }
  32.  
  33.  
  34. /***
  35. *HRESULT CEnumPoint::Create(SAFEARRAY*, CEnumPoint**)
  36. *Purpose:
  37. *  This routine creates a CPoint enumerator from the given
  38. *  (1 X N) SafeArray of CPoint IDispatch pointers.
  39. *
  40. *Entry:
  41. *  psa = pointer to a SafeArray of VARIANTs
  42. *
  43. *Exit:
  44. *  return value = HRESULT
  45. *
  46. *  *ppenum = pointer to a CPoint enumerator
  47. *
  48. ***********************************************************************/
  49. HRESULT
  50. CEnumPoint::Create(SAFEARRAY FAR* psa, CEnumPoint FAR* FAR* ppenum)
  51. {
  52.     long lBound;
  53.     HRESULT hresult;
  54.     CEnumPoint FAR* penum;
  55.  
  56.  
  57.     // Verify that the SafeArray is the proper shape.
  58.     //
  59.     if(SafeArrayGetDim(psa) != 1)
  60.       return E_INVALIDARG;
  61.  
  62.     hresult = SafeArrayGetLBound(psa, 1, &lBound);
  63.     if(FAILED(hresult))
  64.       return hresult;
  65.  
  66.     if(lBound != 0)
  67.       return E_INVALIDARG;
  68.  
  69.     penum = new FAR CEnumPoint();
  70.     if(penum == NULL)
  71.       return E_OUTOFMEMORY;
  72.     penum->AddRef();
  73.  
  74.     hresult = SafeArrayGetUBound(psa, 1, &lBound);
  75.     if(FAILED(hresult))
  76.       goto LError0;
  77.  
  78.     penum->m_psa = psa;
  79.     penum->m_celts = lBound + 1;
  80.  
  81.     *ppenum = penum;
  82.  
  83.     return NOERROR;
  84.  
  85. LError0:;
  86.     penum->Release();
  87.  
  88.     return hresult;
  89. }
  90.  
  91.  
  92. //---------------------------------------------------------------------
  93. //                        IUnknown methods
  94. //---------------------------------------------------------------------
  95.  
  96.  
  97. STDMETHODIMP
  98. CEnumPoint::QueryInterface(REFIID riid, void FAR* FAR* ppv)
  99. {
  100.     if(IsEqualIID(riid, IID_IEnumVARIANT) || IsEqualIID(riid, IID_IUnknown)){
  101.       *ppv = this;
  102.       AddRef();
  103.       return NOERROR;
  104.     }
  105.     *ppv = NULL;
  106.     return E_NOINTERFACE;
  107. }
  108.  
  109.  
  110. STDMETHODIMP_(unsigned long)
  111. CEnumPoint::AddRef()
  112. {
  113.     return ++m_refs;
  114. }
  115.  
  116.  
  117. STDMETHODIMP_(unsigned long)
  118. CEnumPoint::Release()
  119. {
  120.     if(--m_refs == 0){
  121.       if(m_psa != NULL)
  122.     SafeArrayDestroy(m_psa);
  123.       delete this;
  124.       return 0;
  125.     }
  126.     return m_refs;
  127. }
  128.  
  129.  
  130. //---------------------------------------------------------------------
  131. //                        IEnumVARIANT methods
  132. //---------------------------------------------------------------------
  133.  
  134.  
  135. /***
  136. *HRESULT CEnumPoint::Next(unsigned long, VARIANT*, unsigned long*)
  137. *Purpose:
  138. *  Attempt to get the next 'celt' items in the enumeration sequence.
  139. *
  140. *Entry:
  141. *  celt = the number of elements to get
  142. *
  143. *Exit:
  144. *  return value = HRESULT
  145. *    S_OK
  146. *    S_FALSE - the end of the sequence was reached
  147. *
  148. *  rgvar = array of the next 'celt' items
  149. *  *pceltFetched = count of the elements actually fetched.
  150. *
  151. ***********************************************************************/
  152. STDMETHODIMP
  153. CEnumPoint::Next(
  154.     unsigned long celt,
  155.     VARIANT FAR* rgvar,
  156.     unsigned long FAR* pceltFetched)
  157. {
  158.     long ix;
  159.     unsigned int i;
  160.     HRESULT hresult;
  161.  
  162.  
  163.     for(i = 0; i < celt; ++i)
  164.       VariantInit(&rgvar[i]);
  165.  
  166.     for(i = 0; i < celt; ++i){
  167.       if(m_iCurrent == m_celts){
  168.         hresult = S_FALSE;
  169.     goto LDone;
  170.       }
  171.  
  172.       ix = m_iCurrent++;
  173.       hresult = SafeArrayGetElement(m_psa, &ix, &rgvar[i]);
  174.       if(FAILED(hresult))
  175.     goto LError0;
  176.     }
  177.  
  178.     hresult = NOERROR;
  179.  
  180. LDone:;
  181.     if (pceltFetched != NULL)
  182.       *pceltFetched = i;
  183.  
  184.     return hresult;
  185.  
  186. LError0:;
  187.  
  188.     for(i = 0; i < celt; ++i)
  189.       VariantClear(&rgvar[i]);
  190.  
  191.     return hresult;
  192. }
  193.  
  194.  
  195. /***
  196. *HRESULT CEnumPoint::Skip(unsigned long)
  197. *Purpose:
  198. *  Attempt to skip over the next 'celt' elements in the enumeration
  199. *  sequence.
  200. *
  201. *Entry:
  202. *  celt = the count of elements to skip
  203. *
  204. *Exit:
  205. *  return value = HRESULT
  206. *    S_OK
  207. *    S_FALSE -  the end of the sequence was reached
  208. *
  209. ***********************************************************************/
  210. STDMETHODIMP
  211. CEnumPoint::Skip(unsigned long celt)
  212. {
  213.     m_iCurrent += celt;
  214.  
  215.     if(m_iCurrent > m_celts)
  216.      m_iCurrent = m_celts;
  217.  
  218.     return (m_iCurrent == m_celts)
  219.       ? S_FALSE : NOERROR;
  220. }
  221.  
  222.  
  223. /***
  224. *HRESULT CEnumPoint::Reset(void)
  225. *Purpose:
  226. *  Reset the enumeration sequence back to the beginning.
  227. *
  228. *Entry:
  229. *  None
  230. *
  231. *Exit:
  232. *  return value = SHRESULT CODE
  233. *    S_OK
  234. *
  235. ***********************************************************************/
  236. STDMETHODIMP
  237. CEnumPoint::Reset()
  238. {
  239.     m_iCurrent = 0;
  240.  
  241.     return NOERROR; 
  242. }
  243.  
  244.  
  245. /***
  246. *HRESULT CEnumPoint::Clone(IEnumVARIANT**)
  247. *Purpose:
  248. *  Retrun a CPoint enumerator with exactly the same state as the
  249. *  current one.
  250. *
  251. *Entry:
  252. *  None
  253. *
  254. *Exit:
  255. *  return value = HRESULT
  256. *    S_OK
  257. *    E_OUTOFMEMORY
  258. *
  259. ***********************************************************************/
  260. STDMETHODIMP
  261. CEnumPoint::Clone(IEnumVARIANT FAR* FAR* ppenum)
  262. {
  263.     HRESULT hresult;
  264.     SAFEARRAY FAR* psa;
  265.     CEnumPoint FAR* penum;
  266.  
  267.     hresult = SafeArrayCopy(m_psa, &psa);
  268.     if(FAILED(hresult))
  269.       return hresult;
  270.  
  271.     hresult = CEnumPoint::Create(psa, &penum);
  272.     if(FAILED(hresult))
  273.       goto LError0;
  274.  
  275.     // Assert(penum->m_celts == m_celts);
  276.  
  277.     penum->m_iCurrent = m_iCurrent;
  278.  
  279.     *ppenum = penum;
  280.  
  281.     return NOERROR;
  282.  
  283. LError0:
  284.     SafeArrayDestroy(psa);
  285.  
  286.     return hresult;
  287. }
  288.