Windows2003-3790/inetcore/outlookexpress/msoert/enumfmt.cpp
2020-09-30 16:53:55 +02:00

228 lines
5.0 KiB
C++

// --------------------------------------------------------------------------
// Enumfmt.cpp
// Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
// --------------------------------------------------------------------------
#include "pch.hxx"
#include "enumfmt.h"
#include <BadStrFunctions.h>
//////////////////////////////////////////////////////////////////////////////
//
// CEnumFormatEtc Implementation
//
//////////////////////////////////////////////////////////////////////////////
//
// COMMENTS:
// This class was designed and implemented by Kraig Brockschmidt in
// is book "Inside OLE2". See Chapter 6 "Uniform Data Transfer Using
// Data Objects" for more information.
//
// =================================================================================
// CreateStreamOnHFile
// =================================================================================
OESTDAPI_(HRESULT) CreateEnumFormatEtc(LPUNKNOWN pUnkRef, ULONG celt, PDATAOBJINFO rgInfo, LPFORMATETC rgfe,
IEnumFORMATETC ** lppstmHFile)
{
CEnumFormatEtc * pEnumFmt = NULL;
HRESULT hr = S_OK;
// Check the incoming params
if ((0 == pUnkRef) || (0 == lppstmHFile) || (0 == celt) || ((0 != rgInfo) && (0 != rgfe)))
{
hr = E_INVALIDARG;
goto exit;
}
// Initialize outgoing params
*lppstmHFile = NULL;
// Create the rules manager object
if (NULL != rgInfo)
{
pEnumFmt = new CEnumFormatEtc(pUnkRef, rgInfo, celt);
}
else
{
pEnumFmt = new CEnumFormatEtc(pUnkRef, celt, rgfe);
}
if (NULL == pEnumFmt)
{
hr = E_OUTOFMEMORY;
goto exit;
}
// Get the rules manager interface
hr = pEnumFmt->QueryInterface(IID_IEnumFORMATETC, (void **) lppstmHFile);
if (FAILED(hr))
{
goto exit;
}
pEnumFmt = NULL;
// Set the proper return value
hr = S_OK;
exit:
if (NULL != pEnumFmt)
{
delete pEnumFmt;
}
return hr;
}
CEnumFormatEtc::CEnumFormatEtc(LPUNKNOWN pUnkRef, PDATAOBJINFO rgInfo, ULONG celt)
{
UINT i;
m_cRef = 0;
m_pUnkRef = pUnkRef;
m_iCur = 0;
m_cfe = celt;
m_prgfe = new FORMATETC[(UINT) celt];
if (NULL != m_prgfe)
{
for (i = 0; i < celt; i++)
m_prgfe[i] = rgInfo[i].fe;
}
}
CEnumFormatEtc::CEnumFormatEtc(LPUNKNOWN pUnkRef, ULONG cFE, LPFORMATETC rgfe)
{
UINT i;
m_cRef = 0;
m_pUnkRef = pUnkRef;
m_iCur = 0;
m_cfe = cFE;
m_prgfe = new FORMATETC[(UINT) cFE];
if (NULL != m_prgfe)
{
for (i = 0; i < cFE; i++)
m_prgfe[i] = rgfe[i];
}
}
CEnumFormatEtc::~CEnumFormatEtc(void)
{
if (NULL != m_prgfe)
delete [] m_prgfe;
return;
}
STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID riid, LPVOID* ppv)
{
*ppv = NULL;
//
// Enumerators are separate objects, not the data object, so we
// only need to support our IUnknown and IEnumFORMATETC intefaces
// here with no concern for aggregation.
//
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumFORMATETC))
*ppv = (LPVOID) this;
if (NULL != *ppv)
{
((LPUNKNOWN) *ppv)->AddRef();
return (NOERROR);
}
return (ResultFromScode(E_NOINTERFACE));
}
STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
{
++m_cRef;
m_pUnkRef->AddRef();
return (m_cRef);
}
STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
{
ULONG cRefT;
cRefT = --m_cRef;
m_pUnkRef->Release();
if (0 == m_cRef)
delete this;
return (cRefT);
}
STDMETHODIMP CEnumFormatEtc::Next(ULONG cFE, LPFORMATETC pFE, ULONG* pulFE)
{
ULONG cReturn = 0L;
if (NULL == m_prgfe)
return (ResultFromScode(S_FALSE));
if (NULL != pulFE)
*pulFE = 0L;
if (NULL == pFE || m_iCur >= m_cfe)
return ResultFromScode(S_FALSE);
while (m_iCur < m_cfe && cFE > 0)
{
*pFE++ = m_prgfe[m_iCur++];
cReturn++;
cFE--;
}
if (NULL != pulFE)
*pulFE = cReturn;
return (NOERROR);
}
STDMETHODIMP CEnumFormatEtc::Skip(ULONG cSkip)
{
if (((m_iCur + cSkip) >= m_cfe) || NULL == m_prgfe)
return (ResultFromScode(S_FALSE));
m_iCur += cSkip;
return (NOERROR);
}
STDMETHODIMP CEnumFormatEtc::Reset(void)
{
m_iCur = 0;
return (NOERROR);
}
STDMETHODIMP CEnumFormatEtc::Clone(LPENUMFORMATETC* ppEnum)
{
CEnumFormatEtc* pNew;
*ppEnum = NULL;
// Create the clone.
pNew = new CEnumFormatEtc(m_pUnkRef, m_cfe, m_prgfe);
if (NULL == pNew)
return (ResultFromScode(E_OUTOFMEMORY));
pNew->AddRef();
pNew->m_iCur = m_iCur;
*ppEnum = pNew;
return (NOERROR);
}