fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / dtrans / source / win32 / dtobj / XTDataObject.cxx
blob3c8a93731945cb5a6fcf951267fa527051aeff8f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/diagnose.h>
22 #include "XTDataObject.hxx"
23 #include <com/sun/star/datatransfer/DataFlavor.hpp>
24 #include "../misc/ImplHelper.hxx"
25 #include "DTransHelper.hxx"
26 #include "TxtCnvtHlp.hxx"
27 #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
28 #include "FmtFilter.hxx"
29 #include <comphelper/processfactory.hxx>
31 #if defined _MSC_VER
32 #pragma warning(push,1)
33 #pragma warning(disable:4917)
34 #endif
35 #include <windows.h>
36 #include <shlobj.h>
37 #if defined _MSC_VER
38 #pragma warning(pop)
39 #endif
41 #ifdef __MINGW32__
42 #if defined __uuidof
43 #undef __uuidof
44 #endif
45 #define __uuidof(I) IID_##I
46 #endif
48 // namespace directives
50 using namespace com::sun::star::datatransfer;
51 using namespace com::sun::star::datatransfer::clipboard;
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::lang;
55 // a helper class that will be thrown by the function validateFormatEtc
57 class CInvalidFormatEtcException
59 public:
60 HRESULT m_hr;
61 CInvalidFormatEtcException( HRESULT hr ) : m_hr( hr ) {};
64 // ctor
66 CXTDataObject::CXTDataObject( const Reference< XComponentContext >& rxContext,
67 const Reference< XTransferable >& aXTransferable )
68 : m_nRefCnt( 0 )
69 , m_XTransferable( aXTransferable )
70 , m_bFormatEtcContainerInitialized( sal_False )
71 , m_DataFormatTranslator( rxContext )
72 , m_FormatRegistrar( rxContext, m_DataFormatTranslator )
76 // IUnknown->QueryInterface
78 STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
80 if ( NULL == ppvObject )
81 return E_INVALIDARG;
83 HRESULT hr = E_NOINTERFACE;
85 *ppvObject = NULL;
86 if ( ( __uuidof( IUnknown ) == iid ) ||
87 ( __uuidof( IDataObject ) == iid ) )
89 *ppvObject = static_cast< IUnknown* >( this );
90 ( (LPUNKNOWN)*ppvObject )->AddRef( );
91 hr = S_OK;
94 return hr;
97 // IUnknown->AddRef
99 STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
101 return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
104 // IUnknown->Release
106 STDMETHODIMP_(ULONG) CXTDataObject::Release( )
108 ULONG nRefCnt =
109 static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
111 if ( 0 == nRefCnt )
112 delete this;
114 return nRefCnt;
117 STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
119 if ( !(pFormatetc && pmedium) )
120 return E_INVALIDARG;
124 // prepare data transfer
125 invalidateStgMedium( *pmedium );
126 validateFormatEtc( pFormatetc );
128 // handle locale request, because locale is a artificial format for us
129 if ( CF_LOCALE == pFormatetc->cfFormat )
130 renderLocaleAndSetupStgMedium( *pFormatetc, *pmedium );
131 else if ( CF_UNICODETEXT == pFormatetc->cfFormat )
132 renderUnicodeAndSetupStgMedium( *pFormatetc, *pmedium );
133 else
134 renderAnyDataAndSetupStgMedium( *pFormatetc, *pmedium );
136 catch(UnsupportedFlavorException&)
138 HRESULT hr = DV_E_FORMATETC;
140 if ( m_FormatRegistrar.isSynthesizeableFormat( *pFormatetc ) )
141 hr = renderSynthesizedFormatAndSetupStgMedium( *pFormatetc, *pmedium );
143 return hr;
145 catch( CInvalidFormatEtcException& ex )
147 return ex.m_hr;
149 catch( CStgTransferHelper::CStgTransferException& ex )
151 return translateStgExceptionCode( ex.m_hr );
153 catch(...)
155 return E_UNEXPECTED;
158 return S_OK;
161 // inline
162 void SAL_CALL CXTDataObject::renderDataAndSetupStgMedium(
163 const sal_Int8* lpStorage, const FORMATETC& fetc, sal_uInt32 nInitStgSize,
164 sal_uInt32 nBytesToTransfer, STGMEDIUM& stgmedium )
166 OSL_PRECOND( !nInitStgSize || nInitStgSize && (nInitStgSize >= nBytesToTransfer),
167 "Memory size less than number of bytes to transfer" );
169 CStgTransferHelper stgTransfHelper( AUTO_INIT );
171 // setup storage size
172 if ( nInitStgSize > 0 )
173 stgTransfHelper.init( nInitStgSize, GHND );
175 #if OSL_DEBUG_LEVEL > 0
176 sal_uInt32 nBytesWritten = 0;
177 stgTransfHelper.write( lpStorage, nBytesToTransfer, &nBytesWritten );
178 OSL_ASSERT( nBytesWritten == nBytesToTransfer );
179 #else
180 stgTransfHelper.write( lpStorage, nBytesToTransfer );
181 #endif
183 setupStgMedium( fetc, stgTransfHelper, stgmedium );
186 //inline
187 void SAL_CALL CXTDataObject::renderLocaleAndSetupStgMedium(
188 FORMATETC& fetc, STGMEDIUM& stgmedium )
190 if ( m_FormatRegistrar.hasSynthesizedLocale( ) )
192 LCID lcid = m_FormatRegistrar.getSynthesizedLocale( );
193 renderDataAndSetupStgMedium(
194 reinterpret_cast< sal_Int8* >( &lcid ),
195 fetc,
197 sizeof( LCID ),
198 stgmedium );
200 else
201 throw CInvalidFormatEtcException( DV_E_FORMATETC );
204 //inline
205 void SAL_CALL CXTDataObject::renderUnicodeAndSetupStgMedium(
206 FORMATETC& fetc, STGMEDIUM& stgmedium )
208 DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
210 Any aAny = m_XTransferable->getTransferData( aFlavor );
212 // unfortunately not all transferables fulfill the
213 // spec. an do throw an UnsupportedFlavorException
214 // so we must check the any
215 if ( !aAny.hasValue( ) )
217 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
218 throw UnsupportedFlavorException( );
221 OUString aText;
222 aAny >>= aText;
224 sal_uInt32 nBytesToTransfer = aText.getLength( ) * sizeof( sal_Unicode );
226 // to be sure there is an ending 0
227 sal_uInt32 nRequiredMemSize = nBytesToTransfer + sizeof( sal_Unicode );
229 renderDataAndSetupStgMedium(
230 reinterpret_cast< const sal_Int8* >( aText.getStr( ) ),
231 fetc,
232 nRequiredMemSize,
233 nBytesToTransfer,
234 stgmedium );
237 //inline
238 void SAL_CALL CXTDataObject::renderAnyDataAndSetupStgMedium(
239 FORMATETC& fetc, STGMEDIUM& stgmedium )
241 DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
243 Any aAny = m_XTransferable->getTransferData( aFlavor );
245 // unfortunately not all transferables fulfill the
246 // spec. an do throw an UnsupportedFlavorException
247 // so we must check the any
248 if ( !aAny.hasValue( ) )
250 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
251 throw UnsupportedFlavorException( );
254 // unfortunately not all transferables fulfill the
255 // spec. an do throw an UnsupportedFlavorException
256 // so we must check the any
257 if ( !aAny.hasValue( ) )
258 throw UnsupportedFlavorException( );
260 Sequence< sal_Int8 > clipDataStream;
261 aAny >>= clipDataStream;
263 sal_uInt32 nRequiredMemSize = 0;
264 if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) )
265 nRequiredMemSize = sizeof( sal_Int8 ) * clipDataStream.getLength( ) + 1;
267 // prepare data for transmision
268 // #i124085# DIBV5 should not happen for now, but keep as hint here
269 if ( CF_DIBV5 == fetc.cfFormat || CF_DIB == fetc.cfFormat )
271 #ifdef DBG_UTIL
272 if(CF_DIBV5 == fetc.cfFormat)
274 OSL_ENSURE(clipDataStream.getLength( ) > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPV5HEADER)), "Wrong size on CF_DIBV5 data (!)");
276 else // CF_DIB == fetc.cfFormat
278 OSL_ENSURE(clipDataStream.getLength( ) > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)), "Wrong size on CF_DIB data (!)");
280 #endif
282 // remove BITMAPFILEHEADER
283 clipDataStream = OOBmpToWinDIB( clipDataStream );
286 if ( CF_METAFILEPICT == fetc.cfFormat )
288 stgmedium.tymed = TYMED_MFPICT;
289 stgmedium.hMetaFilePict = OOMFPictToWinMFPict( clipDataStream );
290 stgmedium.pUnkForRelease = NULL;
292 else if( CF_ENHMETAFILE == fetc.cfFormat )
294 stgmedium.tymed = TYMED_ENHMF;
295 stgmedium.hMetaFilePict = OOMFPictToWinENHMFPict( clipDataStream );
296 stgmedium.pUnkForRelease = NULL;
298 else
299 renderDataAndSetupStgMedium(
300 clipDataStream.getArray( ),
301 fetc,
302 nRequiredMemSize,
303 clipDataStream.getLength( ),
304 stgmedium );
307 HRESULT SAL_CALL CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
309 HRESULT hr = S_OK;
313 if ( CF_UNICODETEXT == fetc.cfFormat )
314 // the transferable seems to have only text
315 renderSynthesizedUnicodeAndSetupStgMedium( fetc, stgmedium );
316 else if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) )
317 // the transferable seems to have only unicode text
318 renderSynthesizedTextAndSetupStgMedium( fetc, stgmedium );
319 else
320 // the transferable seems to have only text/html
321 renderSynthesizedHtmlAndSetupStgMedium( fetc, stgmedium );
323 catch(UnsupportedFlavorException&)
325 hr = DV_E_FORMATETC;
327 catch( CInvalidFormatEtcException& )
329 OSL_FAIL( "Unexpected exception" );
331 catch( CStgTransferHelper::CStgTransferException& ex )
333 return translateStgExceptionCode( ex.m_hr );
335 catch(...)
337 hr = E_UNEXPECTED;
340 return hr;
343 // the transferable must have only text, so we will synthesize unicode text
345 void SAL_CALL CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
347 OSL_ASSERT( CF_UNICODETEXT == fetc.cfFormat );
349 Any aAny = m_XTransferable->getTransferData( m_FormatRegistrar.getRegisteredTextFlavor( ) );
351 // unfortunately not all transferables fulfill the
352 // spec. an do throw an UnsupportedFlavorException
353 // so we must check the any
354 if ( !aAny.hasValue( ) )
356 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
357 throw UnsupportedFlavorException( );
360 Sequence< sal_Int8 > aText;
361 aAny >>= aText;
363 CStgTransferHelper stgTransfHelper;
365 MultiByteToWideCharEx(
366 m_FormatRegistrar.getRegisteredTextCodePage( ),
367 reinterpret_cast< char* >( aText.getArray( ) ),
368 aText.getLength( ),
369 stgTransfHelper );
371 setupStgMedium( fetc, stgTransfHelper, stgmedium );
374 // the transferable must have only unicode text so we will sythesize text
376 void SAL_CALL CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
378 OSL_ASSERT( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) );
380 DataFlavor aFlavor = formatEtcToDataFlavor(
381 m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) );
383 Any aAny = m_XTransferable->getTransferData( aFlavor );
385 // unfortunately not all transferables fulfill the
386 // spec. an do throw an UnsupportedFlavorException
387 // so we must check the any
388 if ( !aAny.hasValue( ) )
390 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
391 throw UnsupportedFlavorException( );
394 OUString aUnicodeText;
395 aAny >>= aUnicodeText;
397 CStgTransferHelper stgTransfHelper;
399 WideCharToMultiByteEx(
400 GetACP( ),
401 reinterpret_cast<LPCWSTR>( aUnicodeText.getStr( ) ),
402 aUnicodeText.getLength( ),
403 stgTransfHelper );
405 setupStgMedium( fetc, stgTransfHelper, stgmedium );
408 void SAL_CALL CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
410 OSL_ASSERT( m_DataFormatTranslator.isHTMLFormat( fetc.cfFormat ) );
412 DataFlavor aFlavor;
414 // creating a DataFlavor on the fly
415 aFlavor.MimeType = "text/html";
416 aFlavor.DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
418 Any aAny = m_XTransferable->getTransferData( aFlavor );
420 // unfortunately not all transferables fulfill the
421 // spec. an do throw an UnsupportedFlavorException
422 // so we must check the any
423 if ( !aAny.hasValue( ) )
425 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
426 throw UnsupportedFlavorException( );
429 Sequence< sal_Int8 > aTextHtmlSequence;
430 aAny >>= aTextHtmlSequence;
432 Sequence< sal_Int8 > aHTMLFormatSequence = TextHtmlToHTMLFormat( aTextHtmlSequence );
434 sal_uInt32 nBytesToTransfer = aHTMLFormatSequence.getLength( );
436 renderDataAndSetupStgMedium(
437 reinterpret_cast< const sal_Int8* >( aHTMLFormatSequence.getArray( ) ),
438 fetc,
440 nBytesToTransfer,
441 stgmedium );
444 // IDataObject->EnumFormatEtc
446 STDMETHODIMP CXTDataObject::EnumFormatEtc(
447 DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
449 if ( NULL == ppenumFormatetc )
450 return E_INVALIDARG;
452 if ( DATADIR_SET == dwDirection )
453 return E_NOTIMPL;
455 *ppenumFormatetc = NULL;
457 InitializeFormatEtcContainer( );
459 HRESULT hr;
460 if ( DATADIR_GET == dwDirection )
462 *ppenumFormatetc = new CEnumFormatEtc( this, m_FormatEtcContainer );
463 static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
465 hr = S_OK;
467 else
468 hr = E_INVALIDARG;
470 return hr;
473 // IDataObject->QueryGetData
475 STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
477 if ( (NULL == pFormatetc) || IsBadReadPtr( pFormatetc, sizeof( FORMATETC ) ) )
478 return E_INVALIDARG;
480 InitializeFormatEtcContainer( );
482 return m_FormatEtcContainer.hasFormatEtc( *pFormatetc ) ? S_OK : S_FALSE;
485 // IDataObject->GetDataHere
487 STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
489 return E_NOTIMPL;
492 // IDataObject->GetCanonicalFormatEtc
494 STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
496 return E_NOTIMPL;
499 // IDataObject->SetData
501 STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
503 return E_NOTIMPL;
506 // IDataObject->DAdvise
508 STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
510 return E_NOTIMPL;
513 // IDataObject->DUnadvise
515 STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
517 return E_NOTIMPL;
520 // IDataObject->EnumDAdvise
522 STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
524 return E_NOTIMPL;
527 // for our convenience
529 CXTDataObject::operator IDataObject*( )
531 return static_cast< IDataObject* >( this );
534 inline
535 DataFlavor SAL_CALL CXTDataObject::formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const
537 DataFlavor aFlavor;
539 if ( m_FormatRegistrar.hasSynthesizedLocale( ) )
540 aFlavor =
541 m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, m_FormatRegistrar.getSynthesizedLocale( ) );
542 else
543 aFlavor = m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc );
545 if ( !aFlavor.MimeType.getLength( ) )
546 throw UnsupportedFlavorException( );
548 return aFlavor;
551 inline
552 void CXTDataObject::validateFormatEtc( LPFORMATETC lpFormatEtc ) const
554 OSL_ASSERT( lpFormatEtc );
556 if ( lpFormatEtc->lindex != -1 )
557 throw CInvalidFormatEtcException( DV_E_LINDEX );
559 if ( !(lpFormatEtc->dwAspect & DVASPECT_CONTENT) &&
560 !(lpFormatEtc->dwAspect & DVASPECT_SHORTNAME) )
561 throw CInvalidFormatEtcException( DV_E_DVASPECT );
563 if ( !(lpFormatEtc->tymed & TYMED_HGLOBAL) &&
564 !(lpFormatEtc->tymed & TYMED_ISTREAM) &&
565 !(lpFormatEtc->tymed & TYMED_MFPICT) &&
566 !(lpFormatEtc->tymed & TYMED_ENHMF) )
567 throw CInvalidFormatEtcException( DV_E_TYMED );
569 if ( lpFormatEtc->cfFormat == CF_METAFILEPICT &&
570 !(lpFormatEtc->tymed & TYMED_MFPICT) )
571 throw CInvalidFormatEtcException( DV_E_TYMED );
573 if ( lpFormatEtc->cfFormat == CF_ENHMETAFILE &&
574 !(lpFormatEtc->tymed & TYMED_ENHMF) )
575 throw CInvalidFormatEtcException( DV_E_TYMED );
578 //inline
579 void SAL_CALL CXTDataObject::setupStgMedium( const FORMATETC& fetc,
580 CStgTransferHelper& stgTransHlp,
581 STGMEDIUM& stgmedium )
583 stgmedium.pUnkForRelease = NULL;
585 if ( fetc.cfFormat == CF_METAFILEPICT )
587 stgmedium.tymed = TYMED_MFPICT;
588 stgmedium.hMetaFilePict = static_cast< HMETAFILEPICT >( stgTransHlp.getHGlobal( ) );
590 else if ( fetc.cfFormat == CF_ENHMETAFILE )
592 stgmedium.tymed = TYMED_ENHMF;
593 stgmedium.hEnhMetaFile = static_cast< HENHMETAFILE >( stgTransHlp.getHGlobal( ) );
595 else if ( fetc.tymed & TYMED_HGLOBAL )
597 stgmedium.tymed = TYMED_HGLOBAL;
598 stgmedium.hGlobal = stgTransHlp.getHGlobal( );
600 else if ( fetc.tymed & TYMED_ISTREAM )
602 stgmedium.tymed = TYMED_ISTREAM;
603 stgTransHlp.getIStream( &stgmedium.pstm );
605 else
606 OSL_ASSERT( sal_False );
609 inline
610 void SAL_CALL CXTDataObject::invalidateStgMedium( STGMEDIUM& stgmedium ) const
612 stgmedium.tymed = TYMED_NULL;
615 inline
616 HRESULT SAL_CALL CXTDataObject::translateStgExceptionCode( HRESULT hr ) const
618 HRESULT hrTransl;
620 switch( hr )
622 case STG_E_MEDIUMFULL:
623 hrTransl = hr;
624 break;
626 default:
627 hrTransl = E_UNEXPECTED;
628 break;
631 return hrTransl;
634 inline void SAL_CALL CXTDataObject::InitializeFormatEtcContainer( )
636 if ( !m_bFormatEtcContainerInitialized )
638 m_FormatRegistrar.RegisterFormats( m_XTransferable, m_FormatEtcContainer );
639 m_bFormatEtcContainerInitialized = sal_True;
643 // CEnumFormatEtc
645 // ctor
647 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer ) :
648 m_nRefCnt( 0 ),
649 m_lpUnkOuter( lpUnkOuter ),
650 m_FormatEtcContainer( aFormatEtcContainer )
652 Reset( );
655 // IUnknown->QueryInterface
657 STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
659 if ( NULL == ppvObject )
660 return E_INVALIDARG;
662 HRESULT hr = E_NOINTERFACE;
664 *ppvObject = NULL;
666 if ( ( __uuidof( IUnknown ) == iid ) ||
667 ( __uuidof( IEnumFORMATETC ) == iid ) )
669 *ppvObject = static_cast< IUnknown* >( this );
670 static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
671 hr = S_OK;
674 return hr;
677 // IUnknown->AddRef
679 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
681 // keep the dataobject alive
682 m_lpUnkOuter->AddRef( );
683 return InterlockedIncrement( &m_nRefCnt );
686 // IUnknown->Release
688 STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
690 // release the outer dataobject
691 m_lpUnkOuter->Release( );
693 ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
694 if ( 0 == nRefCnt )
695 delete this;
697 return nRefCnt;
700 // IEnumFORMATETC->Next
702 STDMETHODIMP CEnumFormatEtc::Next( ULONG nRequested, LPFORMATETC lpDest, ULONG* lpFetched )
704 if ( ( nRequested < 1 ) ||
705 (( nRequested > 1 ) && ( NULL == lpFetched )) ||
706 IsBadWritePtr( lpDest, sizeof( FORMATETC ) * nRequested ) )
707 return E_INVALIDARG;
709 sal_uInt32 nFetched = m_FormatEtcContainer.nextFormatEtc( lpDest, nRequested );
711 if ( NULL != lpFetched )
712 *lpFetched = nFetched;
714 return (nFetched == nRequested) ? S_OK : S_FALSE;
717 // IEnumFORMATETC->Skip
719 STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
721 return m_FormatEtcContainer.skipFormatEtc( celt ) ? S_OK : S_FALSE;
724 // IEnumFORMATETC->Reset
726 STDMETHODIMP CEnumFormatEtc::Reset( )
728 m_FormatEtcContainer.beginEnumFormatEtc( );
729 return S_OK;
732 // IEnumFORMATETC->Clone
734 STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
736 if ( NULL == ppenum )
737 return E_INVALIDARG;
739 *ppenum = new CEnumFormatEtc( m_lpUnkOuter, m_FormatEtcContainer );
740 static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
742 return S_OK;
745 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */