1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XTDataObject.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dtrans.hxx"
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
37 #include <osl/diagnose.h>
39 #ifndef _TXDATAOBJECT_HXX_
40 #include "XTDataObject.hxx"
42 #include <com/sun/star/datatransfer/dataflavor.hpp>
43 #include "..\misc\ImplHelper.hxx"
44 #include "DTransHelper.hxx"
45 #include "TxtCnvtHlp.hxx"
46 #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
47 #include "FmtFilter.hxx"
50 #pragma warning(push,1)
51 #pragma warning(disable:4917)
60 #define __uuidof(I) IID_##I
63 //------------------------------------------------------------------------
64 // namespace directives
65 //------------------------------------------------------------------------
67 using namespace com::sun::star::datatransfer
;
68 using namespace com::sun::star::datatransfer::clipboard
;
69 using namespace com::sun::star::uno
;
70 using namespace com::sun::star::lang
;
73 //------------------------------------------------------------------------
74 // a helper class that will be thrown by the function validateFormatEtc
75 //------------------------------------------------------------------------
77 class CInvalidFormatEtcException
81 CInvalidFormatEtcException( HRESULT hr
) : m_hr( hr
) {};
84 //------------------------------------------------------------------------
86 //------------------------------------------------------------------------
88 CXTDataObject::CXTDataObject( const Reference
< XMultiServiceFactory
>& aServiceManager
,
89 const Reference
< XTransferable
>& aXTransferable
) :
91 m_SrvMgr( aServiceManager
),
92 m_XTransferable( aXTransferable
),
93 m_DataFormatTranslator( aServiceManager
),
94 m_bFormatEtcContainerInitialized( sal_False
),
95 m_FormatRegistrar( m_SrvMgr
, m_DataFormatTranslator
)
99 //------------------------------------------------------------------------
100 // IUnknown->QueryInterface
101 //------------------------------------------------------------------------
103 STDMETHODIMP
CXTDataObject::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
105 if ( NULL
== ppvObject
)
108 HRESULT hr
= E_NOINTERFACE
;
111 if ( ( __uuidof( IUnknown
) == iid
) ||
112 ( __uuidof( IDataObject
) == iid
) )
114 *ppvObject
= static_cast< IUnknown
* >( this );
115 ( (LPUNKNOWN
)*ppvObject
)->AddRef( );
122 //------------------------------------------------------------------------
124 //------------------------------------------------------------------------
126 STDMETHODIMP_(ULONG
) CXTDataObject::AddRef( )
128 return static_cast< ULONG
>( InterlockedIncrement( &m_nRefCnt
) );
131 //------------------------------------------------------------------------
133 //------------------------------------------------------------------------
135 STDMETHODIMP_(ULONG
) CXTDataObject::Release( )
138 static_cast< ULONG
>( InterlockedDecrement( &m_nRefCnt
) );
146 //------------------------------------------------------------------------
148 //------------------------------------------------------------------------
150 STDMETHODIMP
CXTDataObject::GetData( LPFORMATETC pFormatetc
, LPSTGMEDIUM pmedium
)
152 if ( !(pFormatetc
&& pmedium
) )
157 // prepare data transfer
158 invalidateStgMedium( *pmedium
);
159 validateFormatEtc( pFormatetc
);
161 // handle locale request, because locale is a artificial format for us
162 if ( CF_LOCALE
== pFormatetc
->cfFormat
)
163 renderLocaleAndSetupStgMedium( *pFormatetc
, *pmedium
);
164 else if ( CF_UNICODETEXT
== pFormatetc
->cfFormat
)
165 renderUnicodeAndSetupStgMedium( *pFormatetc
, *pmedium
);
167 renderAnyDataAndSetupStgMedium( *pFormatetc
, *pmedium
);
169 catch(UnsupportedFlavorException
&)
171 HRESULT hr
= DV_E_FORMATETC
;
173 if ( m_FormatRegistrar
.isSynthesizeableFormat( *pFormatetc
) )
174 hr
= renderSynthesizedFormatAndSetupStgMedium( *pFormatetc
, *pmedium
);
178 catch( CInvalidFormatEtcException
& ex
)
182 catch( CStgTransferHelper::CStgTransferException
& ex
)
184 return translateStgExceptionCode( ex
.m_hr
);
194 //------------------------------------------------------------------------
196 //------------------------------------------------------------------------
199 void SAL_CALL
CXTDataObject::renderDataAndSetupStgMedium(
200 const sal_Int8
* lpStorage
, const FORMATETC
& fetc
, sal_uInt32 nInitStgSize
,
201 sal_uInt32 nBytesToTransfer
, STGMEDIUM
& stgmedium
)
203 OSL_PRECOND( !nInitStgSize
|| nInitStgSize
&& (nInitStgSize
>= nBytesToTransfer
),
204 "Memory size less than number of bytes to transfer" );
206 CStgTransferHelper
stgTransfHelper( AUTO_INIT
);
208 // setup storage size
209 if ( nInitStgSize
> 0 )
210 stgTransfHelper
.init( nInitStgSize
, GHND
);
212 #if OSL_DEBUG_LEVEL > 0
213 sal_uInt32 nBytesWritten
= 0;
214 stgTransfHelper
.write( lpStorage
, nBytesToTransfer
, &nBytesWritten
);
215 OSL_ASSERT( nBytesWritten
== nBytesToTransfer
);
217 stgTransfHelper
.write( lpStorage
, nBytesToTransfer
);
220 setupStgMedium( fetc
, stgTransfHelper
, stgmedium
);
223 //------------------------------------------------------------------------
225 //------------------------------------------------------------------------
228 void SAL_CALL
CXTDataObject::renderLocaleAndSetupStgMedium(
229 FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
231 if ( m_FormatRegistrar
.hasSynthesizedLocale( ) )
233 LCID lcid
= m_FormatRegistrar
.getSynthesizedLocale( );
234 renderDataAndSetupStgMedium(
235 reinterpret_cast< sal_Int8
* >( &lcid
),
242 throw CInvalidFormatEtcException( DV_E_FORMATETC
);
245 //------------------------------------------------------------------------
247 //------------------------------------------------------------------------
250 void SAL_CALL
CXTDataObject::renderUnicodeAndSetupStgMedium(
251 FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
253 DataFlavor aFlavor
= formatEtcToDataFlavor( fetc
);
255 Any aAny
= m_XTransferable
->getTransferData( aFlavor
);
257 // unfortunately not all transferables fulfill the
258 // spec. an do throw an UnsupportedFlavorException
259 // so we must check the any
260 if ( !aAny
.hasValue( ) )
262 OSL_ENSURE( sal_False
, "XTransferable should throw an exception if ask for an unsupported flavor" );
263 throw UnsupportedFlavorException( );
269 sal_uInt32 nBytesToTransfer
= aText
.getLength( ) * sizeof( sal_Unicode
);
271 // to be sure there is an ending 0
272 sal_uInt32 nRequiredMemSize
= nBytesToTransfer
+ sizeof( sal_Unicode
);
274 renderDataAndSetupStgMedium(
275 reinterpret_cast< const sal_Int8
* >( aText
.getStr( ) ),
282 //------------------------------------------------------------------------
284 //------------------------------------------------------------------------
287 void SAL_CALL
CXTDataObject::renderAnyDataAndSetupStgMedium(
288 FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
290 DataFlavor aFlavor
= formatEtcToDataFlavor( fetc
);
292 Any aAny
= m_XTransferable
->getTransferData( aFlavor
);
294 // unfortunately not all transferables fulfill the
295 // spec. an do throw an UnsupportedFlavorException
296 // so we must check the any
297 if ( !aAny
.hasValue( ) )
299 OSL_ENSURE( sal_False
, "XTransferable should throw an exception if ask for an unsupported flavor" );
300 throw UnsupportedFlavorException( );
303 // unfortunately not all transferables fulfill the
304 // spec. an do throw an UnsupportedFlavorException
305 // so we must check the any
306 if ( !aAny
.hasValue( ) )
307 throw UnsupportedFlavorException( );
309 Sequence
< sal_Int8
> clipDataStream
;
310 aAny
>>= clipDataStream
;
312 sal_uInt32 nRequiredMemSize
= 0;
313 if ( m_DataFormatTranslator
.isOemOrAnsiTextFormat( fetc
.cfFormat
) )
314 nRequiredMemSize
= sizeof( sal_Int8
) * clipDataStream
.getLength( ) + 1;
316 // prepare data for transmision
317 if ( CF_DIB
== fetc
.cfFormat
)
318 clipDataStream
= OOBmpToWinDIB( clipDataStream
);
320 if ( CF_METAFILEPICT
== fetc
.cfFormat
)
322 stgmedium
.tymed
= TYMED_MFPICT
;
323 stgmedium
.hMetaFilePict
= OOMFPictToWinMFPict( clipDataStream
);
324 stgmedium
.pUnkForRelease
= NULL
;
326 else if( CF_ENHMETAFILE
== fetc
.cfFormat
)
328 stgmedium
.tymed
= TYMED_ENHMF
;
329 stgmedium
.hMetaFilePict
= OOMFPictToWinENHMFPict( clipDataStream
);
330 stgmedium
.pUnkForRelease
= NULL
;
333 renderDataAndSetupStgMedium(
334 clipDataStream
.getArray( ),
337 clipDataStream
.getLength( ),
341 //------------------------------------------------------------------------
343 //------------------------------------------------------------------------
345 HRESULT SAL_CALL
CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
351 if ( CF_UNICODETEXT
== fetc
.cfFormat
)
352 // the transferable seems to have only text
353 renderSynthesizedUnicodeAndSetupStgMedium( fetc
, stgmedium
);
354 else if ( m_DataFormatTranslator
.isOemOrAnsiTextFormat( fetc
.cfFormat
) )
355 // the transferable seems to have only unicode text
356 renderSynthesizedTextAndSetupStgMedium( fetc
, stgmedium
);
358 // the transferable seems to have only text/html
359 renderSynthesizedHtmlAndSetupStgMedium( fetc
, stgmedium
);
361 catch(UnsupportedFlavorException
&)
365 catch( CInvalidFormatEtcException
& )
367 OSL_ENSURE( sal_False
, "Unexpected exception" );
369 catch( CStgTransferHelper::CStgTransferException
& ex
)
371 return translateStgExceptionCode( ex
.m_hr
);
381 //------------------------------------------------------------------------
382 // the transferable must have only text, so we will synthesize unicode text
383 //------------------------------------------------------------------------
385 void SAL_CALL
CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
387 OSL_ASSERT( CF_UNICODETEXT
== fetc
.cfFormat
);
389 Any aAny
= m_XTransferable
->getTransferData( m_FormatRegistrar
.getRegisteredTextFlavor( ) );
391 // unfortunately not all transferables fulfill the
392 // spec. an do throw an UnsupportedFlavorException
393 // so we must check the any
394 if ( !aAny
.hasValue( ) )
396 OSL_ENSURE( sal_False
, "XTransferable should throw an exception if ask for an unsupported flavor" );
397 throw UnsupportedFlavorException( );
400 Sequence
< sal_Int8
> aText
;
403 CStgTransferHelper stgTransfHelper
;
405 MultiByteToWideCharEx(
406 m_FormatRegistrar
.getRegisteredTextCodePage( ),
407 reinterpret_cast< char* >( aText
.getArray( ) ),
411 setupStgMedium( fetc
, stgTransfHelper
, stgmedium
);
414 //------------------------------------------------------------------------
415 // the transferable must have only unicode text so we will sythesize text
416 //------------------------------------------------------------------------
418 void SAL_CALL
CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
420 OSL_ASSERT( m_DataFormatTranslator
.isOemOrAnsiTextFormat( fetc
.cfFormat
) );
422 DataFlavor aFlavor
= formatEtcToDataFlavor(
423 m_DataFormatTranslator
.getFormatEtcForClipformat( CF_UNICODETEXT
) );
425 Any aAny
= m_XTransferable
->getTransferData( aFlavor
);
427 // unfortunately not all transferables fulfill the
428 // spec. an do throw an UnsupportedFlavorException
429 // so we must check the any
430 if ( !aAny
.hasValue( ) )
432 OSL_ENSURE( sal_False
, "XTransferable should throw an exception if ask for an unsupported flavor" );
433 throw UnsupportedFlavorException( );
436 OUString aUnicodeText
;
437 aAny
>>= aUnicodeText
;
439 CStgTransferHelper stgTransfHelper
;
441 WideCharToMultiByteEx(
443 reinterpret_cast<LPCWSTR
>( aUnicodeText
.getStr( ) ),
444 aUnicodeText
.getLength( ),
447 setupStgMedium( fetc
, stgTransfHelper
, stgmedium
);
450 //------------------------------------------------------------------------
452 //------------------------------------------------------------------------
454 void SAL_CALL
CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
456 OSL_ASSERT( m_DataFormatTranslator
.isHTMLFormat( fetc
.cfFormat
) );
460 // creating a DataFlavor on the fly
461 aFlavor
.MimeType
= OUString::createFromAscii( "text/html" );
462 aFlavor
.DataType
= getCppuType( (Sequence
< sal_Int8
>*)0 );
464 Any aAny
= m_XTransferable
->getTransferData( aFlavor
);
466 // unfortunately not all transferables fulfill the
467 // spec. an do throw an UnsupportedFlavorException
468 // so we must check the any
469 if ( !aAny
.hasValue( ) )
471 OSL_ENSURE( sal_False
, "XTransferable should throw an exception if ask for an unsupported flavor" );
472 throw UnsupportedFlavorException( );
475 Sequence
< sal_Int8
> aTextHtmlSequence
;
476 aAny
>>= aTextHtmlSequence
;
478 Sequence
< sal_Int8
> aHTMLFormatSequence
= TextHtmlToHTMLFormat( aTextHtmlSequence
);
480 sal_uInt32 nBytesToTransfer
= aHTMLFormatSequence
.getLength( );
482 renderDataAndSetupStgMedium(
483 reinterpret_cast< const sal_Int8
* >( aHTMLFormatSequence
.getArray( ) ),
490 //------------------------------------------------------------------------
491 // IDataObject->EnumFormatEtc
492 //------------------------------------------------------------------------
494 STDMETHODIMP
CXTDataObject::EnumFormatEtc(
495 DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatetc
)
497 if ( NULL
== ppenumFormatetc
)
500 if ( DATADIR_SET
== dwDirection
)
503 *ppenumFormatetc
= NULL
;
505 InitializeFormatEtcContainer( );
508 if ( DATADIR_GET
== dwDirection
)
510 *ppenumFormatetc
= new CEnumFormatEtc( this, m_FormatEtcContainer
);
511 if ( NULL
!= *ppenumFormatetc
)
512 static_cast< LPUNKNOWN
>( *ppenumFormatetc
)->AddRef( );
514 hr
= ( NULL
!= *ppenumFormatetc
) ? S_OK
: E_OUTOFMEMORY
;
522 //------------------------------------------------------------------------
523 // IDataObject->QueryGetData
524 //------------------------------------------------------------------------
526 STDMETHODIMP
CXTDataObject::QueryGetData( LPFORMATETC pFormatetc
)
528 if ( (NULL
== pFormatetc
) || IsBadReadPtr( pFormatetc
, sizeof( FORMATETC
) ) )
531 InitializeFormatEtcContainer( );
533 return m_FormatEtcContainer
.hasFormatEtc( *pFormatetc
) ? S_OK
: S_FALSE
;
536 //------------------------------------------------------------------------
537 // IDataObject->GetDataHere
538 //------------------------------------------------------------------------
540 STDMETHODIMP
CXTDataObject::GetDataHere( LPFORMATETC
, LPSTGMEDIUM
)
545 //------------------------------------------------------------------------
546 // IDataObject->GetCanonicalFormatEtc
547 //------------------------------------------------------------------------
549 STDMETHODIMP
CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC
, LPFORMATETC
)
554 //------------------------------------------------------------------------
555 // IDataObject->SetData
556 //------------------------------------------------------------------------
558 STDMETHODIMP
CXTDataObject::SetData( LPFORMATETC
, LPSTGMEDIUM
, BOOL
)
563 //------------------------------------------------------------------------
564 // IDataObject->DAdvise
565 //------------------------------------------------------------------------
567 STDMETHODIMP
CXTDataObject::DAdvise( LPFORMATETC
, DWORD
, LPADVISESINK
, DWORD
* )
572 //------------------------------------------------------------------------
573 // IDataObject->DUnadvise
574 //------------------------------------------------------------------------
576 STDMETHODIMP
CXTDataObject::DUnadvise( DWORD
)
581 //------------------------------------------------------------------------
582 // IDataObject->EnumDAdvise
583 //------------------------------------------------------------------------
585 STDMETHODIMP
CXTDataObject::EnumDAdvise( LPENUMSTATDATA
* )
590 //------------------------------------------------------------------------
591 // for our convenience
592 //------------------------------------------------------------------------
594 CXTDataObject::operator IDataObject
*( )
596 return static_cast< IDataObject
* >( this );
599 //------------------------------------------------------------------------
601 //------------------------------------------------------------------------
604 DataFlavor SAL_CALL
CXTDataObject::formatEtcToDataFlavor( const FORMATETC
& aFormatEtc
) const
608 if ( m_FormatRegistrar
.hasSynthesizedLocale( ) )
610 m_DataFormatTranslator
.getDataFlavorFromFormatEtc( aFormatEtc
, m_FormatRegistrar
.getSynthesizedLocale( ) );
612 aFlavor
= m_DataFormatTranslator
.getDataFlavorFromFormatEtc( aFormatEtc
);
614 if ( !aFlavor
.MimeType
.getLength( ) )
615 throw UnsupportedFlavorException( );
620 //------------------------------------------------------------------------
622 //------------------------------------------------------------------------
625 void CXTDataObject::validateFormatEtc( LPFORMATETC lpFormatEtc
) const
627 OSL_ASSERT( lpFormatEtc
);
629 if ( lpFormatEtc
->lindex
!= -1 )
630 throw CInvalidFormatEtcException( DV_E_LINDEX
);
632 if ( !(lpFormatEtc
->dwAspect
& DVASPECT_CONTENT
) &&
633 !(lpFormatEtc
->dwAspect
& DVASPECT_SHORTNAME
) )
634 throw CInvalidFormatEtcException( DV_E_DVASPECT
);
636 if ( !(lpFormatEtc
->tymed
& TYMED_HGLOBAL
) &&
637 !(lpFormatEtc
->tymed
& TYMED_ISTREAM
) &&
638 !(lpFormatEtc
->tymed
& TYMED_MFPICT
) &&
639 !(lpFormatEtc
->tymed
& TYMED_ENHMF
) )
640 throw CInvalidFormatEtcException( DV_E_TYMED
);
642 if ( lpFormatEtc
->cfFormat
== CF_METAFILEPICT
&&
643 !(lpFormatEtc
->tymed
& TYMED_MFPICT
) )
644 throw CInvalidFormatEtcException( DV_E_TYMED
);
646 if ( lpFormatEtc
->cfFormat
== CF_ENHMETAFILE
&&
647 !(lpFormatEtc
->tymed
& TYMED_ENHMF
) )
648 throw CInvalidFormatEtcException( DV_E_TYMED
);
651 //------------------------------------------------------------------------
653 //------------------------------------------------------------------------
656 void SAL_CALL
CXTDataObject::setupStgMedium( const FORMATETC
& fetc
,
657 CStgTransferHelper
& stgTransHlp
,
658 STGMEDIUM
& stgmedium
)
660 stgmedium
.pUnkForRelease
= NULL
;
662 if ( fetc
.cfFormat
== CF_METAFILEPICT
)
664 stgmedium
.tymed
= TYMED_MFPICT
;
665 stgmedium
.hMetaFilePict
= static_cast< HMETAFILEPICT
>( stgTransHlp
.getHGlobal( ) );
667 else if ( fetc
.cfFormat
== CF_ENHMETAFILE
)
669 stgmedium
.tymed
= TYMED_ENHMF
;
670 stgmedium
.hEnhMetaFile
= static_cast< HENHMETAFILE
>( stgTransHlp
.getHGlobal( ) );
672 else if ( fetc
.tymed
& TYMED_HGLOBAL
)
674 stgmedium
.tymed
= TYMED_HGLOBAL
;
675 stgmedium
.hGlobal
= stgTransHlp
.getHGlobal( );
677 else if ( fetc
.tymed
& TYMED_ISTREAM
)
679 stgmedium
.tymed
= TYMED_ISTREAM
;
680 stgTransHlp
.getIStream( &stgmedium
.pstm
);
683 OSL_ASSERT( sal_False
);
686 //------------------------------------------------------------------------
688 //------------------------------------------------------------------------
691 void SAL_CALL
CXTDataObject::invalidateStgMedium( STGMEDIUM
& stgmedium
) const
693 stgmedium
.tymed
= TYMED_NULL
;
696 //------------------------------------------------------------------------
698 //------------------------------------------------------------------------
701 HRESULT SAL_CALL
CXTDataObject::translateStgExceptionCode( HRESULT hr
) const
707 case STG_E_MEDIUMFULL
:
712 hrTransl
= E_UNEXPECTED
;
719 //------------------------------------------------------------------------
721 //------------------------------------------------------------------------
723 inline void SAL_CALL
CXTDataObject::InitializeFormatEtcContainer( )
725 if ( !m_bFormatEtcContainerInitialized
)
727 m_FormatRegistrar
.RegisterFormats( m_XTransferable
, m_FormatEtcContainer
);
728 m_bFormatEtcContainerInitialized
= sal_True
;
732 //============================================================================
734 //============================================================================
736 //----------------------------------------------------------------------------
738 //----------------------------------------------------------------------------
740 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter
, const CFormatEtcContainer
& aFormatEtcContainer
) :
742 m_lpUnkOuter( lpUnkOuter
),
743 m_FormatEtcContainer( aFormatEtcContainer
)
748 //----------------------------------------------------------------------------
749 // IUnknown->QueryInterface
750 //----------------------------------------------------------------------------
752 STDMETHODIMP
CEnumFormatEtc::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
754 if ( NULL
== ppvObject
)
757 HRESULT hr
= E_NOINTERFACE
;
761 if ( ( __uuidof( IUnknown
) == iid
) ||
762 ( __uuidof( IEnumFORMATETC
) == iid
) )
764 *ppvObject
= static_cast< IUnknown
* >( this );
765 static_cast< LPUNKNOWN
>( *ppvObject
)->AddRef( );
772 //----------------------------------------------------------------------------
774 //----------------------------------------------------------------------------
776 STDMETHODIMP_(ULONG
) CEnumFormatEtc::AddRef( )
778 // keep the dataobject alive
779 m_lpUnkOuter
->AddRef( );
780 return InterlockedIncrement( &m_nRefCnt
);
783 //----------------------------------------------------------------------------
785 //----------------------------------------------------------------------------
787 STDMETHODIMP_(ULONG
) CEnumFormatEtc::Release( )
789 // release the outer dataobject
790 m_lpUnkOuter
->Release( );
792 ULONG nRefCnt
= InterlockedDecrement( &m_nRefCnt
);
799 //----------------------------------------------------------------------------
800 // IEnumFORMATETC->Next
801 //----------------------------------------------------------------------------
803 STDMETHODIMP
CEnumFormatEtc::Next( ULONG nRequested
, LPFORMATETC lpDest
, ULONG
* lpFetched
)
805 if ( ( nRequested
< 1 ) ||
806 (( nRequested
> 1 ) && ( NULL
== lpFetched
)) ||
807 IsBadWritePtr( lpDest
, sizeof( FORMATETC
) * nRequested
) )
810 sal_uInt32 nFetched
= m_FormatEtcContainer
.nextFormatEtc( lpDest
, nRequested
);
812 if ( NULL
!= lpFetched
)
813 *lpFetched
= nFetched
;
815 return (nFetched
== nRequested
) ? S_OK
: S_FALSE
;
818 //----------------------------------------------------------------------------
819 // IEnumFORMATETC->Skip
820 //----------------------------------------------------------------------------
822 STDMETHODIMP
CEnumFormatEtc::Skip( ULONG celt
)
824 return m_FormatEtcContainer
.skipFormatEtc( celt
) ? S_OK
: S_FALSE
;
827 //----------------------------------------------------------------------------
828 // IEnumFORMATETC->Reset
829 //----------------------------------------------------------------------------
831 STDMETHODIMP
CEnumFormatEtc::Reset( )
833 m_FormatEtcContainer
.beginEnumFormatEtc( );
837 //----------------------------------------------------------------------------
838 // IEnumFORMATETC->Clone
839 //----------------------------------------------------------------------------
841 STDMETHODIMP
CEnumFormatEtc::Clone( IEnumFORMATETC
** ppenum
)
843 if ( NULL
== ppenum
)
846 *ppenum
= new CEnumFormatEtc( m_lpUnkOuter
, m_FormatEtcContainer
);
847 if ( NULL
!= ppenum
)
848 static_cast< LPUNKNOWN
>( *ppenum
)->AddRef( );
850 return ( NULL
!= *ppenum
) ? S_OK
: E_OUTOFMEMORY
;