windows-nt/Source/XPSP1/NT/shell/themes/themeui/enumunknown.cpp

208 lines
4.9 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*****************************************************************************\
FILE: EnumUnknown.cpp
DESCRIPTION:
This code will implement IEnumUnknown for an HDPA.
BryanSt 5/30/2000 Updated and Converted to C++
Copyright (C) Microsoft Corp 2000-2000. All rights reserved.
\*****************************************************************************/
#include "priv.h"
#include "EnumUnknown.h"
class CEnumUnknown : public IEnumUnknown
{
public:
//////////////////////////////////////////////////////
// Public Interfaces
//////////////////////////////////////////////////////
// *** IUnknown ***
virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
virtual STDMETHODIMP_(ULONG) AddRef(void);
virtual STDMETHODIMP_(ULONG) Release(void);
// *** IEnumUnknown ***
virtual STDMETHODIMP Next(IN ULONG celt, IN IUnknown ** rgelt, IN ULONG * pceltFetched);
virtual STDMETHODIMP Skip(IN ULONG celt);
virtual STDMETHODIMP Reset(void);
virtual STDMETHODIMP Clone(OUT IEnumUnknown ** ppenum);
protected:
HRESULT _Initialize(void);
private:
CEnumUnknown(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex);
virtual ~CEnumUnknown(void);
// Private Member Variables
long m_cRef;
IUnknown * m_punkOwner; // The owner of m_pUnknownArray. We hold a ref on this guy to keep m_pUnknownArray valid.
IUnknown ** m_pUnknownArray; // The array of IUnknowns
int m_nArraySize; // The size of m_pUnknownArray
int m_nIndex; // The current index during enum.
// Private Member Functions
// Friend Functions
friend HRESULT CEnumUnknown_CreateInstance(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex, OUT IEnumUnknown ** ppEnumUnknown);
};
//===========================
// *** Class Internals & Helpers ***
//===========================
//===========================
// *** IEnumUnknown Interface ***
//===========================
HRESULT CEnumUnknown::Next(IN ULONG celt, IN IUnknown ** rgelt, IN ULONG * pceltFetched)
{
HRESULT hr = E_INVALIDARG;
if (rgelt && pceltFetched)
{
ULONG nIndex;
hr = S_OK;
*pceltFetched = 0;
for (nIndex = 0; nIndex < celt; nIndex++,m_nIndex++)
{
if ((m_nIndex < m_nArraySize) && m_pUnknownArray[m_nIndex])
{
rgelt[nIndex] = NULL;
IUnknown_Set(&(rgelt[nIndex]), m_pUnknownArray[m_nIndex]);
(*pceltFetched)++;
}
else
{
rgelt[nIndex] = NULL;
}
}
}
return hr;
}
HRESULT CEnumUnknown::Skip(IN ULONG celt)
{
m_nIndex += celt;
return S_OK;
}
HRESULT CEnumUnknown::Reset(void)
{
m_nIndex = 0;
return S_OK;
}
HRESULT CEnumUnknown::Clone(OUT IEnumUnknown ** ppenum)
{
HRESULT hr = E_INVALIDARG;
if (ppenum)
{
hr = CEnumUnknown_CreateInstance(SAFECAST(this, IEnumUnknown *), m_pUnknownArray, m_nArraySize, m_nIndex, ppenum);
}
return hr;
}
//===========================
// *** IUnknown Interface ***
//===========================
ULONG CEnumUnknown::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
ULONG CEnumUnknown::Release()
{
if (InterlockedDecrement(&m_cRef))
return m_cRef;
delete this;
return 0;
}
HRESULT CEnumUnknown::QueryInterface(REFIID riid, void **ppvObj)
{
static const QITAB qit[] = {
QITABENT(CEnumUnknown, IEnumUnknown),
{ 0 },
};
return QISearch(this, qit, riid, ppvObj);
}
//===========================
// *** Class Methods ***
//===========================
CEnumUnknown::CEnumUnknown(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex) : m_cRef(1)
{
DllAddRef();
// This needs to be allocated in Zero Inited Memory.
// Assert that all Member Variables are inited to Zero.
ASSERT(!m_punkOwner);
IUnknown_Set(&m_punkOwner, punkOwner);
m_pUnknownArray = ppArray;
m_nArraySize = nArraySize;
m_nIndex = nIndex;
}
CEnumUnknown::~CEnumUnknown()
{
IUnknown_Set(&m_punkOwner, NULL);
DllRelease();
}
HRESULT CEnumUnknown_CreateInstance(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex, OUT IEnumUnknown ** ppEnumUnknown)
{
HRESULT hr = E_INVALIDARG;
if (punkOwner && ppArray && ppEnumUnknown)
{
CEnumUnknown * pObject = new CEnumUnknown(punkOwner, ppArray, nArraySize, nIndex);
*ppEnumUnknown = NULL;
if (pObject)
{
hr = pObject->QueryInterface(IID_PPV_ARG(IEnumUnknown, ppEnumUnknown));
pObject->Release();
}
else
{
hr = E_OUTOFMEMORY;
}
}
return hr;
}