?? impienumunknown.cpp
字號(hào):
// ImpIEnumUnknown.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 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:
//
// CImpIEnumUnknown::CImpIEnumUnknown()
// CImpIEnumUnknown::~CImpIEnumUnknown()
// CImpIEnumUnknown::AddRef()
// CImpIEnumUnknown::Release()
// CImpIEnumUnknown::QueryInterface()
// CImpIEnumUnknown::Next()
// CImpIEnumUnknown::Skip()
// CImpIEnumUnknown::Reset()
// CImpIEnumUnknown::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"
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::CImpIEnumUnknown)_
//
// Constructor
//
// Parameters:
// 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).
//
////////////////////////////////////////////////////////////////
CImpIEnumUnknown::CImpIEnumUnknown(LPUNKNOWN pUnkOuter,
ULONG lCount,
LPUNKNOWN *pUnkList,
IMalloc *pIMalloc)
{
m_lRefCount = 0;
m_pUnkOuter = pUnkOuter;
m_lCurrentElem = 0;
m_lNumUnks = lCount;
m_pUnkList = new LPUNKNOWN[(UINT)lCount];
m_pIMalloc = pIMalloc;
if (NULL != m_pUnkList)
{
for (UINT i = 0; i < lCount; 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_pUnkList[i] = pUnkList[i];
m_pUnkList[i]->AddRef();
}
}
return;
}
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::~CImpIEnumUnknown
//
// Destructor
//
////////////////////////////////////////////////////////////////
CImpIEnumUnknown::~CImpIEnumUnknown(void)
{
unsigned int i;
if (NULL != m_pUnkList)
{
for (i = 0; i < m_lNumUnks; i++)
{
// Release each object since this ENUM is done with it
//
m_pUnkList[i]->Release();
}
delete [] m_pUnkList;
}
return;
}
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::QueryInterface()
//
// Purpose:
// IUnknown members for CImpIEnumUnknown object.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIEnumUnknown::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;
}
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::Release()
//
// Purpose:
// IUnknown members for CImpIEnumUnknown object.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CImpIEnumUnknown::AddRef(void)
{
// Addref this object and also the 'parent' if any
//
InterlockedIncrement(&m_lRefCount);
if(m_pUnkOuter != NULL)
{
m_pUnkOuter->AddRef();
}
return m_lRefCount;
}
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::Release()
//
// Purpose:
// IUnknown members for CImpIEnumUnknown object.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CImpIEnumUnknown::Release(void)
{
// Release this object and also the 'parent' if any
//
if(m_pUnkOuter != NULL)
{
m_pUnkOuter->Release();
}
if (0L != InterlockedDecrement(&m_lRefCount))
{
return m_lRefCount;
}
delete this;
return 0;
}
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::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 CImpIEnumUnknown::Next(ULONG cRequested,
IUnknown **ppUnk,
ULONG *pActual)
{
ULONG cReturn = 0L,
maxcount = cRequested;
*pActual = 0L; // default
*ppUnk = NULL; // default
// If this enumerator is empty - return FALSE
//
if (NULL == m_pUnkList)
{
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_lCurrentElem >= m_lNumUnks)
{
return S_FALSE;
}
// Return as many as we have left in list up to request count
//
while (m_lCurrentElem < m_lNumUnks && cRequested > 0)
{
ppUnk[cReturn] = m_pUnkList[m_lCurrentElem];
if (NULL != ppUnk[cReturn]) // (should never be null)
{
ppUnk[cReturn]->AddRef();
}
// And move on to the next one
//
m_lCurrentElem++;
cReturn++;
cRequested--;
}
if (NULL != pActual)
{
*pActual = cReturn;
}
if (cReturn == maxcount)
{
return S_OK;
}
return S_FALSE;
}
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::Skip()
//
// Purpose:
// Skips the next n elements in the enumeration.
//
// Parameters:
// lNumSkip ULONG number of elements to skip.
//
// Return Value:
// HRESULT - S_OK if successful, S_FALSE if we could not
// skip the requested number.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIEnumUnknown::Skip(ULONG lNumSkip)
{
if (((m_lCurrentElem + lNumSkip) >= m_lNumUnks) || NULL == m_pUnkList)
{
return S_FALSE;
}
m_lCurrentElem += lNumSkip;
return S_OK;
}
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::Reset()
//
// Purpose:
// Resets the current element index in the enumeration to zero.
//
// Parameters:
// None
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIEnumUnknown::Reset(void)
{
m_lCurrentElem = 0;
return S_OK;
}
////////////////////////////////////////////////////////////////
// CImpIEnumUnknown::Clone()
//
// Purpose:
// Returns another IEnumUnknown with the same state as ourselves.
//
// Parameters:
// ppEnum LPENUMUNKNOWN * in which to return the
// new object.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIEnumUnknown::Clone(LPENUMUNKNOWN *ppEnum)
{
CImpIEnumUnknown *pNew;
*ppEnum = NULL;
//Create the clone
//
pNew = new CImpIEnumUnknown(m_pUnkOuter, m_lNumUnks, m_pUnkList, m_pIMalloc);
if (NULL == pNew)
{
return E_OUTOFMEMORY;
}
pNew->AddRef();
// Set the 'state' of the clone to match the state if this
//
pNew->m_lCurrentElem = m_lCurrentElem;
*ppEnum=pNew;
return S_OK;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -