Updated core
[LibreOffice.git] / sal / workben / clipboardwben / testcopy / XTDataObject.cxx
blob5408fe131c1c2852c81a2083023513c5ea859bbf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
24 #include <windows.h>
25 #include <ole2.h>
26 #include <memory>
28 //------------------------------------------------------------------------
29 // namespace directives
30 //------------------------------------------------------------------------
33 //============================================================================
34 // OTWrapperDataObject
35 //============================================================================
37 //------------------------------------------------------------------------
38 // ctor
39 //------------------------------------------------------------------------
41 CXTDataObject::CXTDataObject( LONG nRefCntInitVal ) :
42 m_nRefCnt( nRefCntInitVal )
46 //------------------------------------------------------------------------
47 // dtor
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 )
63 return E_INVALIDARG;
65 HRESULT hr = E_NOINTERFACE;
67 *ppvObject = NULL;
69 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
71 *ppvObject = static_cast< IUnknown* >( this );
72 ( (LPUNKNOWN)*ppvObject )->AddRef( );
73 hr = S_OK;
76 return hr;
79 //------------------------------------------------------------------------
80 // IUnknown->AddRef
81 //------------------------------------------------------------------------
83 STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
85 return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
88 //------------------------------------------------------------------------
89 // IUnknown->Release
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 ) );
99 if ( 0 == nRefCnt )
101 delete this;
104 return 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 ) )
120 return E_INVALIDARG;
122 HRESULT hr = E_FAIL;
124 if ( CF_TEXT == pFormatetc->cfFormat )
126 char buff[] = "Hello World, How are you!";
127 LPSTREAM lpStream;
129 hr = CreateStreamOnHGlobal( NULL, FALSE, &lpStream );
130 if ( SUCCEEDED( hr ) )
132 hr = lpStream->Write( buff, sizeof( buff ) * sizeof( char ), NULL );
133 if ( SUCCEEDED( hr ) )
135 HGLOBAL hGlob;
137 GetHGlobalFromStream( lpStream, &hGlob );
139 pmedium->tymed = TYMED_HGLOBAL;
140 pmedium->hGlobal = hGlob;
141 pmedium->pUnkForRelease = NULL;
143 lpStream->Release( );
144 hr = S_OK;
146 else
148 pmedium->tymed = TYMED_NULL;
151 else if ( CF_UNICODETEXT == pFormatetc->cfFormat )
153 WCHAR buff[] = L"Hello World, How are you!";
154 LPSTREAM lpStream;
156 hr = CreateStreamOnHGlobal( NULL, FALSE, &lpStream );
157 if ( SUCCEEDED( hr ) )
159 hr = lpStream->Write( buff, sizeof( buff ) * sizeof( WCHAR ), NULL );
160 if ( SUCCEEDED( hr ) )
162 HGLOBAL hGlob;
164 GetHGlobalFromStream( lpStream, &hGlob );
166 pmedium->tymed = TYMED_HGLOBAL;
167 pmedium->hGlobal = hGlob;
168 pmedium->pUnkForRelease = NULL;
170 lpStream->Release( );
171 hr = S_OK;
173 else
175 pmedium->tymed = TYMED_NULL;
179 return hr;
182 //------------------------------------------------------------------------
183 // IDataObject->EnumFormatEtc
184 //------------------------------------------------------------------------
186 STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
188 if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) )
189 return E_INVALIDARG;
191 *ppenumFormatetc = NULL;
193 HRESULT hr = E_FAIL;
195 if ( DATADIR_GET == dwDirection )
197 *ppenumFormatetc = new CEnumFormatEtc( this );
198 static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
199 hr = S_OK;
202 return hr;
205 //------------------------------------------------------------------------
206 // IDataObject->QueryGetData
207 //------------------------------------------------------------------------
209 STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
211 return E_NOTIMPL;
214 //------------------------------------------------------------------------
215 // IDataObject->GetDataHere
216 //------------------------------------------------------------------------
218 STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
220 return E_NOTIMPL;
223 //------------------------------------------------------------------------
224 // IDataObject->GetCanonicalFormatEtc
225 //------------------------------------------------------------------------
227 STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
229 return E_NOTIMPL;
232 //------------------------------------------------------------------------
233 // IDataObject->SetData
234 //------------------------------------------------------------------------
236 STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
238 return E_NOTIMPL;
241 //------------------------------------------------------------------------
242 // IDataObject->DAdvise
243 //------------------------------------------------------------------------
245 STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
247 return E_NOTIMPL;
250 //------------------------------------------------------------------------
251 // IDataObject->DUnadvise
252 //------------------------------------------------------------------------
254 STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
256 return E_NOTIMPL;
259 //------------------------------------------------------------------------
260 // IDataObject->EnumDAdvise
261 //------------------------------------------------------------------------
263 STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
265 return E_NOTIMPL;
268 //------------------------------------------------------------------------
269 // for our convenience
270 //------------------------------------------------------------------------
272 CXTDataObject::operator IDataObject*( )
274 return static_cast< IDataObject* >( this );
278 //============================================================================
279 // CEnumFormatEtc
280 //============================================================================
283 //----------------------------------------------------------------------------
284 // ctor
285 //----------------------------------------------------------------------------
287 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) :
288 m_nRefCnt( 0 ),
289 m_pUnkDataObj( pUnkDataObj ),
290 m_nCurrentPos( 0 )
292 m_cfFormats[0] = CF_UNICODETEXT;
293 m_cfFormats[1] = CF_TEXT;
296 //----------------------------------------------------------------------------
297 // dtor
298 //----------------------------------------------------------------------------
300 CEnumFormatEtc::~CEnumFormatEtc( )
304 //----------------------------------------------------------------------------
305 // IUnknown->QueryInterface
306 //----------------------------------------------------------------------------
308 STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
310 if ( NULL == ppvObject )
311 return E_INVALIDARG;
313 HRESULT hr = E_NOINTERFACE;
315 *ppvObject = NULL;
317 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) )
319 *ppvObject = static_cast< IUnknown* >( this );
320 static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
321 hr = S_OK;
324 return hr;
327 //----------------------------------------------------------------------------
328 // IUnknown->AddRef
329 //----------------------------------------------------------------------------
331 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
333 // keep the dataobject alive
334 m_pUnkDataObj->AddRef( );
335 return InterlockedIncrement( &m_nRefCnt );
338 //----------------------------------------------------------------------------
339 // IUnknown->Release
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 );
351 if ( 0 == nRefCnt )
352 delete this;
354 return 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 ) )
367 return E_INVALIDARG;
369 ULONG ulFetched = 0;
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];
378 rgelt->ptd = NULL;
379 rgelt->dwAspect = DVASPECT_CONTENT;
380 rgelt->lindex = -1;
381 rgelt->tymed = TYMED_HGLOBAL;
383 ++m_nCurrentPos;
384 ++rgelt;
385 --ulToFetch;
386 ++ulFetched;
389 if ( ulFetched == celt )
390 hr = S_OK;
392 if ( NULL != pceltFetched )
394 OSL_ASSERT( !IsBadWritePtr( (LPVOID)pceltFetched, sizeof( ULONG ) ) );
395 *pceltFetched = ulFetched;
398 return hr;
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;
412 hr = S_OK;
415 return hr;
418 //----------------------------------------------------------------------------
419 // IEnumFORMATETC->Reset
420 //----------------------------------------------------------------------------
422 STDMETHODIMP CEnumFormatEtc::Reset( )
424 m_nCurrentPos = 0;
425 return S_OK;
428 //----------------------------------------------------------------------------
429 // IEnumFORMATETC->Clone
430 //----------------------------------------------------------------------------
432 STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
434 OSL_ASSERT( NULL != ppenum );
436 if ( NULL == ppenum )
437 return E_INVALIDARG;
439 HRESULT hr = E_FAIL;
441 *ppenum = NULL;
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( );
449 hr = NOERROR;
452 return hr;
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */