windows-nt/Source/XPSP1/NT/shell/ext/cscui/fmtetc.cpp
2020-09-26 16:20:57 +08:00

186 lines
3.2 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: fmtetc.cpp
//
//--------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "fmtetc.h"
CEnumFormatEtc::CEnumFormatEtc(
UINT cFormats,
LPFORMATETC prgFormats
) : m_cRef(0),
m_cFormats(0),
m_iCurrent(0),
m_prgFormats(NULL),
m_hrCtor(NOERROR)
{
m_hrCtor = AddFormats(cFormats, prgFormats);
}
CEnumFormatEtc::CEnumFormatEtc(
const CEnumFormatEtc& ef
) : m_cRef(0),
m_cFormats(0),
m_iCurrent(0),
m_prgFormats(NULL),
m_hrCtor(NOERROR)
{
m_hrCtor = AddFormats(ef.m_cFormats, ef.m_prgFormats);
}
CEnumFormatEtc::~CEnumFormatEtc(
VOID
)
{
delete[] m_prgFormats;
}
STDMETHODIMP
CEnumFormatEtc::QueryInterface(
REFIID riid,
LPVOID *ppv
)
{
static const QITAB qit[] = {
QITABENT(CEnumFormatEtc, IEnumFORMATETC),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG)
CEnumFormatEtc::AddRef(
VOID
)
{
InterlockedIncrement(&m_cRef);
return m_cRef;
}
STDMETHODIMP_(ULONG)
CEnumFormatEtc::Release(
VOID
)
{
if (0 != InterlockedDecrement(&m_cRef))
return m_cRef;
delete this;
return 0;
}
STDMETHODIMP
CEnumFormatEtc::Next(
DWORD cFormats,
LPFORMATETC pFormats,
LPDWORD pcReturned
)
{
HRESULT hr = S_OK;
DWORD iFormats = 0;
if (NULL == pFormats)
return E_INVALIDARG;
while(cFormats-- > 0)
{
if (m_iCurrent < m_cFormats)
{
*(pFormats + iFormats++) = m_prgFormats[m_iCurrent++];
}
else
{
hr = S_FALSE;
break;
}
}
if (NULL != pcReturned)
*pcReturned = iFormats;
return hr;
}
STDMETHODIMP
CEnumFormatEtc::Skip(
DWORD cFormats
)
{
while((cFormats-- > 0) && (m_iCurrent < m_cFormats))
m_iCurrent++;
return cFormats == 0 ? S_OK : S_FALSE;
}
STDMETHODIMP
CEnumFormatEtc::Reset(
VOID
)
{
m_iCurrent = 0;
return S_OK;
}
STDMETHODIMP
CEnumFormatEtc::Clone(
IEnumFORMATETC **ppvOut
)
{
HRESULT hr = E_OUTOFMEMORY;
CEnumFormatEtc *pNew = new CEnumFormatEtc(*this);
if (NULL != pNew)
{
hr = pNew->QueryInterface(IID_IEnumFORMATETC, (LPVOID *)ppvOut);
}
return hr;
}
HRESULT
CEnumFormatEtc::AddFormats(
UINT cFormats,
LPFORMATETC pFormats
)
{
HRESULT hr = E_OUTOFMEMORY;
LPFORMATETC pNew = new FORMATETC[m_cFormats + cFormats];
if (NULL != pNew)
{
FORMATETC *pSrc = m_prgFormats;
FORMATETC *pDest = pNew;
int i;
for (i = 0; i < m_cFormats; i++)
{
*pDest++ = *pSrc++; // Copy original formats.
}
pSrc = pFormats;
for (i = 0; i < int(cFormats); i++)
{
*pDest++ = *pSrc++; // Add new formats.
}
delete[] m_prgFormats;
m_cFormats += cFormats;
m_prgFormats = pNew;
hr = NOERROR;
}
return hr;
}