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_sal.hxx"
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
37 #include <osl/diagnose.h>
39 #ifndef _TWRAPPERDATAOBJECT_HXX_
40 #include "XTDataObject.hxx"
47 //------------------------------------------------------------------------
48 // namespace directives
49 //------------------------------------------------------------------------
52 //============================================================================
53 // OTWrapperDataObject
54 //============================================================================
56 //------------------------------------------------------------------------
58 //------------------------------------------------------------------------
60 CXTDataObject::CXTDataObject( LONG nRefCntInitVal
) :
61 m_nRefCnt( nRefCntInitVal
)
65 //------------------------------------------------------------------------
67 //------------------------------------------------------------------------
69 CXTDataObject::~CXTDataObject( )
73 //------------------------------------------------------------------------
74 // IUnknown->QueryInterface
75 //------------------------------------------------------------------------
77 STDMETHODIMP
CXTDataObject::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
79 OSL_ASSERT( NULL
!= ppvObject
);
81 if ( NULL
== ppvObject
)
84 HRESULT hr
= E_NOINTERFACE
;
88 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IDataObject
) == iid
) )
90 *ppvObject
= static_cast< IUnknown
* >( this );
91 ( (LPUNKNOWN
)*ppvObject
)->AddRef( );
98 //------------------------------------------------------------------------
100 //------------------------------------------------------------------------
102 STDMETHODIMP_(ULONG
) CXTDataObject::AddRef( )
104 return static_cast< ULONG
>( InterlockedIncrement( &m_nRefCnt
) );
107 //------------------------------------------------------------------------
109 //------------------------------------------------------------------------
111 STDMETHODIMP_(ULONG
) CXTDataObject::Release( )
113 // we need a helper variable because it's
114 // not allowed to access a member variable
115 // after an object is destroyed
116 ULONG nRefCnt
= static_cast< ULONG
>( InterlockedDecrement( &m_nRefCnt
) );
126 //------------------------------------------------------------------------
127 // IDataObject->GetData
128 // warning: 'goto' ahead (to easy error handling without using exceptions)
129 //------------------------------------------------------------------------
131 STDMETHODIMP
CXTDataObject::GetData(LPFORMATETC pFormatetc
, LPSTGMEDIUM pmedium
)
133 OSL_ASSERT( ( NULL
!= pFormatetc
) &&
134 ( !IsBadReadPtr( (LPVOID
)pFormatetc
, sizeof( FORMATETC
) ) ) );
135 OSL_ASSERT( ( NULL
!= pmedium
) &&
136 ( !IsBadWritePtr( (LPVOID
)pmedium
, sizeof( STGMEDIUM
) ) ) );
138 if ( ( NULL
== pFormatetc
) || ( NULL
== pmedium
) )
143 if ( CF_TEXT
== pFormatetc
->cfFormat
)
145 char buff
[] = "Hello World, How are you!";
148 hr
= CreateStreamOnHGlobal( NULL
, FALSE
, &lpStream
);
149 if ( SUCCEEDED( hr
) )
151 hr
= lpStream
->Write( buff
, sizeof( buff
) * sizeof( char ), NULL
);
152 if ( SUCCEEDED( hr
) )
156 GetHGlobalFromStream( lpStream
, &hGlob
);
158 pmedium
->tymed
= TYMED_HGLOBAL
;
159 pmedium
->hGlobal
= hGlob
;
160 pmedium
->pUnkForRelease
= NULL
;
162 lpStream
->Release( );
167 pmedium
->tymed
= TYMED_NULL
;
170 else if ( CF_UNICODETEXT
== pFormatetc
->cfFormat
)
172 WCHAR buff
[] = L
"Hello World, How are you!";
175 hr
= CreateStreamOnHGlobal( NULL
, FALSE
, &lpStream
);
176 if ( SUCCEEDED( hr
) )
178 hr
= lpStream
->Write( buff
, sizeof( buff
) * sizeof( WCHAR
), NULL
);
179 if ( SUCCEEDED( hr
) )
183 GetHGlobalFromStream( lpStream
, &hGlob
);
185 pmedium
->tymed
= TYMED_HGLOBAL
;
186 pmedium
->hGlobal
= hGlob
;
187 pmedium
->pUnkForRelease
= NULL
;
189 lpStream
->Release( );
194 pmedium
->tymed
= TYMED_NULL
;
201 //------------------------------------------------------------------------
202 // IDataObject->EnumFormatEtc
203 //------------------------------------------------------------------------
205 STDMETHODIMP
CXTDataObject::EnumFormatEtc( DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatetc
)
207 if ( ( NULL
== ppenumFormatetc
) || ( DATADIR_SET
== dwDirection
) )
210 *ppenumFormatetc
= NULL
;
214 if ( DATADIR_GET
== dwDirection
)
216 *ppenumFormatetc
= new CEnumFormatEtc( this );
217 static_cast< LPUNKNOWN
>( *ppenumFormatetc
)->AddRef( );
224 //------------------------------------------------------------------------
225 // IDataObject->QueryGetData
226 //------------------------------------------------------------------------
228 STDMETHODIMP
CXTDataObject::QueryGetData( LPFORMATETC pFormatetc
)
233 //------------------------------------------------------------------------
234 // IDataObject->GetDataHere
235 //------------------------------------------------------------------------
237 STDMETHODIMP
CXTDataObject::GetDataHere( LPFORMATETC
, LPSTGMEDIUM
)
242 //------------------------------------------------------------------------
243 // IDataObject->GetCanonicalFormatEtc
244 //------------------------------------------------------------------------
246 STDMETHODIMP
CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC
, LPFORMATETC
)
251 //------------------------------------------------------------------------
252 // IDataObject->SetData
253 //------------------------------------------------------------------------
255 STDMETHODIMP
CXTDataObject::SetData( LPFORMATETC
, LPSTGMEDIUM
, BOOL
)
260 //------------------------------------------------------------------------
261 // IDataObject->DAdvise
262 //------------------------------------------------------------------------
264 STDMETHODIMP
CXTDataObject::DAdvise( LPFORMATETC
, DWORD
, LPADVISESINK
, DWORD
* )
269 //------------------------------------------------------------------------
270 // IDataObject->DUnadvise
271 //------------------------------------------------------------------------
273 STDMETHODIMP
CXTDataObject::DUnadvise( DWORD
)
278 //------------------------------------------------------------------------
279 // IDataObject->EnumDAdvise
280 //------------------------------------------------------------------------
282 STDMETHODIMP
CXTDataObject::EnumDAdvise( LPENUMSTATDATA
* )
287 //------------------------------------------------------------------------
288 // for our convenience
289 //------------------------------------------------------------------------
291 CXTDataObject::operator IDataObject
*( )
293 return static_cast< IDataObject
* >( this );
297 //============================================================================
299 //============================================================================
302 //----------------------------------------------------------------------------
304 //----------------------------------------------------------------------------
306 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj
) :
308 m_pUnkDataObj( pUnkDataObj
),
311 m_cfFormats
[0] = CF_UNICODETEXT
;
312 m_cfFormats
[1] = CF_TEXT
;
315 //----------------------------------------------------------------------------
317 //----------------------------------------------------------------------------
319 CEnumFormatEtc::~CEnumFormatEtc( )
323 //----------------------------------------------------------------------------
324 // IUnknown->QueryInterface
325 //----------------------------------------------------------------------------
327 STDMETHODIMP
CEnumFormatEtc::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
329 if ( NULL
== ppvObject
)
332 HRESULT hr
= E_NOINTERFACE
;
336 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IEnumFORMATETC
) == iid
) )
338 *ppvObject
= static_cast< IUnknown
* >( this );
339 static_cast< LPUNKNOWN
>( *ppvObject
)->AddRef( );
346 //----------------------------------------------------------------------------
348 //----------------------------------------------------------------------------
350 STDMETHODIMP_(ULONG
) CEnumFormatEtc::AddRef( )
352 // keep the dataobject alive
353 m_pUnkDataObj
->AddRef( );
354 return InterlockedIncrement( &m_nRefCnt
);
357 //----------------------------------------------------------------------------
359 //----------------------------------------------------------------------------
361 STDMETHODIMP_(ULONG
) CEnumFormatEtc::Release( )
363 // release the outer dataobject
364 m_pUnkDataObj
->Release( );
366 // we need a helper variable because it's
367 // not allowed to access a member variable
368 // after an object is destroyed
369 ULONG nRefCnt
= InterlockedDecrement( &m_nRefCnt
);
376 //----------------------------------------------------------------------------
377 // IEnumFORMATETC->Next
378 //----------------------------------------------------------------------------
380 STDMETHODIMP
CEnumFormatEtc::Next( ULONG celt
, LPFORMATETC rgelt
, ULONG
* pceltFetched
)
382 OSL_ASSERT( ( ( celt
> 0 ) && ( NULL
!= rgelt
) ) ||
383 ( ( 0 == celt
) && ( NULL
== rgelt
) ) );
385 if ( ( 0 != celt
) && ( NULL
== rgelt
) )
389 ULONG ulToFetch
= celt
;
390 HRESULT hr
= S_FALSE
;
392 while( ( m_nCurrentPos
< sizeof( m_cfFormats
) ) && ( ulToFetch
> 0 ) )
394 OSL_ASSERT( !IsBadWritePtr( (LPVOID
)rgelt
, sizeof( FORMATETC
) ) );
396 rgelt
->cfFormat
= m_cfFormats
[m_nCurrentPos
];
398 rgelt
->dwAspect
= DVASPECT_CONTENT
;
400 rgelt
->tymed
= TYMED_HGLOBAL
;
408 if ( ulFetched
== celt
)
411 if ( NULL
!= pceltFetched
)
413 OSL_ASSERT( !IsBadWritePtr( (LPVOID
)pceltFetched
, sizeof( ULONG
) ) );
414 *pceltFetched
= ulFetched
;
420 //----------------------------------------------------------------------------
421 // IEnumFORMATETC->Skip
422 //----------------------------------------------------------------------------
424 STDMETHODIMP
CEnumFormatEtc::Skip( ULONG celt
)
426 HRESULT hr
= S_FALSE
;
428 if ( ( m_nCurrentPos
+ celt
) < sizeof( m_cfFormats
) )
430 m_nCurrentPos
+= celt
;
437 //----------------------------------------------------------------------------
438 // IEnumFORMATETC->Reset
439 //----------------------------------------------------------------------------
441 STDMETHODIMP
CEnumFormatEtc::Reset( )
447 //----------------------------------------------------------------------------
448 // IEnumFORMATETC->Clone
449 //----------------------------------------------------------------------------
451 STDMETHODIMP
CEnumFormatEtc::Clone( IEnumFORMATETC
** ppenum
)
453 OSL_ASSERT( NULL
!= ppenum
);
455 if ( NULL
== ppenum
)
462 CEnumFormatEtc
* pCEnumFEtc
= new CEnumFormatEtc( m_pUnkDataObj
);
463 if ( NULL
!= pCEnumFEtc
)
465 pCEnumFEtc
->m_nCurrentPos
= m_nCurrentPos
;
466 *ppenum
= static_cast< IEnumFORMATETC
* >( pCEnumFEtc
);
467 static_cast< LPUNKNOWN
>( *ppenum
)->AddRef( );