home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
sdk
/
com
/
inole2
/
chap10
/
ddataobj
/
ienumfe.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
5KB
|
260 lines
/*
* IENUMFE.CPP
* Data Object Chapter 10
*
* Standard implementation of a FORMATETC enumerator with the
* IEnumFORMATETC interface that will generally not need
* modification.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "dataobj.h"
/*
* CEnumFormatEtc::CEnumFormatEtc
* CEnumFormatEtc::~CEnumFormatEtc
*
* Parameters (Constructor):
* cFE ULONG number of FORMATETCs in pFE
* prgFE LPFORMATETC to the array to enumerate.
*/
CEnumFormatEtc::CEnumFormatEtc(ULONG cFE, LPFORMATETC prgFE)
{
UINT i;
m_cRef=0;
m_iCur=0;
m_cfe=cFE;
m_prgfe=new FORMATETC[(UINT)cFE];
if (NULL!=m_prgfe)
{
for (i=0; i < cFE; i++)
m_prgfe[i]=prgFE[i];
}
return;
}
CEnumFormatEtc::~CEnumFormatEtc(void)
{
if (NULL!=m_prgfe)
delete [] m_prgfe;
return;
}
/*
* CEnumFormatEtc::QueryInterface
* CEnumFormatEtc::AddRef
* CEnumFormatEtc::Release
*
* Purpose:
* IUnknown members for CEnumFormatEtc object. For QueryInterface
* we only return out own interfaces and not those of the data
* object. However, since enumerating formats only makes sense
* when the data object is around, we insure that it stays as
* long as we stay by calling an outer IUnknown for AddRef
* and Release. But since we are not controlled by the lifetime
* of the outer object, we still keep our own reference count in
* order to free ourselves.
*/
STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;
/*
* Enumerators are separate objects, not the data object, so
* we only need to support out IUnknown and IEnumFORMATETC
* interfaces here with no concern for aggregation.
*/
if (IID_IUnknown==riid || IID_IEnumFORMATETC==riid)
*ppv=this;
//AddRef any interface we'll return.
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
{
++m_cRef;
return m_cRef;
}
STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
{
if (0!=--m_cRef)
return m_cRef;
delete this;
return 0;
}
/*
* CEnumFormatEtc::Next
*
* Purpose:
* Returns the next element in the enumeration.
*
* Parameters:
* cFE ULONG number of FORMATETCs to return.
* pFE LPFORMATETC in which to store the returned
* structures.
* pulFE ULONG * in which to return how many we
* enumerated.
*
* Return Value:
* HRESULT NOERROR if successful, S_FALSE otherwise,
*/
STDMETHODIMP CEnumFormatEtc::Next(ULONG cFE, LPFORMATETC pFE
, ULONG *pulFE)
{
ULONG cReturn=0L;
if (NULL==m_prgfe)
return ResultFromScode(S_FALSE);
if (NULL==pulFE)
{
if (1L!=cFE)
return ResultFromScode(E_POINTER);
}
else
*pulFE=0L;
if (NULL==pFE || m_iCur >= m_cfe)
return ResultFromScode(S_FALSE);
while (m_iCur < m_cfe && cFE > 0)
{
*pFE++=m_prgfe[m_iCur++];
cReturn++;
cFE--;
}
if (NULL!=pulFE)
*pulFE=cReturn;
return NOERROR;
}
/*
* CEnumFormatEtc::Skip
*
* Purpose:
* Skips the next n elements in the enumeration.
*
* Parameters:
* cSkip ULONG number of elements to skip.
*
* Return Value:
* HRESULT NOERROR if successful, S_FALSE if we could not
* skip the requested number.
*/
STDMETHODIMP CEnumFormatEtc::Skip(ULONG cSkip)
{
if (((m_iCur+cSkip) >= m_cfe) || NULL==m_prgfe)
return ResultFromScode(S_FALSE);
m_iCur+=cSkip;
return NOERROR;
}
/*
* CEnumFormatEtc::Reset
*
* Purpose:
* Resets the current element index in the enumeration to zero.
*
* Parameters:
* None
*
* Return Value:
* HRESULT NOERROR
*/
STDMETHODIMP CEnumFormatEtc::Reset(void)
{
m_iCur=0;
return NOERROR;
}
/*
* CEnumFormatEtc::Clone
*
* Purpose:
* Returns another IEnumFORMATETC with the same state as ourselves.
*
* Parameters:
* ppEnum LPENUMFORMATETC * in which to return the
* new object.
*
* Return Value:
* HRESULT NOERROR or a general error value.
*/
STDMETHODIMP CEnumFormatEtc::Clone(LPENUMFORMATETC *ppEnum)
{
PCEnumFormatEtc pNew;
*ppEnum=NULL;
//Create the clone
pNew=new CEnumFormatEtc(m_cfe, m_prgfe);
if (NULL==pNew)
return ResultFromScode(E_OUTOFMEMORY);
pNew->AddRef();
pNew->m_iCur=m_iCur;
*ppEnum=pNew;
return NOERROR;
}