mirror of https://github.com/lianthony/NT4.0
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.
284 lines
5.3 KiB
284 lines
5.3 KiB
/***
|
|
*cenumpt.cpp
|
|
*
|
|
* Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
*Purpose:
|
|
* This module implements the CEnumPoint class.
|
|
*
|
|
*
|
|
*Implementation Notes:
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "hostenv.h"
|
|
#include "cenumpt.h"
|
|
|
|
|
|
CEnumPoint::CEnumPoint()
|
|
{
|
|
m_refs = 0;
|
|
|
|
m_psa = NULL;
|
|
m_celts = 0;
|
|
m_iCurrent = 0;
|
|
}
|
|
|
|
|
|
/***
|
|
*HRESULT CEnumPoint::Create(SAFEARRAY*, CEnumPoint**)
|
|
*Purpose:
|
|
* This routine creates a CPoint enumerator from the given
|
|
* (1 X N) SafeArray of CPoint IDispatch pointers.
|
|
*
|
|
*Entry:
|
|
* psa = pointer to a SafeArray of VARIANTs
|
|
*
|
|
*Exit:
|
|
* return value = HRESULT
|
|
*
|
|
* *ppenum = pointer to a CPoint enumerator
|
|
*
|
|
***********************************************************************/
|
|
HRESULT
|
|
CEnumPoint::Create(SAFEARRAY FAR* psa, CEnumPoint FAR* FAR* ppenum)
|
|
{
|
|
long lBound;
|
|
HRESULT hresult;
|
|
CEnumPoint FAR* penum;
|
|
|
|
|
|
// Verify that the SafeArray is the proper shape.
|
|
//
|
|
if(SafeArrayGetDim(psa) != 1)
|
|
return ResultFromScode(E_INVALIDARG);
|
|
|
|
hresult = SafeArrayGetLBound(psa, 1, &lBound);
|
|
if(FAILED(hresult))
|
|
return hresult;
|
|
|
|
if(lBound != 0)
|
|
return ResultFromScode(E_INVALIDARG);
|
|
|
|
penum = new FAR CEnumPoint();
|
|
if(penum == NULL)
|
|
return ResultFromScode(E_OUTOFMEMORY);
|
|
penum->AddRef();
|
|
|
|
hresult = SafeArrayGetUBound(psa, 1, &lBound);
|
|
if(FAILED(hresult))
|
|
goto LError0;
|
|
|
|
penum->m_psa = psa;
|
|
penum->m_celts = lBound + 1;
|
|
|
|
*ppenum = penum;
|
|
|
|
return NOERROR;
|
|
|
|
LError0:;
|
|
penum->Release();
|
|
|
|
return hresult;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
// IUnknown methods
|
|
//---------------------------------------------------------------------
|
|
|
|
|
|
STDMETHODIMP
|
|
CEnumPoint::QueryInterface(REFIID riid, void FAR* FAR* ppv)
|
|
{
|
|
|
|
if(!IsEqualIID(riid, IID_IUnknown))
|
|
if(!IsEqualIID(riid, IID_IEnumVARIANT)) {
|
|
*ppv = NULL;
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
*ppv = this;
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(unsigned long)
|
|
CEnumPoint::AddRef()
|
|
{
|
|
return ++m_refs;
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(unsigned long)
|
|
CEnumPoint::Release()
|
|
{
|
|
if(--m_refs == 0){
|
|
if(m_psa != NULL)
|
|
SafeArrayDestroy(m_psa);
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_refs;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
// IEnumVARIANT methods
|
|
//---------------------------------------------------------------------
|
|
|
|
|
|
/***
|
|
*HRESULT CEnumPoint::Next(unsigned long, VARIANT*, unsigned long*)
|
|
*Purpose:
|
|
* Attempt to get the next 'celt' items in the enumeration sequence.
|
|
*
|
|
*Entry:
|
|
* celt = the number of elements to get
|
|
*
|
|
*Exit:
|
|
* return value = HRESULT
|
|
* S_OK
|
|
* S_FALSE - the end of the sequence was reached
|
|
*
|
|
* rgvar = array of the next 'celt' items
|
|
* *pceltFetched = count of the elements actually fetched.
|
|
*
|
|
***********************************************************************/
|
|
STDMETHODIMP
|
|
CEnumPoint::Next(
|
|
unsigned long celt,
|
|
VARIANT FAR* rgvar,
|
|
unsigned long FAR* pceltFetched)
|
|
{
|
|
long ix;
|
|
unsigned int i;
|
|
HRESULT hresult;
|
|
|
|
|
|
for(i = 0; i < celt; ++i)
|
|
VariantInit(&rgvar[i]);
|
|
|
|
for(i = 0; i < celt; ++i){
|
|
if(m_iCurrent == m_celts){
|
|
hresult = ResultFromScode(S_FALSE);
|
|
goto LDone;
|
|
}
|
|
|
|
ix = m_iCurrent++;
|
|
hresult = SafeArrayGetElement(m_psa, &ix, &rgvar[i]);
|
|
if(FAILED(hresult))
|
|
goto LError0;
|
|
}
|
|
|
|
hresult = NOERROR;
|
|
|
|
LDone:;
|
|
if (pceltFetched != NULL)
|
|
*pceltFetched = i;
|
|
|
|
return hresult;
|
|
|
|
LError0:;
|
|
|
|
for(i = 0; i < celt; ++i)
|
|
VariantClear(&rgvar[i]);
|
|
|
|
return hresult;
|
|
}
|
|
|
|
|
|
/***
|
|
*HRESULT CEnumPoint::Skip(unsigned long)
|
|
*Purpose:
|
|
* Attempt to skip over the next 'celt' elements in the enumeration
|
|
* sequence.
|
|
*
|
|
*Entry:
|
|
* celt = the count of elements to skip
|
|
*
|
|
*Exit:
|
|
* return value = HRESULT
|
|
* S_OK
|
|
* S_FALSE - the end of the sequence was reached
|
|
*
|
|
***********************************************************************/
|
|
STDMETHODIMP
|
|
CEnumPoint::Skip(unsigned long celt)
|
|
{
|
|
m_iCurrent += celt;
|
|
|
|
if(m_iCurrent > m_celts)
|
|
m_iCurrent = m_celts;
|
|
|
|
return (m_iCurrent == m_celts)
|
|
? ResultFromScode(S_FALSE) : NOERROR;
|
|
}
|
|
|
|
|
|
/***
|
|
*HRESULT CEnumPoint::Reset(void)
|
|
*Purpose:
|
|
* Reset the enumeration sequence back to the beginning.
|
|
*
|
|
*Entry:
|
|
* None
|
|
*
|
|
*Exit:
|
|
* return value = SHRESULT CODE
|
|
* S_OK
|
|
*
|
|
***********************************************************************/
|
|
STDMETHODIMP
|
|
CEnumPoint::Reset()
|
|
{
|
|
m_iCurrent = 0;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
/***
|
|
*HRESULT CEnumPoint::Clone(IEnumVARIANT**)
|
|
*Purpose:
|
|
* Retrun a CPoint enumerator with exactly the same state as the
|
|
* current one.
|
|
*
|
|
*Entry:
|
|
* None
|
|
*
|
|
*Exit:
|
|
* return value = HRESULT
|
|
* S_OK
|
|
* E_OUTOFMEMORY
|
|
*
|
|
***********************************************************************/
|
|
STDMETHODIMP
|
|
CEnumPoint::Clone(IEnumVARIANT FAR* FAR* ppenum)
|
|
{
|
|
HRESULT hresult;
|
|
SAFEARRAY FAR* psa;
|
|
CEnumPoint FAR* penum;
|
|
|
|
hresult = SafeArrayCopy(m_psa, &psa);
|
|
if(FAILED(hresult))
|
|
return hresult;
|
|
|
|
hresult = CEnumPoint::Create(psa, &penum);
|
|
if(FAILED(hresult))
|
|
goto LError0;
|
|
|
|
// Assert(penum->m_celts == m_celts);
|
|
|
|
penum->m_iCurrent = m_iCurrent;
|
|
|
|
*ppenum = penum;
|
|
|
|
return NOERROR;
|
|
|
|
LError0:
|
|
SafeArrayDestroy(psa);
|
|
|
|
return hresult;
|
|
}
|