xref: /AOO41X/main/dtrans/source/win32/dtobj/XTDataObject.cxx (revision 45fd3b9abd7258384488f2747dad7bc0899f1720)
148123e16SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
348123e16SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
448123e16SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
548123e16SAndrew Rist  * distributed with this work for additional information
648123e16SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
748123e16SAndrew Rist  * to you under the Apache License, Version 2.0 (the
848123e16SAndrew Rist  * "License"); you may not use this file except in compliance
948123e16SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
1148123e16SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
1348123e16SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1448123e16SAndrew Rist  * software distributed under the License is distributed on an
1548123e16SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1648123e16SAndrew Rist  * KIND, either express or implied.  See the License for the
1748123e16SAndrew Rist  * specific language governing permissions and limitations
1848123e16SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
2048123e16SAndrew Rist  *************************************************************/
2148123e16SAndrew Rist 
2248123e16SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_dtrans.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //------------------------------------------------------------------------
28cdf0e10cSrcweir // includes
29cdf0e10cSrcweir //------------------------------------------------------------------------
30cdf0e10cSrcweir #include <osl/diagnose.h>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #ifndef _TXDATAOBJECT_HXX_
33cdf0e10cSrcweir #include "XTDataObject.hxx"
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #include <com/sun/star/datatransfer/DataFlavor.hpp>
36cdf0e10cSrcweir #include "..\misc\ImplHelper.hxx"
37cdf0e10cSrcweir #include "DTransHelper.hxx"
38cdf0e10cSrcweir #include "TxtCnvtHlp.hxx"
39cdf0e10cSrcweir #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
40cdf0e10cSrcweir #include "FmtFilter.hxx"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #if defined _MSC_VER
43cdf0e10cSrcweir #pragma warning(push,1)
44cdf0e10cSrcweir #pragma warning(disable:4917)
45cdf0e10cSrcweir #endif
46cdf0e10cSrcweir #include <windows.h>
47cdf0e10cSrcweir #include <shlobj.h>
48cdf0e10cSrcweir #if defined _MSC_VER
49cdf0e10cSrcweir #pragma warning(pop)
50cdf0e10cSrcweir #endif
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #ifdef __MINGW32__
53cdf0e10cSrcweir #define __uuidof(I) IID_##I
54cdf0e10cSrcweir #endif
55cdf0e10cSrcweir 
56cdf0e10cSrcweir //------------------------------------------------------------------------
57cdf0e10cSrcweir // namespace directives
58cdf0e10cSrcweir //------------------------------------------------------------------------
59cdf0e10cSrcweir 
60cdf0e10cSrcweir using namespace com::sun::star::datatransfer;
61cdf0e10cSrcweir using namespace com::sun::star::datatransfer::clipboard;
62cdf0e10cSrcweir using namespace com::sun::star::uno;
63cdf0e10cSrcweir using namespace com::sun::star::lang;
64cdf0e10cSrcweir using namespace rtl;
65cdf0e10cSrcweir 
66cdf0e10cSrcweir //------------------------------------------------------------------------
67cdf0e10cSrcweir // a helper class that will be thrown by the function validateFormatEtc
68cdf0e10cSrcweir //------------------------------------------------------------------------
69cdf0e10cSrcweir 
70cdf0e10cSrcweir class CInvalidFormatEtcException
71cdf0e10cSrcweir {
72cdf0e10cSrcweir public:
73cdf0e10cSrcweir 	HRESULT m_hr;
74cdf0e10cSrcweir 	CInvalidFormatEtcException( HRESULT hr ) : m_hr( hr ) {};
75cdf0e10cSrcweir };
76cdf0e10cSrcweir 
77cdf0e10cSrcweir //------------------------------------------------------------------------
78cdf0e10cSrcweir // ctor
79cdf0e10cSrcweir //------------------------------------------------------------------------
80cdf0e10cSrcweir 
81cdf0e10cSrcweir CXTDataObject::CXTDataObject( const Reference< XMultiServiceFactory >& aServiceManager,
82cdf0e10cSrcweir 							  const Reference< XTransferable >& aXTransferable ) :
83cdf0e10cSrcweir 	m_nRefCnt( 0 ),
84cdf0e10cSrcweir 	m_SrvMgr( aServiceManager ),
85cdf0e10cSrcweir 	m_XTransferable( aXTransferable ),
86cdf0e10cSrcweir 	m_DataFormatTranslator( aServiceManager ),
87cdf0e10cSrcweir     m_bFormatEtcContainerInitialized( sal_False ),
88cdf0e10cSrcweir 	m_FormatRegistrar( m_SrvMgr, m_DataFormatTranslator )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
92cdf0e10cSrcweir //------------------------------------------------------------------------
93cdf0e10cSrcweir // IUnknown->QueryInterface
94cdf0e10cSrcweir //------------------------------------------------------------------------
95cdf0e10cSrcweir 
96cdf0e10cSrcweir STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir 	if ( NULL == ppvObject )
99cdf0e10cSrcweir 		return E_INVALIDARG;
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	HRESULT hr = E_NOINTERFACE;
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 	*ppvObject = NULL;
104cdf0e10cSrcweir 	if ( ( __uuidof( IUnknown ) == iid ) ||
105cdf0e10cSrcweir 		 ( __uuidof( IDataObject ) == iid ) )
106cdf0e10cSrcweir 	{
107cdf0e10cSrcweir 		*ppvObject = static_cast< IUnknown* >( this );
108cdf0e10cSrcweir 		( (LPUNKNOWN)*ppvObject )->AddRef( );
109cdf0e10cSrcweir 		hr = S_OK;
110cdf0e10cSrcweir 	}
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 	return hr;
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
115cdf0e10cSrcweir //------------------------------------------------------------------------
116cdf0e10cSrcweir // IUnknown->AddRef
117cdf0e10cSrcweir //------------------------------------------------------------------------
118cdf0e10cSrcweir 
119cdf0e10cSrcweir STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
120cdf0e10cSrcweir {
121cdf0e10cSrcweir 	return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
122cdf0e10cSrcweir }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir //------------------------------------------------------------------------
125cdf0e10cSrcweir // IUnknown->Release
126cdf0e10cSrcweir //------------------------------------------------------------------------
127cdf0e10cSrcweir 
128cdf0e10cSrcweir STDMETHODIMP_(ULONG) CXTDataObject::Release( )
129cdf0e10cSrcweir {
130cdf0e10cSrcweir 	ULONG nRefCnt =
131cdf0e10cSrcweir 		static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 	if ( 0 == nRefCnt )
134cdf0e10cSrcweir 		delete this;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	return nRefCnt;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir 
139cdf0e10cSrcweir //------------------------------------------------------------------------
140cdf0e10cSrcweir //
141cdf0e10cSrcweir //------------------------------------------------------------------------
142cdf0e10cSrcweir 
143cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir 	if ( !(pFormatetc && pmedium) )
146cdf0e10cSrcweir 		return E_INVALIDARG;
147cdf0e10cSrcweir 
148cdf0e10cSrcweir 	try
149cdf0e10cSrcweir 	{
150cdf0e10cSrcweir 		// prepare data transfer
151cdf0e10cSrcweir 		invalidateStgMedium( *pmedium );
152cdf0e10cSrcweir 		validateFormatEtc( pFormatetc );
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 		// handle locale request, because locale is a artificial format for us
155cdf0e10cSrcweir 		if ( CF_LOCALE == pFormatetc->cfFormat )
156cdf0e10cSrcweir 			renderLocaleAndSetupStgMedium( *pFormatetc, *pmedium );
157cdf0e10cSrcweir 		else if ( CF_UNICODETEXT == pFormatetc->cfFormat )
158cdf0e10cSrcweir 			renderUnicodeAndSetupStgMedium( *pFormatetc, *pmedium );
159cdf0e10cSrcweir 		else
160cdf0e10cSrcweir 			renderAnyDataAndSetupStgMedium( *pFormatetc, *pmedium );
161cdf0e10cSrcweir 	}
162cdf0e10cSrcweir 	catch(UnsupportedFlavorException&)
163cdf0e10cSrcweir 	{
164cdf0e10cSrcweir 		HRESULT hr = DV_E_FORMATETC;
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 		if ( m_FormatRegistrar.isSynthesizeableFormat( *pFormatetc ) )
167cdf0e10cSrcweir 			hr = renderSynthesizedFormatAndSetupStgMedium( *pFormatetc, *pmedium );
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 		return hr;
170cdf0e10cSrcweir 	}
171cdf0e10cSrcweir 	catch( CInvalidFormatEtcException& ex )
172cdf0e10cSrcweir 	{
173cdf0e10cSrcweir 		return ex.m_hr;
174cdf0e10cSrcweir 	}
175cdf0e10cSrcweir 	catch( CStgTransferHelper::CStgTransferException& ex )
176cdf0e10cSrcweir 	{
177cdf0e10cSrcweir 		return translateStgExceptionCode( ex.m_hr );
178cdf0e10cSrcweir 	}
179cdf0e10cSrcweir 	catch(...)
180cdf0e10cSrcweir 	{
181cdf0e10cSrcweir 		return E_UNEXPECTED;
182cdf0e10cSrcweir 	}
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 	return S_OK;
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir //------------------------------------------------------------------------
188cdf0e10cSrcweir //
189cdf0e10cSrcweir //------------------------------------------------------------------------
190cdf0e10cSrcweir 
191cdf0e10cSrcweir // inline
192cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderDataAndSetupStgMedium(
193cdf0e10cSrcweir 	const sal_Int8* lpStorage, const FORMATETC& fetc, sal_uInt32 nInitStgSize,
194cdf0e10cSrcweir 	sal_uInt32 nBytesToTransfer, STGMEDIUM& stgmedium )
195cdf0e10cSrcweir {
196cdf0e10cSrcweir 	OSL_PRECOND( !nInitStgSize || nInitStgSize && (nInitStgSize >= nBytesToTransfer),
197cdf0e10cSrcweir 		         "Memory size less than number of bytes to transfer" );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 	CStgTransferHelper stgTransfHelper( AUTO_INIT );
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 	// setup storage size
202cdf0e10cSrcweir 	if ( nInitStgSize > 0 )
203cdf0e10cSrcweir 		stgTransfHelper.init( nInitStgSize, GHND );
204cdf0e10cSrcweir 
205cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
206cdf0e10cSrcweir     sal_uInt32 nBytesWritten = 0;
207cdf0e10cSrcweir     stgTransfHelper.write( lpStorage, nBytesToTransfer, &nBytesWritten );
208cdf0e10cSrcweir     OSL_ASSERT( nBytesWritten == nBytesToTransfer );
209cdf0e10cSrcweir #else
210cdf0e10cSrcweir     stgTransfHelper.write( lpStorage, nBytesToTransfer );
211cdf0e10cSrcweir #endif
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 	setupStgMedium( fetc, stgTransfHelper, stgmedium );
214cdf0e10cSrcweir }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir //------------------------------------------------------------------------
217cdf0e10cSrcweir //
218cdf0e10cSrcweir //------------------------------------------------------------------------
219cdf0e10cSrcweir 
220cdf0e10cSrcweir //inline
221cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderLocaleAndSetupStgMedium(
222cdf0e10cSrcweir 	FORMATETC& fetc, STGMEDIUM& stgmedium )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	if ( m_FormatRegistrar.hasSynthesizedLocale( ) )
225cdf0e10cSrcweir 	{
226cdf0e10cSrcweir 		LCID lcid = m_FormatRegistrar.getSynthesizedLocale( );
227cdf0e10cSrcweir 		renderDataAndSetupStgMedium(
228cdf0e10cSrcweir 			reinterpret_cast< sal_Int8* >( &lcid ),
229cdf0e10cSrcweir 			fetc,
230cdf0e10cSrcweir 			0,
231cdf0e10cSrcweir 			sizeof( LCID ),
232cdf0e10cSrcweir 			stgmedium );
233cdf0e10cSrcweir 	}
234cdf0e10cSrcweir 	else
235cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_FORMATETC );
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir //------------------------------------------------------------------------
239cdf0e10cSrcweir //
240cdf0e10cSrcweir //------------------------------------------------------------------------
241cdf0e10cSrcweir 
242cdf0e10cSrcweir //inline
243cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderUnicodeAndSetupStgMedium(
244cdf0e10cSrcweir 	FORMATETC& fetc, STGMEDIUM& stgmedium )
245cdf0e10cSrcweir {
246cdf0e10cSrcweir 	DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( aFlavor );
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
251cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
252cdf0e10cSrcweir 	// so we must check the any
253cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
254cdf0e10cSrcweir 	{
255cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
256cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
257cdf0e10cSrcweir 	}
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 	OUString aText;
260cdf0e10cSrcweir 	aAny >>= aText;
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 	sal_uInt32 nBytesToTransfer = aText.getLength( ) * sizeof( sal_Unicode );
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 	// to be sure there is an ending 0
265cdf0e10cSrcweir 	sal_uInt32 nRequiredMemSize = nBytesToTransfer + sizeof( sal_Unicode );
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 	renderDataAndSetupStgMedium(
268cdf0e10cSrcweir 		reinterpret_cast< const sal_Int8* >( aText.getStr( ) ),
269cdf0e10cSrcweir 		fetc,
270cdf0e10cSrcweir 		nRequiredMemSize,
271cdf0e10cSrcweir 		nBytesToTransfer,
272cdf0e10cSrcweir 		stgmedium );
273cdf0e10cSrcweir }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir //------------------------------------------------------------------------
276cdf0e10cSrcweir //
277cdf0e10cSrcweir //------------------------------------------------------------------------
278cdf0e10cSrcweir 
279cdf0e10cSrcweir //inline
280cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderAnyDataAndSetupStgMedium(
281cdf0e10cSrcweir 	FORMATETC& fetc, STGMEDIUM& stgmedium )
282cdf0e10cSrcweir {
283cdf0e10cSrcweir 	DataFlavor aFlavor = formatEtcToDataFlavor( fetc );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( aFlavor );
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
288cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
289cdf0e10cSrcweir 	// so we must check the any
290cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
291cdf0e10cSrcweir 	{
292cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
293cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
294cdf0e10cSrcweir 	}
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
297cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
298cdf0e10cSrcweir 	// so we must check the any
299cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
300cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 	Sequence< sal_Int8 > clipDataStream;
303cdf0e10cSrcweir 	aAny >>= clipDataStream;
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 	sal_uInt32 nRequiredMemSize = 0;
306cdf0e10cSrcweir 	if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) )
307cdf0e10cSrcweir 		nRequiredMemSize = sizeof( sal_Int8 ) * clipDataStream.getLength( ) + 1;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 	// prepare data for transmision
310*45fd3b9aSArmin Le Grand 	if ( CF_DIBV5 == fetc.cfFormat || CF_DIB == fetc.cfFormat )
311*45fd3b9aSArmin Le Grand     {
312*45fd3b9aSArmin Le Grand #ifdef DBG_UTIL
313*45fd3b9aSArmin Le Grand         if(CF_DIBV5 == fetc.cfFormat)
314*45fd3b9aSArmin Le Grand         {
315*45fd3b9aSArmin Le Grand             OSL_ENSURE(clipDataStream.getLength( ) > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPV5HEADER)), "Wrong size on CF_DIBV5 data (!)");
316*45fd3b9aSArmin Le Grand         }
317*45fd3b9aSArmin Le Grand         else // CF_DIB == fetc.cfFormat
318*45fd3b9aSArmin Le Grand         {
319*45fd3b9aSArmin Le Grand             OSL_ENSURE(clipDataStream.getLength( ) > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)), "Wrong size on CF_DIB data (!)");
320*45fd3b9aSArmin Le Grand         }
321*45fd3b9aSArmin Le Grand #endif
322*45fd3b9aSArmin Le Grand 
323*45fd3b9aSArmin Le Grand         // remove BITMAPFILEHEADER
324cdf0e10cSrcweir         clipDataStream = OOBmpToWinDIB( clipDataStream );
325*45fd3b9aSArmin Le Grand     }
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 	if ( CF_METAFILEPICT == fetc.cfFormat )
328cdf0e10cSrcweir 	{
329cdf0e10cSrcweir 		stgmedium.tymed          = TYMED_MFPICT;
330cdf0e10cSrcweir 		stgmedium.hMetaFilePict  = OOMFPictToWinMFPict( clipDataStream );
331cdf0e10cSrcweir 		stgmedium.pUnkForRelease = NULL;
332cdf0e10cSrcweir 	}
333cdf0e10cSrcweir 	else if( CF_ENHMETAFILE	== fetc.cfFormat )
334cdf0e10cSrcweir 	{
335cdf0e10cSrcweir 		stgmedium.tymed          = TYMED_ENHMF;
336cdf0e10cSrcweir 		stgmedium.hMetaFilePict  = OOMFPictToWinENHMFPict( clipDataStream );
337cdf0e10cSrcweir 		stgmedium.pUnkForRelease = NULL;
338cdf0e10cSrcweir 	}
339cdf0e10cSrcweir 	else
340cdf0e10cSrcweir 		renderDataAndSetupStgMedium(
341cdf0e10cSrcweir 			clipDataStream.getArray( ),
342cdf0e10cSrcweir 			fetc,
343cdf0e10cSrcweir 			nRequiredMemSize,
344cdf0e10cSrcweir 			clipDataStream.getLength( ),
345cdf0e10cSrcweir 			stgmedium );
346cdf0e10cSrcweir }
347cdf0e10cSrcweir 
348cdf0e10cSrcweir //------------------------------------------------------------------------
349cdf0e10cSrcweir //
350cdf0e10cSrcweir //------------------------------------------------------------------------
351cdf0e10cSrcweir 
352cdf0e10cSrcweir HRESULT SAL_CALL CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
353cdf0e10cSrcweir {
354cdf0e10cSrcweir 	HRESULT hr = S_OK;
355cdf0e10cSrcweir 
356cdf0e10cSrcweir 	try
357cdf0e10cSrcweir 	{
358cdf0e10cSrcweir 		if ( CF_UNICODETEXT == fetc.cfFormat )
359cdf0e10cSrcweir 			// the transferable seems to have only text
360cdf0e10cSrcweir 			renderSynthesizedUnicodeAndSetupStgMedium( fetc, stgmedium );
361cdf0e10cSrcweir 		else if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) )
362cdf0e10cSrcweir 			// the transferable seems to have only unicode text
363cdf0e10cSrcweir 			renderSynthesizedTextAndSetupStgMedium( fetc, stgmedium );
364cdf0e10cSrcweir 		else
365cdf0e10cSrcweir 			// the transferable seems to have only text/html
366cdf0e10cSrcweir 			renderSynthesizedHtmlAndSetupStgMedium( fetc, stgmedium );
367cdf0e10cSrcweir 	}
368cdf0e10cSrcweir 	catch(UnsupportedFlavorException&)
369cdf0e10cSrcweir 	{
370cdf0e10cSrcweir 		hr = DV_E_FORMATETC;
371cdf0e10cSrcweir 	}
372cdf0e10cSrcweir 	catch( CInvalidFormatEtcException& )
373cdf0e10cSrcweir 	{
374cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "Unexpected exception" );
375cdf0e10cSrcweir 	}
376cdf0e10cSrcweir 	catch( CStgTransferHelper::CStgTransferException& ex )
377cdf0e10cSrcweir 	{
378cdf0e10cSrcweir 		return translateStgExceptionCode( ex.m_hr );
379cdf0e10cSrcweir 	}
380cdf0e10cSrcweir 	catch(...)
381cdf0e10cSrcweir 	{
382cdf0e10cSrcweir 		hr = E_UNEXPECTED;
383cdf0e10cSrcweir 	}
384cdf0e10cSrcweir 
385cdf0e10cSrcweir 	return hr;
386cdf0e10cSrcweir }
387cdf0e10cSrcweir 
388cdf0e10cSrcweir //------------------------------------------------------------------------
389cdf0e10cSrcweir // the transferable must have only text, so we will synthesize unicode text
390cdf0e10cSrcweir //------------------------------------------------------------------------
391cdf0e10cSrcweir 
392cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
393cdf0e10cSrcweir {
394cdf0e10cSrcweir 	OSL_ASSERT( CF_UNICODETEXT == fetc.cfFormat );
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( m_FormatRegistrar.getRegisteredTextFlavor( ) );
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
399cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
400cdf0e10cSrcweir 	// so we must check the any
401cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
402cdf0e10cSrcweir 	{
403cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
404cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
405cdf0e10cSrcweir 	}
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 	Sequence< sal_Int8 > aText;
408cdf0e10cSrcweir 	aAny >>= aText;
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 	CStgTransferHelper stgTransfHelper;
411cdf0e10cSrcweir 
412cdf0e10cSrcweir 	MultiByteToWideCharEx(
413cdf0e10cSrcweir 		m_FormatRegistrar.getRegisteredTextCodePage( ),
414cdf0e10cSrcweir 		reinterpret_cast< char* >( aText.getArray( ) ),
415cdf0e10cSrcweir 		aText.getLength( ),
416cdf0e10cSrcweir 		stgTransfHelper );
417cdf0e10cSrcweir 
418cdf0e10cSrcweir 	setupStgMedium( fetc, stgTransfHelper, stgmedium );
419cdf0e10cSrcweir }
420cdf0e10cSrcweir 
421cdf0e10cSrcweir //------------------------------------------------------------------------
422cdf0e10cSrcweir // the transferable must have only unicode text so we will sythesize text
423cdf0e10cSrcweir //------------------------------------------------------------------------
424cdf0e10cSrcweir 
425cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
426cdf0e10cSrcweir {
427cdf0e10cSrcweir 	OSL_ASSERT( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) );
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 	DataFlavor aFlavor = formatEtcToDataFlavor(
430cdf0e10cSrcweir 		m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) );
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( aFlavor );
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
435cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
436cdf0e10cSrcweir 	// so we must check the any
437cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
438cdf0e10cSrcweir 	{
439cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
440cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
441cdf0e10cSrcweir 	}
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 	OUString aUnicodeText;
444cdf0e10cSrcweir 	aAny >>= aUnicodeText;
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 	CStgTransferHelper stgTransfHelper;
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 	WideCharToMultiByteEx(
449cdf0e10cSrcweir 		GetACP( ),
450cdf0e10cSrcweir 		reinterpret_cast<LPCWSTR>( aUnicodeText.getStr( ) ),
451cdf0e10cSrcweir 		aUnicodeText.getLength( ),
452cdf0e10cSrcweir 		stgTransfHelper );
453cdf0e10cSrcweir 
454cdf0e10cSrcweir 	setupStgMedium( fetc, stgTransfHelper, stgmedium );
455cdf0e10cSrcweir }
456cdf0e10cSrcweir 
457cdf0e10cSrcweir //------------------------------------------------------------------------
458cdf0e10cSrcweir //
459cdf0e10cSrcweir //------------------------------------------------------------------------
460cdf0e10cSrcweir 
461cdf0e10cSrcweir void SAL_CALL CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium )
462cdf0e10cSrcweir {
463cdf0e10cSrcweir 	OSL_ASSERT( m_DataFormatTranslator.isHTMLFormat( fetc.cfFormat ) );
464cdf0e10cSrcweir 
465cdf0e10cSrcweir 	DataFlavor aFlavor;
466cdf0e10cSrcweir 
467cdf0e10cSrcweir 	// creating a DataFlavor on the fly
468cdf0e10cSrcweir 	aFlavor.MimeType = OUString::createFromAscii( "text/html" );
469cdf0e10cSrcweir 	aFlavor.DataType = getCppuType( (Sequence< sal_Int8 >*)0 );
470cdf0e10cSrcweir 
471cdf0e10cSrcweir 	Any aAny = m_XTransferable->getTransferData( aFlavor );
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 	// unfortunately not all transferables fulfill the
474cdf0e10cSrcweir 	// spec. an do throw an UnsupportedFlavorException
475cdf0e10cSrcweir 	// so we must check the any
476cdf0e10cSrcweir 	if ( !aAny.hasValue( ) )
477cdf0e10cSrcweir 	{
478cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" );
479cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
480cdf0e10cSrcweir 	}
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 	Sequence< sal_Int8 > aTextHtmlSequence;
483cdf0e10cSrcweir 	aAny >>= aTextHtmlSequence;
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 	Sequence< sal_Int8 > aHTMLFormatSequence = TextHtmlToHTMLFormat( aTextHtmlSequence );
486cdf0e10cSrcweir 
487cdf0e10cSrcweir 	sal_uInt32 nBytesToTransfer = aHTMLFormatSequence.getLength( );
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 	renderDataAndSetupStgMedium(
490cdf0e10cSrcweir 		reinterpret_cast< const sal_Int8* >( aHTMLFormatSequence.getArray( ) ),
491cdf0e10cSrcweir 		fetc,
492cdf0e10cSrcweir 		0,
493cdf0e10cSrcweir 		nBytesToTransfer,
494cdf0e10cSrcweir 		stgmedium );
495cdf0e10cSrcweir }
496cdf0e10cSrcweir 
497cdf0e10cSrcweir //------------------------------------------------------------------------
498cdf0e10cSrcweir // IDataObject->EnumFormatEtc
499cdf0e10cSrcweir //------------------------------------------------------------------------
500cdf0e10cSrcweir 
501cdf0e10cSrcweir STDMETHODIMP CXTDataObject::EnumFormatEtc(
502cdf0e10cSrcweir 	DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
503cdf0e10cSrcweir {
504cdf0e10cSrcweir 	if ( NULL == ppenumFormatetc )
505cdf0e10cSrcweir 		return E_INVALIDARG;
506cdf0e10cSrcweir 
507cdf0e10cSrcweir 	if ( DATADIR_SET == dwDirection )
508cdf0e10cSrcweir 		return E_NOTIMPL;
509cdf0e10cSrcweir 
510cdf0e10cSrcweir 	*ppenumFormatetc = NULL;
511cdf0e10cSrcweir 
512cdf0e10cSrcweir     InitializeFormatEtcContainer( );
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 	HRESULT hr;
515cdf0e10cSrcweir 	if ( DATADIR_GET == dwDirection )
516cdf0e10cSrcweir 	{
517cdf0e10cSrcweir 		*ppenumFormatetc = new CEnumFormatEtc( this, m_FormatEtcContainer );
518cdf0e10cSrcweir 		if ( NULL != *ppenumFormatetc )
519cdf0e10cSrcweir 			static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
520cdf0e10cSrcweir 
521cdf0e10cSrcweir 		hr = ( NULL != *ppenumFormatetc ) ? S_OK : E_OUTOFMEMORY;
522cdf0e10cSrcweir 	}
523cdf0e10cSrcweir 	else
524cdf0e10cSrcweir 		hr = E_INVALIDARG;
525cdf0e10cSrcweir 
526cdf0e10cSrcweir 	return hr;
527cdf0e10cSrcweir }
528cdf0e10cSrcweir 
529cdf0e10cSrcweir //------------------------------------------------------------------------
530cdf0e10cSrcweir // IDataObject->QueryGetData
531cdf0e10cSrcweir //------------------------------------------------------------------------
532cdf0e10cSrcweir 
533cdf0e10cSrcweir STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
534cdf0e10cSrcweir {
535cdf0e10cSrcweir 	if ( (NULL == pFormatetc) || IsBadReadPtr( pFormatetc, sizeof( FORMATETC ) ) )
536cdf0e10cSrcweir 		return E_INVALIDARG;
537cdf0e10cSrcweir 
538cdf0e10cSrcweir     InitializeFormatEtcContainer( );
539cdf0e10cSrcweir 
540cdf0e10cSrcweir 	return m_FormatEtcContainer.hasFormatEtc( *pFormatetc ) ? S_OK : S_FALSE;
541cdf0e10cSrcweir }
542cdf0e10cSrcweir 
543cdf0e10cSrcweir //------------------------------------------------------------------------
544cdf0e10cSrcweir // IDataObject->GetDataHere
545cdf0e10cSrcweir //------------------------------------------------------------------------
546cdf0e10cSrcweir 
547cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
548cdf0e10cSrcweir {
549cdf0e10cSrcweir 	return E_NOTIMPL;
550cdf0e10cSrcweir }
551cdf0e10cSrcweir 
552cdf0e10cSrcweir //------------------------------------------------------------------------
553cdf0e10cSrcweir // IDataObject->GetCanonicalFormatEtc
554cdf0e10cSrcweir //------------------------------------------------------------------------
555cdf0e10cSrcweir 
556cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
557cdf0e10cSrcweir {
558cdf0e10cSrcweir 	return E_NOTIMPL;
559cdf0e10cSrcweir }
560cdf0e10cSrcweir 
561cdf0e10cSrcweir //------------------------------------------------------------------------
562cdf0e10cSrcweir // IDataObject->SetData
563cdf0e10cSrcweir //------------------------------------------------------------------------
564cdf0e10cSrcweir 
565cdf0e10cSrcweir STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
566cdf0e10cSrcweir {
567cdf0e10cSrcweir 	return E_NOTIMPL;
568cdf0e10cSrcweir }
569cdf0e10cSrcweir 
570cdf0e10cSrcweir //------------------------------------------------------------------------
571cdf0e10cSrcweir // IDataObject->DAdvise
572cdf0e10cSrcweir //------------------------------------------------------------------------
573cdf0e10cSrcweir 
574cdf0e10cSrcweir STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
575cdf0e10cSrcweir {
576cdf0e10cSrcweir 	return E_NOTIMPL;
577cdf0e10cSrcweir }
578cdf0e10cSrcweir 
579cdf0e10cSrcweir //------------------------------------------------------------------------
580cdf0e10cSrcweir // IDataObject->DUnadvise
581cdf0e10cSrcweir //------------------------------------------------------------------------
582cdf0e10cSrcweir 
583cdf0e10cSrcweir STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
584cdf0e10cSrcweir {
585cdf0e10cSrcweir 	return E_NOTIMPL;
586cdf0e10cSrcweir }
587cdf0e10cSrcweir 
588cdf0e10cSrcweir //------------------------------------------------------------------------
589cdf0e10cSrcweir // IDataObject->EnumDAdvise
590cdf0e10cSrcweir //------------------------------------------------------------------------
591cdf0e10cSrcweir 
592cdf0e10cSrcweir STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
593cdf0e10cSrcweir {
594cdf0e10cSrcweir 	return E_NOTIMPL;
595cdf0e10cSrcweir }
596cdf0e10cSrcweir 
597cdf0e10cSrcweir //------------------------------------------------------------------------
598cdf0e10cSrcweir // for our convenience
599cdf0e10cSrcweir //------------------------------------------------------------------------
600cdf0e10cSrcweir 
601cdf0e10cSrcweir CXTDataObject::operator IDataObject*( )
602cdf0e10cSrcweir {
603cdf0e10cSrcweir 	return static_cast< IDataObject* >( this );
604cdf0e10cSrcweir }
605cdf0e10cSrcweir 
606cdf0e10cSrcweir //------------------------------------------------------------------------
607cdf0e10cSrcweir //
608cdf0e10cSrcweir //------------------------------------------------------------------------
609cdf0e10cSrcweir 
610cdf0e10cSrcweir inline
611cdf0e10cSrcweir DataFlavor SAL_CALL CXTDataObject::formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const
612cdf0e10cSrcweir {
613cdf0e10cSrcweir 	DataFlavor aFlavor;
614cdf0e10cSrcweir 
615cdf0e10cSrcweir 	if ( m_FormatRegistrar.hasSynthesizedLocale( ) )
616cdf0e10cSrcweir 		aFlavor =
617cdf0e10cSrcweir 			m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, m_FormatRegistrar.getSynthesizedLocale( ) );
618cdf0e10cSrcweir 	else
619cdf0e10cSrcweir 		aFlavor = m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc );
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 	if ( !aFlavor.MimeType.getLength( ) )
622cdf0e10cSrcweir 		throw UnsupportedFlavorException( );
623cdf0e10cSrcweir 
624cdf0e10cSrcweir 	return aFlavor;
625cdf0e10cSrcweir }
626cdf0e10cSrcweir 
627cdf0e10cSrcweir //------------------------------------------------------------------------
628cdf0e10cSrcweir //
629cdf0e10cSrcweir //------------------------------------------------------------------------
630cdf0e10cSrcweir 
631cdf0e10cSrcweir inline
632cdf0e10cSrcweir void CXTDataObject::validateFormatEtc( LPFORMATETC lpFormatEtc ) const
633cdf0e10cSrcweir {
634cdf0e10cSrcweir 	OSL_ASSERT( lpFormatEtc );
635cdf0e10cSrcweir 
636cdf0e10cSrcweir 	if ( lpFormatEtc->lindex != -1 )
637cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_LINDEX );
638cdf0e10cSrcweir 
639cdf0e10cSrcweir 	if ( !(lpFormatEtc->dwAspect & DVASPECT_CONTENT) &&
640cdf0e10cSrcweir 		 !(lpFormatEtc->dwAspect & DVASPECT_SHORTNAME) )
641cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_DVASPECT );
642cdf0e10cSrcweir 
643cdf0e10cSrcweir 	if ( !(lpFormatEtc->tymed & TYMED_HGLOBAL) &&
644cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_ISTREAM) &&
645cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_MFPICT) &&
646cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_ENHMF) )
647cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_TYMED );
648cdf0e10cSrcweir 
649cdf0e10cSrcweir 	if ( lpFormatEtc->cfFormat == CF_METAFILEPICT &&
650cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_MFPICT) )
651cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_TYMED );
652cdf0e10cSrcweir 
653cdf0e10cSrcweir 	if ( lpFormatEtc->cfFormat == CF_ENHMETAFILE &&
654cdf0e10cSrcweir 		 !(lpFormatEtc->tymed & TYMED_ENHMF) )
655cdf0e10cSrcweir 		throw CInvalidFormatEtcException( DV_E_TYMED );
656cdf0e10cSrcweir }
657cdf0e10cSrcweir 
658cdf0e10cSrcweir //------------------------------------------------------------------------
659cdf0e10cSrcweir //
660cdf0e10cSrcweir //------------------------------------------------------------------------
661cdf0e10cSrcweir 
662cdf0e10cSrcweir //inline
663cdf0e10cSrcweir void SAL_CALL CXTDataObject::setupStgMedium( const FORMATETC& fetc,
664cdf0e10cSrcweir 											 CStgTransferHelper& stgTransHlp,
665cdf0e10cSrcweir 											 STGMEDIUM& stgmedium )
666cdf0e10cSrcweir {
667cdf0e10cSrcweir 	stgmedium.pUnkForRelease = NULL;
668cdf0e10cSrcweir 
669cdf0e10cSrcweir 	if ( fetc.cfFormat == CF_METAFILEPICT )
670cdf0e10cSrcweir 	{
671cdf0e10cSrcweir 		stgmedium.tymed         = TYMED_MFPICT;
672cdf0e10cSrcweir 		stgmedium.hMetaFilePict = static_cast< HMETAFILEPICT >( stgTransHlp.getHGlobal( ) );
673cdf0e10cSrcweir 	}
674cdf0e10cSrcweir 	else if ( fetc.cfFormat == CF_ENHMETAFILE )
675cdf0e10cSrcweir 	{
676cdf0e10cSrcweir 		stgmedium.tymed        = TYMED_ENHMF;
677cdf0e10cSrcweir 		stgmedium.hEnhMetaFile = static_cast< HENHMETAFILE >( stgTransHlp.getHGlobal( ) );
678cdf0e10cSrcweir 	}
679cdf0e10cSrcweir 	else if ( fetc.tymed & TYMED_HGLOBAL )
680cdf0e10cSrcweir 	{
681cdf0e10cSrcweir 		stgmedium.tymed   = TYMED_HGLOBAL;
682cdf0e10cSrcweir 		stgmedium.hGlobal = stgTransHlp.getHGlobal( );
683cdf0e10cSrcweir 	}
684cdf0e10cSrcweir 	else if ( fetc.tymed & TYMED_ISTREAM )
685cdf0e10cSrcweir 	{
686cdf0e10cSrcweir 		stgmedium.tymed = TYMED_ISTREAM;
687cdf0e10cSrcweir 		stgTransHlp.getIStream( &stgmedium.pstm );
688cdf0e10cSrcweir 	}
689cdf0e10cSrcweir 	else
690cdf0e10cSrcweir 		OSL_ASSERT( sal_False );
691cdf0e10cSrcweir }
692cdf0e10cSrcweir 
693cdf0e10cSrcweir //------------------------------------------------------------------------
694cdf0e10cSrcweir //
695cdf0e10cSrcweir //------------------------------------------------------------------------
696cdf0e10cSrcweir 
697cdf0e10cSrcweir inline
698cdf0e10cSrcweir void SAL_CALL CXTDataObject::invalidateStgMedium( STGMEDIUM& stgmedium ) const
699cdf0e10cSrcweir {
700cdf0e10cSrcweir 	stgmedium.tymed = TYMED_NULL;
701cdf0e10cSrcweir }
702cdf0e10cSrcweir 
703cdf0e10cSrcweir //------------------------------------------------------------------------
704cdf0e10cSrcweir //
705cdf0e10cSrcweir //------------------------------------------------------------------------
706cdf0e10cSrcweir 
707cdf0e10cSrcweir inline
708cdf0e10cSrcweir HRESULT SAL_CALL CXTDataObject::translateStgExceptionCode( HRESULT hr ) const
709cdf0e10cSrcweir {
710cdf0e10cSrcweir 	HRESULT hrTransl;
711cdf0e10cSrcweir 
712cdf0e10cSrcweir 	switch( hr )
713cdf0e10cSrcweir 	{
714cdf0e10cSrcweir 	case STG_E_MEDIUMFULL:
715cdf0e10cSrcweir 		hrTransl = hr;
716cdf0e10cSrcweir 		break;
717cdf0e10cSrcweir 
718cdf0e10cSrcweir 	default:
719cdf0e10cSrcweir 		hrTransl = E_UNEXPECTED;
720cdf0e10cSrcweir 		break;
721cdf0e10cSrcweir 	}
722cdf0e10cSrcweir 
723cdf0e10cSrcweir 	return hrTransl;
724cdf0e10cSrcweir }
725cdf0e10cSrcweir 
726cdf0e10cSrcweir //------------------------------------------------------------------------
727cdf0e10cSrcweir //
728cdf0e10cSrcweir //------------------------------------------------------------------------
729cdf0e10cSrcweir 
730cdf0e10cSrcweir inline void SAL_CALL CXTDataObject::InitializeFormatEtcContainer( )
731cdf0e10cSrcweir {
732cdf0e10cSrcweir     if ( !m_bFormatEtcContainerInitialized )
733cdf0e10cSrcweir     {
734cdf0e10cSrcweir         m_FormatRegistrar.RegisterFormats( m_XTransferable, m_FormatEtcContainer );
735cdf0e10cSrcweir         m_bFormatEtcContainerInitialized = sal_True;
736cdf0e10cSrcweir     }
737cdf0e10cSrcweir }
738cdf0e10cSrcweir 
739cdf0e10cSrcweir //============================================================================
740cdf0e10cSrcweir // CEnumFormatEtc
741cdf0e10cSrcweir //============================================================================
742cdf0e10cSrcweir 
743cdf0e10cSrcweir //----------------------------------------------------------------------------
744cdf0e10cSrcweir // ctor
745cdf0e10cSrcweir //----------------------------------------------------------------------------
746cdf0e10cSrcweir 
747cdf0e10cSrcweir CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer ) :
748cdf0e10cSrcweir 	m_nRefCnt( 0 ),
749cdf0e10cSrcweir 	m_lpUnkOuter( lpUnkOuter ),
750cdf0e10cSrcweir 	m_FormatEtcContainer( aFormatEtcContainer )
751cdf0e10cSrcweir {
752cdf0e10cSrcweir 	Reset( );
753cdf0e10cSrcweir }
754cdf0e10cSrcweir 
755cdf0e10cSrcweir //----------------------------------------------------------------------------
756cdf0e10cSrcweir // IUnknown->QueryInterface
757cdf0e10cSrcweir //----------------------------------------------------------------------------
758cdf0e10cSrcweir 
759cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
760cdf0e10cSrcweir {
761cdf0e10cSrcweir 	if ( NULL == ppvObject )
762cdf0e10cSrcweir 		return E_INVALIDARG;
763cdf0e10cSrcweir 
764cdf0e10cSrcweir 	HRESULT hr = E_NOINTERFACE;
765cdf0e10cSrcweir 
766cdf0e10cSrcweir 	*ppvObject = NULL;
767cdf0e10cSrcweir 
768cdf0e10cSrcweir 	if ( ( __uuidof( IUnknown ) == iid ) ||
769cdf0e10cSrcweir 		 ( __uuidof( IEnumFORMATETC ) == iid ) )
770cdf0e10cSrcweir 	{
771cdf0e10cSrcweir 		*ppvObject = static_cast< IUnknown* >( this );
772cdf0e10cSrcweir 		static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
773cdf0e10cSrcweir 		hr = S_OK;
774cdf0e10cSrcweir 	}
775cdf0e10cSrcweir 
776cdf0e10cSrcweir 	return hr;
777cdf0e10cSrcweir }
778cdf0e10cSrcweir 
779cdf0e10cSrcweir //----------------------------------------------------------------------------
780cdf0e10cSrcweir // IUnknown->AddRef
781cdf0e10cSrcweir //----------------------------------------------------------------------------
782cdf0e10cSrcweir 
783cdf0e10cSrcweir STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
784cdf0e10cSrcweir {
785cdf0e10cSrcweir 	// keep the dataobject alive
786cdf0e10cSrcweir 	m_lpUnkOuter->AddRef( );
787cdf0e10cSrcweir 	return InterlockedIncrement( &m_nRefCnt );
788cdf0e10cSrcweir }
789cdf0e10cSrcweir 
790cdf0e10cSrcweir //----------------------------------------------------------------------------
791cdf0e10cSrcweir // IUnknown->Release
792cdf0e10cSrcweir //----------------------------------------------------------------------------
793cdf0e10cSrcweir 
794cdf0e10cSrcweir STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
795cdf0e10cSrcweir {
796cdf0e10cSrcweir 	// release the outer dataobject
797cdf0e10cSrcweir 	m_lpUnkOuter->Release( );
798cdf0e10cSrcweir 
799cdf0e10cSrcweir 	ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
800cdf0e10cSrcweir 	if ( 0 == nRefCnt )
801cdf0e10cSrcweir 		delete this;
802cdf0e10cSrcweir 
803cdf0e10cSrcweir 	return nRefCnt;
804cdf0e10cSrcweir }
805cdf0e10cSrcweir 
806cdf0e10cSrcweir //----------------------------------------------------------------------------
807cdf0e10cSrcweir // IEnumFORMATETC->Next
808cdf0e10cSrcweir //----------------------------------------------------------------------------
809cdf0e10cSrcweir 
810cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Next( ULONG nRequested, LPFORMATETC lpDest, ULONG* lpFetched )
811cdf0e10cSrcweir {
812cdf0e10cSrcweir 	if ( ( nRequested < 1 ) ||
813cdf0e10cSrcweir 		 (( nRequested > 1 ) && ( NULL == lpFetched )) ||
814cdf0e10cSrcweir 		 IsBadWritePtr( lpDest, sizeof( FORMATETC ) * nRequested ) )
815cdf0e10cSrcweir 		return E_INVALIDARG;
816cdf0e10cSrcweir 
817cdf0e10cSrcweir 	sal_uInt32 nFetched = m_FormatEtcContainer.nextFormatEtc( lpDest, nRequested );
818cdf0e10cSrcweir 
819cdf0e10cSrcweir 	if ( NULL != lpFetched )
820cdf0e10cSrcweir 		*lpFetched = nFetched;
821cdf0e10cSrcweir 
822cdf0e10cSrcweir 	return (nFetched == nRequested) ? S_OK : S_FALSE;
823cdf0e10cSrcweir }
824cdf0e10cSrcweir 
825cdf0e10cSrcweir //----------------------------------------------------------------------------
826cdf0e10cSrcweir // IEnumFORMATETC->Skip
827cdf0e10cSrcweir //----------------------------------------------------------------------------
828cdf0e10cSrcweir 
829cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
830cdf0e10cSrcweir {
831cdf0e10cSrcweir 	return m_FormatEtcContainer.skipFormatEtc( celt ) ? S_OK : S_FALSE;
832cdf0e10cSrcweir }
833cdf0e10cSrcweir 
834cdf0e10cSrcweir //----------------------------------------------------------------------------
835cdf0e10cSrcweir // IEnumFORMATETC->Reset
836cdf0e10cSrcweir //----------------------------------------------------------------------------
837cdf0e10cSrcweir 
838cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Reset( )
839cdf0e10cSrcweir {
840cdf0e10cSrcweir 	m_FormatEtcContainer.beginEnumFormatEtc( );
841cdf0e10cSrcweir 	return S_OK;
842cdf0e10cSrcweir }
843cdf0e10cSrcweir 
844cdf0e10cSrcweir //----------------------------------------------------------------------------
845cdf0e10cSrcweir // IEnumFORMATETC->Clone
846cdf0e10cSrcweir //----------------------------------------------------------------------------
847cdf0e10cSrcweir 
848cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
849cdf0e10cSrcweir {
850cdf0e10cSrcweir 	if ( NULL == ppenum )
851cdf0e10cSrcweir 		return E_INVALIDARG;
852cdf0e10cSrcweir 
853cdf0e10cSrcweir 	*ppenum = new CEnumFormatEtc( m_lpUnkOuter, m_FormatEtcContainer );
854cdf0e10cSrcweir 	if ( NULL != ppenum )
855cdf0e10cSrcweir 		static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
856cdf0e10cSrcweir 
857cdf0e10cSrcweir 	return ( NULL != *ppenum ) ? S_OK : E_OUTOFMEMORY;
858cdf0e10cSrcweir }
859