www.pudn.com > Ge_opc_Server_v1.rar > I_ENUMST.CPP
// I_enumst.cpp
//
// This file contains an implementation of an IEnumString 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.
//
// Note that new/delete is used for local buffer storage
// while the global allocator is used for returned storage.
//
// 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"
/*
* ILHEpipeviewEnumString::ILHEpipeviewEnumString
* ILHEpipeviewEnumString::~ILHEpipeviewEnumString
*
* Parameters (Constructor):
* pUnkRef LPUNKNOWN to use for reference counting.
* cstr ULONG number of LPOLESTRs in pstr
* prgstr LPOLESTR to the array to enumerate. (note OLESTR == WSTR)
* pmem IMalloc memory allocator to use for returned strings
*/
ILHEpipeviewEnumString::ILHEpipeviewEnumString(LPUNKNOWN pUnkRef, ULONG cstr
, LPOLESTR *prgstr, IMalloc * pmem)
{
UINT i;
m_cRef = 0;
m_pUnkRef = pUnkRef;
m_iCur = 0;
m_cstr = cstr;
m_prgstr = new LPOLESTR[cstr];
m_pmem = pmem;
if (NULL != m_prgstr)
{
// Make local copies of all the strings
//
for (i=0; i < m_cstr; i++)
{
m_prgstr[i] = new WCHAR[wcslen(prgstr[i]) + 1];
wcscpy(m_prgstr[i], prgstr[i]);
}
}
return;
}
ILHEpipeviewEnumString::~ILHEpipeviewEnumString(void)
{
unsigned int i;
if (NULL!=m_prgstr)
{
// Delete the local copies of all the strings
//
for (i=0; i < m_cstr; i++)
{
delete [] m_prgstr[i];
}
delete [] m_prgstr;
}
return;
}
/*
* ILHEpipeviewEnumString::QueryInterface
* ILHEpipeviewEnumString::AddRef
* ILHEpipeviewEnumString::Release
*
* Purpose:
* IUnknown members for ILHEpipeviewEnumString object.
*/
STDMETHODIMP ILHEpipeviewEnumString::QueryInterface(REFIID riid
, LPVOID *ppv)
{
*ppv=NULL;
if (IID_IUnknown==riid || IID_IEnumString==riid)
*ppv=(LPVOID)this;
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) ILHEpipeviewEnumString::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) ILHEpipeviewEnumString::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;
}
/*
* ILHEpipeviewEnumString::Next
*
* Purpose:
* Returns the next element in the enumeration.
*
* Parameters:
* cstr ULONG max number of LPOLESTRs to return.
* pstr LPOLESTR(s) in which to store the returned
* structures.
* pulstr ULONG * in which to return how many we
* actually returned.
*
* Return Value:
* HRESULT S_OK if successful, S_FALSE otherwise,
*/
STDMETHODIMP ILHEpipeviewEnumString::Next(ULONG cstr, LPOLESTR *pstr
, ULONG *pulstr)
{
ULONG cReturn = 0L;
ULONG maxcount = cstr;
*pulstr = 0L; // default return count
*pstr = NULL; // default return pointer
// If this enumerator is empty - return FALSE (should never happen)
//
if (NULL == m_prgstr)
return S_FALSE;
// If user passed null for count of items returned
// Then he is only allowed to ask for 1 item
//
if (NULL == pulstr)
{
if (1L != cstr)
return E_POINTER;
}
// If we are at end of list return FALSE
//
if (m_iCur >= m_cstr)
return S_FALSE;
// Return as many as we have left in list up to request count
//
while (m_iCur < m_cstr && cstr > 0)
{
int size;
// Compute WCHARs in string (will be at least 1 for nul).
//
size = (wcslen(m_prgstr[m_iCur])+1);
pstr[cReturn] = (WCHAR*)m_pmem->Alloc(size * sizeof(WCHAR));
if(pstr[cReturn])
{
wcscpy(pstr[cReturn], m_prgstr[m_iCur]);
}
// And move on to the next one
//
m_iCur++;
cReturn++;
cstr--;
}
if (NULL != pulstr)
*pulstr = cReturn;
if (cReturn == maxcount) return S_OK;
return S_FALSE;
}
/*
* ILHEpipeviewEnumString::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 ILHEpipeviewEnumString::Skip(ULONG cSkip)
{
if (((m_iCur+cSkip) >= m_cstr) || NULL==m_prgstr)
return S_FALSE;
m_iCur+=cSkip;
return S_OK;
}
/*
* ILHEpipeviewEnumString::Reset
*
* Purpose:
* Resets the current element index in the enumeration to zero.
*
* Parameters:
* None
*/
STDMETHODIMP ILHEpipeviewEnumString::Reset(void)
{
m_iCur=0;
return S_OK;
}
/*
* ILHEpipeviewEnumString::Clone
*
* Purpose:
* Returns another IEnumString with the same state as ourselves.
*
* Parameters:
* ppEnum LPENUMSTRING * in which to return the
* new object.
*/
STDMETHODIMP ILHEpipeviewEnumString::Clone(LPENUMSTRING *ppEnum)
{
ILHEpipeviewEnumString *pNew;
*ppEnum=NULL;
//Create the clone
//
pNew=new ILHEpipeviewEnumString(m_pUnkRef, m_cstr, m_prgstr, 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;
}