📄 impienumstring.cpp
字号:
// ImpEnumString.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 IEnumXXXX::Next in Win32SDK\OLE\Reference\Interfaces\IEnumXXXX
// for general guidelines for enumerators
//
// (c) COPYRIGHT 1996-1998, INTELLUTION INC.
// ALL RIGHTS RESERVED
//
//
// Functions defined in this module:
//
// CImpIEnumString::CImpIEnumString()
// CImpIEnumString::~CImpIEnumString()
// CImpIEnumString::AddRef()
// CImpIEnumString::Release()
// CImpIEnumString::QueryInterface()
// CImpIEnumString::Next()
// CImpIEnumString::Skip()
// CImpIEnumString::Reset()
// CImpIEnumString::Clone()
//
//
//
// Modification Log:
// Vers Date By Notes
// ---- -------- --- -----
// 1.00 08/26/97 jra Created
// 1.3 03/10/98 jra Modified to be wizard generated and driver specific.
//
#define WIN32_LEAN_AND_MEAN
#include "OpcStdAfx.h"
#include "OPC.h"
#include "OPCDrv.h"
////////////////////////////////////////////////////////////////
// CImpIEnumString::CImpIEnumString()
//
// Constructor
//
// Parameters:
// pUnkRef - LPUNKNOWN to use for reference counting.
// lNumStrings - ULONG number of LPOLESTRs in pstr
// pOleStrings - LPOLESTR to the array to enumerate.
// (note OLESTR == WSTR)
// pIMalloc - IMalloc memory allocator to use for returned
// strings
//
////////////////////////////////////////////////////////////////
CImpIEnumString::CImpIEnumString(LPUNKNOWN pUnkRef,
ULONG lNumStrings,
LPOLESTR *pOleStrings,
IMalloc *pIMalloc)
{
// Initialize the data members
//
m_lRefCount = 0;
m_pUnkRef = pUnkRef;
m_lCurrentElement = 0;
m_lNumStrings = lNumStrings;
m_lpOLEStrings = new LPOLESTR[lNumStrings];
m_pIMalloc = pIMalloc;
if (NULL != m_lpOLEStrings)
{
// Make local copies of all the strings
//
for (UINT i = 0; i < m_lNumStrings; i++)
{
m_lpOLEStrings[i] = new WCHAR[wcslen(pOleStrings[i]) + 1];
wcscpy(m_lpOLEStrings[i], pOleStrings[i]);
}
}
return;
}
////////////////////////////////////////////////////////////////
// CImpIEnumString::~CImpIEnumString()
//
// Destructor
//
////////////////////////////////////////////////////////////////
CImpIEnumString::~CImpIEnumString(void)
{
if (NULL != m_lpOLEStrings)
{
// Delete the local copies of all the strings
//
for (unsigned int i = 0; i < m_lNumStrings; i++)
{
delete [] m_lpOLEStrings[i];
}
delete [] m_lpOLEStrings;
}
return;
}
////////////////////////////////////////////////////////////////
// CImpIEnumString::QueryInterface()
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIEnumString::QueryInterface(REFIID riid,
LPVOID *ppInterface)
{
*ppInterface = NULL;
if (IID_IUnknown == riid || IID_IEnumString == riid)
{
*ppInterface = (LPVOID)this;
}
if (NULL != *ppInterface)
{
((LPUNKNOWN)*ppInterface)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
////////////////////////////////////////////////////////////////
// CImpIEnumString::AddRef()
//
////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CImpIEnumString::AddRef(void)
{
// Addref this object and also the 'parent' if any
//
InterlockedIncrement(&m_lRefCount);
if(m_pUnkRef != NULL)
{
m_pUnkRef->AddRef();
}
return m_lRefCount;
}
////////////////////////////////////////////////////////////////
// CImpIEnumString::Release()
//
////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CImpIEnumString::Release(void)
{
// Release this object and also the 'parent' if any
//
if(m_pUnkRef != NULL)
{
m_pUnkRef->Release();
}
if (0L != InterlockedDecrement(&m_lRefCount))
{
return m_lRefCount;
}
delete this;
return 0;
}
////////////////////////////////////////////////////////////////
// CImpIEnumString::Next
//
// Purpose:
// Returns the next element in the enumeration.
//
// Parameters:
// lMax 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 CImpIEnumString::Next(ULONG lMax,
LPOLESTR *pstr,
ULONG *pulstr)
{
ULONG lReturn = 0L;
ULONG lMaxCount = lMax;
*pulstr = 0L; // default return count
*pstr = NULL; // default return pointer
// If this enumerator is empty - return FALSE (should never happen)
//
if (NULL == m_lpOLEStrings)
{
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 != lMax)
{
return E_POINTER;
}
}
// If we are at end of list return FALSE
//
if (m_lCurrentElement >= m_lNumStrings)
{
return S_FALSE;
}
// Return as many as we have left in list up to request count
//
while (m_lCurrentElement < m_lNumStrings && lMax > 0)
{
int size;
// Compute WCHARs in string (will be at least 1 for nul).
//
size = (wcslen(m_lpOLEStrings[m_lCurrentElement])+1);
pstr[lReturn] = (WCHAR*)m_pIMalloc->Alloc(size * sizeof(WCHAR));
if(pstr[lReturn])
{
wcscpy(pstr[lReturn], m_lpOLEStrings[m_lCurrentElement]);
}
// And move on to the next one
//
m_lCurrentElement++;
lReturn++;
lMax--;
}
if (NULL != pulstr)
{
*pulstr = lReturn;
}
if (lReturn == lMaxCount)
{
return S_OK;
}
return S_FALSE;
}
////////////////////////////////////////////////////////////////
// CImpIEnumString::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 CImpIEnumString::Skip(ULONG cSkip)
{
if (((m_lCurrentElement + cSkip) >= m_lNumStrings) || NULL == m_lpOLEStrings)
{
return S_FALSE;
}
this->m_lCurrentElement += cSkip;
return S_OK;
}
////////////////////////////////////////////////////////////////
// CImpIEnumString::Reset()
//
// Purpose:
// Resets the current element index in the enumeration to zero.
//
// Parameters:
// None
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIEnumString::Reset(void)
{
this->m_lCurrentElement = 0;
return S_OK;
}
////////////////////////////////////////////////////////////////
// CImpIEnumString::Clone()
//
// Purpose:
// Returns another IEnumString with the same state as ourselves.
//
// Parameters:
// ppEnum LPENUMSTRING * in which to return the
// new object.
//
/////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIEnumString::Clone(LPENUMSTRING *ppEnum)
{
CImpIEnumString *pNew;
*ppEnum = NULL;
// Create the clone
//
pNew = new CImpIEnumString(this->m_pUnkRef,
this->m_lNumStrings,
this->m_lpOLEStrings,
this->m_pIMalloc);
if (NULL == pNew)
{
return E_OUTOFMEMORY;
}
pNew->AddRef();
// Set the 'state' of the clone to match the state if this
//
pNew->m_lCurrentElement = this->m_lCurrentElement;
*ppEnum = pNew;
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -