⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 impienumstring.cpp

📁 基于Intellution开发包的开发的OPC服务器
💻 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 + -