update dev300-m57
[ooovba.git] / sal / workben / clipboardwben / testcopy / XTDataObject.cxx
blob5b69c1127b7b5623c6d1cad84e8de36175f58df3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XTDataObject.cxx,v $
10 * $Revision: 1.6 $
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 //------------------------------------------------------------------------
35 // includes
36 //------------------------------------------------------------------------
37 #include <osl/diagnose.h>
39 #ifndef _TWRAPPERDATAOBJECT_HXX_
40 #include "XTDataObject.hxx"
41 #endif
43 #include <windows.h>
44 #include <ole2.h>
45 #include <memory>
47 //------------------------------------------------------------------------
48 // namespace directives
49 //------------------------------------------------------------------------
52 //============================================================================
53 // OTWrapperDataObject
54 //============================================================================
56 //------------------------------------------------------------------------
57 // ctor
58 //------------------------------------------------------------------------
60 CXTDataObject::CXTDataObject( LONG nRefCntInitVal ) :
61 m_nRefCnt( nRefCntInitVal )
65 //------------------------------------------------------------------------
66 // dtor
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 )
82 return E_INVALIDARG;
84 HRESULT hr = E_NOINTERFACE;
86 *ppvObject = NULL;
88 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
90 *ppvObject = static_cast< IUnknown* >( this );
91 ( (LPUNKNOWN)*ppvObject )->AddRef( );
92 hr = S_OK;
95 return hr;
98 //------------------------------------------------------------------------
99 // IUnknown->AddRef
100 //------------------------------------------------------------------------
102 STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
104 return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
107 //------------------------------------------------------------------------
108 // IUnknown->Release
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 ) );
118 if ( 0 == nRefCnt )
120 delete this;
123 return 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 ) )
139 return E_INVALIDARG;
141 HRESULT hr = E_FAIL;
143 if ( CF_TEXT == pFormatetc->cfFormat )
145 char buff[] = "Hello World, How are you!";
146 LPSTREAM lpStream;
148 hr = CreateStreamOnHGlobal( NULL, FALSE, &lpStream );
149 if ( SUCCEEDED( hr ) )
151 hr = lpStream->Write( buff, sizeof( buff ) * sizeof( char ), NULL );
152 if ( SUCCEEDED( hr ) )
154 HGLOBAL hGlob;
156 GetHGlobalFromStream( lpStream, &hGlob );
158 pmedium->tymed = TYMED_HGLOBAL;
159 pmedium->hGlobal = hGlob;
160 pmedium->pUnkForRelease = NULL;
162 lpStream->Release( );
163 hr = S_OK;
165 else
167 pmedium->tymed = TYMED_NULL;
170 else if ( CF_UNICODETEXT == pFormatetc->cfFormat )
172 WCHAR buff[] = L"Hello World, How are you!";
173 LPSTREAM lpStream;
175 hr = CreateStreamOnHGlobal( NULL, FALSE, &lpStream );
176 if ( SUCCEEDED( hr ) )
178 hr = lpStream->Write( buff, sizeof( buff ) * sizeof( WCHAR ), NULL );
179 if ( SUCCEEDED( hr ) )
181 HGLOBAL hGlob;
183 GetHGlobalFromStream( lpStream, &hGlob );
185 pmedium->tymed = TYMED_HGLOBAL;
186 pmedium->hGlobal = hGlob;
187 pmedium->pUnkForRelease = NULL;
189 lpStream->Release( );
190 hr = S_OK;
192 else
194 pmedium->tymed = TYMED_NULL;
198 return hr;
201 //------------------------------------------------------------------------
202 // IDataObject->EnumFormatEtc
203 //------------------------------------------------------------------------
205 STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
207 if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) )
208 return E_INVALIDARG;
210 *ppenumFormatetc = NULL;
212 HRESULT hr = E_FAIL;
214 if ( DATADIR_GET == dwDirection )
216 *ppenumFormatetc = new CEnumFormatEtc( this );
217 static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
218 hr = S_OK;
221 return hr;
224 //------------------------------------------------------------------------
225 // IDataObject->QueryGetData
226 //------------------------------------------------------------------------
228 STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
230 return E_NOTIMPL;
233 //------------------------------------------------------------------------
234 // IDataObject->GetDataHere
235 //------------------------------------------------------------------------
237 STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
239 return E_NOTIMPL;
242 //------------------------------------------------------------------------
243 // IDataObject->GetCanonicalFormatEtc
244 //------------------------------------------------------------------------
246 STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
248 return E_NOTIMPL;
251 //------------------------------------------------------------------------
252 // IDataObject->SetData
253 //------------------------------------------------------------------------
255 STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
257 return E_NOTIMPL;
260 //------------------------------------------------------------------------
261 // IDataObject->DAdvise
262 //------------------------------------------------------------------------
264 STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
266 return E_NOTIMPL;
269 //------------------------------------------------------------------------
270 // IDataObject->DUnadvise
271 //------------------------------------------------------------------------
273 STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
275 return E_NOTIMPL;
278 //------------------------------------------------------------------------
279 // IDataObject->EnumDAdvise
280 //------------------------------------------------------------------------
282 STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
284 return E_NOTIMPL;
287 //------------------------------------------------------------------------
288 // for our convenience
289 //------------------------------------------------------------------------
291 CXTDataObject::operator IDataObject*( )
293 return static_cast< IDataObject* >( this );
297 //============================================================================
298 // CEnumFormatEtc
299 //============================================================================
302 //----------------------------------------------------------------------------
303 // ctor
304 //----------------------------------------------------------------------------
306 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) :
307 m_nRefCnt( 0 ),
308 m_pUnkDataObj( pUnkDataObj ),
309 m_nCurrentPos( 0 )
311 m_cfFormats[0] = CF_UNICODETEXT;
312 m_cfFormats[1] = CF_TEXT;
315 //----------------------------------------------------------------------------
316 // dtor
317 //----------------------------------------------------------------------------
319 CEnumFormatEtc::~CEnumFormatEtc( )
323 //----------------------------------------------------------------------------
324 // IUnknown->QueryInterface
325 //----------------------------------------------------------------------------
327 STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
329 if ( NULL == ppvObject )
330 return E_INVALIDARG;
332 HRESULT hr = E_NOINTERFACE;
334 *ppvObject = NULL;
336 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) )
338 *ppvObject = static_cast< IUnknown* >( this );
339 static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
340 hr = S_OK;
343 return hr;
346 //----------------------------------------------------------------------------
347 // IUnknown->AddRef
348 //----------------------------------------------------------------------------
350 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
352 // keep the dataobject alive
353 m_pUnkDataObj->AddRef( );
354 return InterlockedIncrement( &m_nRefCnt );
357 //----------------------------------------------------------------------------
358 // IUnknown->Release
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 );
370 if ( 0 == nRefCnt )
371 delete this;
373 return 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 ) )
386 return E_INVALIDARG;
388 ULONG ulFetched = 0;
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];
397 rgelt->ptd = NULL;
398 rgelt->dwAspect = DVASPECT_CONTENT;
399 rgelt->lindex = -1;
400 rgelt->tymed = TYMED_HGLOBAL;
402 ++m_nCurrentPos;
403 ++rgelt;
404 --ulToFetch;
405 ++ulFetched;
408 if ( ulFetched == celt )
409 hr = S_OK;
411 if ( NULL != pceltFetched )
413 OSL_ASSERT( !IsBadWritePtr( (LPVOID)pceltFetched, sizeof( ULONG ) ) );
414 *pceltFetched = ulFetched;
417 return hr;
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;
431 hr = S_OK;
434 return hr;
437 //----------------------------------------------------------------------------
438 // IEnumFORMATETC->Reset
439 //----------------------------------------------------------------------------
441 STDMETHODIMP CEnumFormatEtc::Reset( )
443 m_nCurrentPos = 0;
444 return S_OK;
447 //----------------------------------------------------------------------------
448 // IEnumFORMATETC->Clone
449 //----------------------------------------------------------------------------
451 STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
453 OSL_ASSERT( NULL != ppenum );
455 if ( NULL == ppenum )
456 return E_INVALIDARG;
458 HRESULT hr = E_FAIL;
460 *ppenum = NULL;
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( );
468 hr = NOERROR;
471 return hr;