www.pudn.com > Ge_opc_Server_v1.rar > I_ENUMUN.CPP
// I_enumun.cpp
//
// This file contains an implementation of an IEnumUnknown interface.
// Note this is a fully 'generic' enumerator implementation.
//
// Since the list of elements is buffered in the object
// It is appropriate for enumerations with a 'reasonable' number of elements
//
// There is no OPC or Server specific code here.
//
// See IEnumLHEpipeviewX::Next in Win32SDK\OLE\Reference\Interfaces\IEnumLHEpipeviewX
// for general guidelines for enumerators
//
//
// (c) COPYRIGHT 1996, INTELLUTION INC.
// ALL RIGHTS RESERVED
//
// Original Author: Al Chisholm
//
// Modification Log:
// Vers Date By Notes
// ---- -------- --- -----
// 0.00 12/10/96 ACC Based on Brockschmidt (with improvements)
//
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#include "OLE2.h"
#include "ENUMHELP.h"
/*
* ILHEpipeviewEnumUnknown::ILHEpipeviewEnumUnknown
* ILHEpipeviewEnumUnknown::~ILHEpipeviewEnumUnknown
*
* Parameters (Constructor):
* pUnkRef LPUNKNOWN to use for reference counting (the 'parent').
* cUnk ULONG number of LPUNKNOWNs in prgUnk
* prgUnk LPUNKNOWN to the array to enumerate (we will make a local copy).
*/
ILHEpipeviewEnumUnknown::ILHEpipeviewEnumUnknown(LPUNKNOWN pUnkRef, ULONG cUnk
, LPUNKNOWN *prgUnk, IMalloc * pmem)
{
UINT i;
m_cRef=0;
m_pUnkRef=pUnkRef;
m_iCur=0;
m_cUnk=cUnk;
m_prgUnk=new LPUNKNOWN[(UINT)cUnk];
m_pmem = pmem;
if (NULL!=m_prgUnk)
{
for (i=0; i < cUnk; i++)
{
// Create a local copy of the IUnknown List
// And AddRef to insure the objects are not deleted
// while the ENUM is using them!
//
m_prgUnk[i] = prgUnk[i];
m_prgUnk[i]->AddRef();
}
}
return;
}
ILHEpipeviewEnumUnknown::~ILHEpipeviewEnumUnknown(void)
{
unsigned int i;
if (NULL != m_prgUnk)
{
for (i=0; i < m_cUnk; i++)
{
// Release each object since this ENUM is done with it
//
m_prgUnk[i]->Release();
}
delete [] m_prgUnk;
}
return;
}
/*
* ILHEpipeviewEnumUnknown::QueryInterface
* ILHEpipeviewEnumUnknown::AddRef
* ILHEpipeviewEnumUnknown::Release
*
* Purpose:
* IUnknown members for ILHEpipeviewEnumUnknown object.
*/
STDMETHODIMP ILHEpipeviewEnumUnknown::QueryInterface(REFIID riid
, LPVOID *ppv)
{
*ppv=NULL;
/*
* Enumerators are separate objects with their own
* QueryInterface behavior.
*/
if (IID_IUnknown==riid || IID_IEnumUnknown==riid)
*ppv=(LPVOID)this;
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) ILHEpipeviewEnumUnknown::AddRef(void)
{
// Addref this object and also the 'parent' if any
//
++m_cRef;
if(m_pUnkRef != NULL)
m_pUnkRef->AddRef();
return m_cRef;
}
STDMETHODIMP_(ULONG) ILHEpipeviewEnumUnknown::Release(void)
{
// Release this object and also the 'parent' if any
//
if(m_pUnkRef != NULL)
m_pUnkRef->Release();
if (0L!=--m_cRef)
return m_cRef;
delete this;
return 0;
}
/*
* ILHEpipeviewEnumUnknown::Next
*
* Purpose:
* Returns the next element in the enumeration.
*
* Parameters:
* cRequested ULONG max number of LPUNKNOWNs to return.
* ppUnk LPUNKNOWN * in which to store the returned
* pointer.
* pActual ULONG * in which to return how many we actually
* enumerated.
*
* Return Value:
* HRESULT S_OK if successful, S_FALSE otherwise,
*/
STDMETHODIMP ILHEpipeviewEnumUnknown::Next(ULONG cRequested, IUnknown **ppUnk
, ULONG *pActual)
{
ULONG cReturn=0L;
ULONG maxcount = cRequested;
*pActual = 0L; // default
*ppUnk = NULL; // default
// If this enumerator is empty - return FALSE
//
if (NULL==m_prgUnk)
return S_FALSE;
// If user passed null for count of items returned
// Then he is only allowed to ask for 1 item
//
if (NULL == pActual)
{
if (1L != cRequested)
return E_POINTER;
}
// If we are at end of list return FALSE
//
if (m_iCur >= m_cUnk)
return S_FALSE;
// Return as many as we have left in list up to request count
//
while (m_iCur < m_cUnk && cRequested > 0)
{
ppUnk[cReturn] = m_prgUnk[m_iCur];
if (NULL != ppUnk[cReturn]) // (should never be null)
ppUnk[cReturn]->AddRef();
// And move on to the next one
//
m_iCur++;
cReturn++;
cRequested--;
}
if (NULL != pActual)
*pActual = cReturn;
if (cReturn == maxcount) return S_OK;
return S_FALSE;
}
/*
* ILHEpipeviewEnumUnknown::Skip
*
* Purpose:
* Skips the next n elements in the enumeration.
*
* Parameters:
* cSkip ULONG number of elements to skip.
*
* Return Value:
* HRESULT S_OK if successful, S_FALSE if we could not
* skip the requested number.
*/
STDMETHODIMP ILHEpipeviewEnumUnknown::Skip(ULONG cSkip)
{
if (((m_iCur+cSkip) >= m_cUnk) || NULL==m_prgUnk)
return S_FALSE;
m_iCur+=cSkip;
return S_OK;
}
/*
* ILHEpipeviewEnumUnknown::Reset
*
* Purpose:
* Resets the current element index in the enumeration to zero.
*
* Parameters:
* None
*/
STDMETHODIMP ILHEpipeviewEnumUnknown::Reset(void)
{
m_iCur=0;
return S_OK;
}
/*
* ILHEpipeviewEnumUnknown::Clone
*
* Purpose:
* Returns another IEnumUnknown with the same state as ourselves.
*
* Parameters:
* ppEnum LPENUMUNKNOWN * in which to return the
* new object.
*/
STDMETHODIMP ILHEpipeviewEnumUnknown::Clone(LPENUMUNKNOWN *ppEnum)
{
ILHEpipeviewEnumUnknown *pNew;
*ppEnum=NULL;
//Create the clone
//
pNew=new ILHEpipeviewEnumUnknown(m_pUnkRef, m_cUnk, m_prgUnk, m_pmem);
if (NULL==pNew)
return E_OUTOFMEMORY;
pNew->AddRef();
// Set the 'state' of the clone to match the state if this
//
pNew->m_iCur=m_iCur;
*ppEnum=pNew;
return S_OK;
}