1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
28 //------------------------------------------------------------------------
29 // namespace directives
30 //------------------------------------------------------------------------
33 //============================================================================
34 // OTWrapperDataObject
35 //============================================================================
37 //------------------------------------------------------------------------
39 //------------------------------------------------------------------------
41 CXTDataObject::CXTDataObject( LONG nRefCntInitVal
) :
42 m_nRefCnt( nRefCntInitVal
)
46 //------------------------------------------------------------------------
48 //------------------------------------------------------------------------
50 CXTDataObject::~CXTDataObject( )
54 //------------------------------------------------------------------------
55 // IUnknown->QueryInterface
56 //------------------------------------------------------------------------
58 STDMETHODIMP
CXTDataObject::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
60 OSL_ASSERT( NULL
!= ppvObject
);
62 if ( NULL
== ppvObject
)
65 HRESULT hr
= E_NOINTERFACE
;
69 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IDataObject
) == iid
) )
71 *ppvObject
= static_cast< IUnknown
* >( this );
72 ( (LPUNKNOWN
)*ppvObject
)->AddRef( );
79 //------------------------------------------------------------------------
81 //------------------------------------------------------------------------
83 STDMETHODIMP_(ULONG
) CXTDataObject::AddRef( )
85 return static_cast< ULONG
>( InterlockedIncrement( &m_nRefCnt
) );
88 //------------------------------------------------------------------------
90 //------------------------------------------------------------------------
92 STDMETHODIMP_(ULONG
) CXTDataObject::Release( )
94 // we need a helper variable because it's
95 // not allowed to access a member variable
96 // after an object is destroyed
97 ULONG nRefCnt
= static_cast< ULONG
>( InterlockedDecrement( &m_nRefCnt
) );
107 //------------------------------------------------------------------------
108 // IDataObject->GetData
109 // warning: 'goto' ahead (to easy error handling without using exceptions)
110 //------------------------------------------------------------------------
112 STDMETHODIMP
CXTDataObject::GetData(LPFORMATETC pFormatetc
, LPSTGMEDIUM pmedium
)
114 OSL_ASSERT( ( NULL
!= pFormatetc
) &&
115 ( !IsBadReadPtr( (LPVOID
)pFormatetc
, sizeof( FORMATETC
) ) ) );
116 OSL_ASSERT( ( NULL
!= pmedium
) &&
117 ( !IsBadWritePtr( (LPVOID
)pmedium
, sizeof( STGMEDIUM
) ) ) );
119 if ( ( NULL
== pFormatetc
) || ( NULL
== pmedium
) )
124 if ( CF_TEXT
== pFormatetc
->cfFormat
)
126 char buff
[] = "Hello World, How are you!";
129 hr
= CreateStreamOnHGlobal( NULL
, FALSE
, &lpStream
);
130 if ( SUCCEEDED( hr
) )
132 hr
= lpStream
->Write( buff
, sizeof( buff
) * sizeof( char ), NULL
);
133 if ( SUCCEEDED( hr
) )
137 GetHGlobalFromStream( lpStream
, &hGlob
);
139 pmedium
->tymed
= TYMED_HGLOBAL
;
140 pmedium
->hGlobal
= hGlob
;
141 pmedium
->pUnkForRelease
= NULL
;
143 lpStream
->Release( );
148 pmedium
->tymed
= TYMED_NULL
;
151 else if ( CF_UNICODETEXT
== pFormatetc
->cfFormat
)
153 WCHAR buff
[] = L
"Hello World, How are you!";
156 hr
= CreateStreamOnHGlobal( NULL
, FALSE
, &lpStream
);
157 if ( SUCCEEDED( hr
) )
159 hr
= lpStream
->Write( buff
, sizeof( buff
) * sizeof( WCHAR
), NULL
);
160 if ( SUCCEEDED( hr
) )
164 GetHGlobalFromStream( lpStream
, &hGlob
);
166 pmedium
->tymed
= TYMED_HGLOBAL
;
167 pmedium
->hGlobal
= hGlob
;
168 pmedium
->pUnkForRelease
= NULL
;
170 lpStream
->Release( );
175 pmedium
->tymed
= TYMED_NULL
;
182 //------------------------------------------------------------------------
183 // IDataObject->EnumFormatEtc
184 //------------------------------------------------------------------------
186 STDMETHODIMP
CXTDataObject::EnumFormatEtc( DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatetc
)
188 if ( ( NULL
== ppenumFormatetc
) || ( DATADIR_SET
== dwDirection
) )
191 *ppenumFormatetc
= NULL
;
195 if ( DATADIR_GET
== dwDirection
)
197 *ppenumFormatetc
= new CEnumFormatEtc( this );
198 static_cast< LPUNKNOWN
>( *ppenumFormatetc
)->AddRef( );
205 //------------------------------------------------------------------------
206 // IDataObject->QueryGetData
207 //------------------------------------------------------------------------
209 STDMETHODIMP
CXTDataObject::QueryGetData( LPFORMATETC pFormatetc
)
214 //------------------------------------------------------------------------
215 // IDataObject->GetDataHere
216 //------------------------------------------------------------------------
218 STDMETHODIMP
CXTDataObject::GetDataHere( LPFORMATETC
, LPSTGMEDIUM
)
223 //------------------------------------------------------------------------
224 // IDataObject->GetCanonicalFormatEtc
225 //------------------------------------------------------------------------
227 STDMETHODIMP
CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC
, LPFORMATETC
)
232 //------------------------------------------------------------------------
233 // IDataObject->SetData
234 //------------------------------------------------------------------------
236 STDMETHODIMP
CXTDataObject::SetData( LPFORMATETC
, LPSTGMEDIUM
, BOOL
)
241 //------------------------------------------------------------------------
242 // IDataObject->DAdvise
243 //------------------------------------------------------------------------
245 STDMETHODIMP
CXTDataObject::DAdvise( LPFORMATETC
, DWORD
, LPADVISESINK
, DWORD
* )
250 //------------------------------------------------------------------------
251 // IDataObject->DUnadvise
252 //------------------------------------------------------------------------
254 STDMETHODIMP
CXTDataObject::DUnadvise( DWORD
)
259 //------------------------------------------------------------------------
260 // IDataObject->EnumDAdvise
261 //------------------------------------------------------------------------
263 STDMETHODIMP
CXTDataObject::EnumDAdvise( LPENUMSTATDATA
* )
268 //------------------------------------------------------------------------
269 // for our convenience
270 //------------------------------------------------------------------------
272 CXTDataObject::operator IDataObject
*( )
274 return static_cast< IDataObject
* >( this );
278 //============================================================================
280 //============================================================================
283 //----------------------------------------------------------------------------
285 //----------------------------------------------------------------------------
287 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj
) :
289 m_pUnkDataObj( pUnkDataObj
),
292 m_cfFormats
[0] = CF_UNICODETEXT
;
293 m_cfFormats
[1] = CF_TEXT
;
296 //----------------------------------------------------------------------------
298 //----------------------------------------------------------------------------
300 CEnumFormatEtc::~CEnumFormatEtc( )
304 //----------------------------------------------------------------------------
305 // IUnknown->QueryInterface
306 //----------------------------------------------------------------------------
308 STDMETHODIMP
CEnumFormatEtc::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
310 if ( NULL
== ppvObject
)
313 HRESULT hr
= E_NOINTERFACE
;
317 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IEnumFORMATETC
) == iid
) )
319 *ppvObject
= static_cast< IUnknown
* >( this );
320 static_cast< LPUNKNOWN
>( *ppvObject
)->AddRef( );
327 //----------------------------------------------------------------------------
329 //----------------------------------------------------------------------------
331 STDMETHODIMP_(ULONG
) CEnumFormatEtc::AddRef( )
333 // keep the dataobject alive
334 m_pUnkDataObj
->AddRef( );
335 return InterlockedIncrement( &m_nRefCnt
);
338 //----------------------------------------------------------------------------
340 //----------------------------------------------------------------------------
342 STDMETHODIMP_(ULONG
) CEnumFormatEtc::Release( )
344 // release the outer dataobject
345 m_pUnkDataObj
->Release( );
347 // we need a helper variable because it's
348 // not allowed to access a member variable
349 // after an object is destroyed
350 ULONG nRefCnt
= InterlockedDecrement( &m_nRefCnt
);
357 //----------------------------------------------------------------------------
358 // IEnumFORMATETC->Next
359 //----------------------------------------------------------------------------
361 STDMETHODIMP
CEnumFormatEtc::Next( ULONG celt
, LPFORMATETC rgelt
, ULONG
* pceltFetched
)
363 OSL_ASSERT( ( ( celt
> 0 ) && ( NULL
!= rgelt
) ) ||
364 ( ( 0 == celt
) && ( NULL
== rgelt
) ) );
366 if ( ( 0 != celt
) && ( NULL
== rgelt
) )
370 ULONG ulToFetch
= celt
;
371 HRESULT hr
= S_FALSE
;
373 while( ( m_nCurrentPos
< sizeof( m_cfFormats
) ) && ( ulToFetch
> 0 ) )
375 OSL_ASSERT( !IsBadWritePtr( (LPVOID
)rgelt
, sizeof( FORMATETC
) ) );
377 rgelt
->cfFormat
= m_cfFormats
[m_nCurrentPos
];
379 rgelt
->dwAspect
= DVASPECT_CONTENT
;
381 rgelt
->tymed
= TYMED_HGLOBAL
;
389 if ( ulFetched
== celt
)
392 if ( NULL
!= pceltFetched
)
394 OSL_ASSERT( !IsBadWritePtr( (LPVOID
)pceltFetched
, sizeof( ULONG
) ) );
395 *pceltFetched
= ulFetched
;
401 //----------------------------------------------------------------------------
402 // IEnumFORMATETC->Skip
403 //----------------------------------------------------------------------------
405 STDMETHODIMP
CEnumFormatEtc::Skip( ULONG celt
)
407 HRESULT hr
= S_FALSE
;
409 if ( ( m_nCurrentPos
+ celt
) < sizeof( m_cfFormats
) )
411 m_nCurrentPos
+= celt
;
418 //----------------------------------------------------------------------------
419 // IEnumFORMATETC->Reset
420 //----------------------------------------------------------------------------
422 STDMETHODIMP
CEnumFormatEtc::Reset( )
428 //----------------------------------------------------------------------------
429 // IEnumFORMATETC->Clone
430 //----------------------------------------------------------------------------
432 STDMETHODIMP
CEnumFormatEtc::Clone( IEnumFORMATETC
** ppenum
)
434 OSL_ASSERT( NULL
!= ppenum
);
436 if ( NULL
== ppenum
)
443 CEnumFormatEtc
* pCEnumFEtc
= new CEnumFormatEtc( m_pUnkDataObj
);
444 if ( NULL
!= pCEnumFEtc
)
446 pCEnumFEtc
->m_nCurrentPos
= m_nCurrentPos
;
447 *ppenum
= static_cast< IEnumFORMATETC
* >( pCEnumFEtc
);
448 static_cast< LPUNKNOWN
>( *ppenum
)->AddRef( );
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */