//+------------------------------------------------------------------------- // // 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; }