update dev300-m58
[ooovba.git] / dtrans / source / win32 / dtobj / APNDataObject.cxx
blob249822105bfa9f36c67f088c5654ca3a35a6b62b
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: APNDataObject.cxx,v $
10 * $Revision: 1.9 $
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_dtrans.hxx"
34 //------------------------------------------------------------------------
35 // includes
36 //------------------------------------------------------------------------
37 #include "APNDataObject.hxx"
38 #include <osl/diagnose.h>
40 #include <systools/win32/comtools.hxx>
41 #ifdef __MINGW32__
42 #define __uuidof(I) IID_##I
43 #endif
45 //------------------------------------------------------------------------
46 // defines
47 //------------------------------------------------------------------------
49 #define FREE_HGLOB_ON_RELEASE TRUE
50 #define KEEP_HGLOB_ON_RELEASE FALSE
52 //------------------------------------------------------------------------
53 // ctor
54 //------------------------------------------------------------------------
56 CAPNDataObject::CAPNDataObject( IDataObjectPtr rIDataObject ) :
57 m_rIDataObjectOrg( rIDataObject ),
58 m_hGlobal( NULL ),
59 m_nRefCnt( 0 )
62 OSL_ENSURE( m_rIDataObjectOrg.get( ), "constructing CAPNDataObject with empty data object" );
64 // we marshal the IDataObject interface pointer here so
65 // that it can be unmarshaled multiple times when this
66 // class will be used from another apartment
67 IStreamPtr pStm;
68 HRESULT hr = CreateStreamOnHGlobal( 0, KEEP_HGLOB_ON_RELEASE, &pStm );
70 OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
72 if ( SUCCEEDED( hr ) )
74 HRESULT hr_marshal = CoMarshalInterface(
75 pStm.get(),
76 __uuidof(IDataObject),
77 static_cast<LPUNKNOWN>(m_rIDataObjectOrg.get()),
78 MSHCTX_LOCAL,
79 NULL,
80 MSHLFLAGS_TABLEWEAK );
82 OSL_ENSURE( CO_E_NOTINITIALIZED != hr_marshal, "COM is not initialized" );
84 // marshalling may fail if COM is not initialized
85 // for the calling thread which is a program time
86 // error or because of stream errors which are runtime
87 // errors for instance E_OUTOFMEMORY etc.
89 hr = GetHGlobalFromStream(pStm.get(), &m_hGlobal );
91 OSL_ENSURE( E_INVALIDARG != hr, "invalid stream passed to GetHGlobalFromStream" );
93 // if the marshalling failed we free the
94 // global memory again and set m_hGlobal
95 // to a defined value
96 if (FAILED(hr_marshal))
98 OSL_ENSURE(sal_False, "marshalling failed");
100 #if OSL_DEBUG_LEVEL > 0
101 HGLOBAL hGlobal =
102 #endif
103 GlobalFree(m_hGlobal);
104 OSL_ENSURE(NULL == hGlobal, "GlobalFree failed");
105 m_hGlobal = NULL;
110 CAPNDataObject::~CAPNDataObject( )
112 if (m_hGlobal)
114 IStreamPtr pStm;
115 HRESULT hr = CreateStreamOnHGlobal(m_hGlobal, FREE_HGLOB_ON_RELEASE, &pStm);
117 OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
119 if (SUCCEEDED(hr))
121 hr = CoReleaseMarshalData(pStm.get());
122 OSL_ENSURE(SUCCEEDED(hr), "CoReleaseMarshalData failed");
127 //------------------------------------------------------------------------
128 // IUnknown->QueryInterface
129 //------------------------------------------------------------------------
131 STDMETHODIMP CAPNDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
133 OSL_ASSERT( NULL != ppvObject );
135 if ( NULL == ppvObject )
136 return E_INVALIDARG;
138 HRESULT hr = E_NOINTERFACE;
139 *ppvObject = NULL;
141 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
143 *ppvObject = static_cast< IUnknown* >( this );
144 ( (LPUNKNOWN)*ppvObject )->AddRef( );
145 hr = S_OK;
148 return hr;
151 //------------------------------------------------------------------------
152 // IUnknown->AddRef
153 //------------------------------------------------------------------------
155 STDMETHODIMP_(ULONG) CAPNDataObject::AddRef( )
157 return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
160 //------------------------------------------------------------------------
161 // IUnknown->Release
162 //------------------------------------------------------------------------
164 STDMETHODIMP_(ULONG) CAPNDataObject::Release( )
166 // we need a helper variable because it's not allowed to access
167 // a member variable after an object is destroyed
168 ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
170 if ( 0 == nRefCnt )
171 delete this;
173 return nRefCnt;
176 //------------------------------------------------------------------------
177 // IDataObject->GetData
178 //------------------------------------------------------------------------
180 STDMETHODIMP CAPNDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
182 HRESULT hr = m_rIDataObjectOrg->GetData( pFormatetc, pmedium );
184 if (RPC_E_WRONG_THREAD == hr)
186 IDataObjectPtr pIDOTmp;
187 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
189 if (SUCCEEDED(hr))
190 hr = pIDOTmp->GetData(pFormatetc, pmedium);
192 return hr;
195 //------------------------------------------------------------------------
196 // IDataObject->EnumFormatEtc
197 //------------------------------------------------------------------------
199 STDMETHODIMP CAPNDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
201 HRESULT hr = m_rIDataObjectOrg->EnumFormatEtc(dwDirection, ppenumFormatetc);
203 if (RPC_E_WRONG_THREAD == hr)
205 IDataObjectPtr pIDOTmp;
206 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
208 if (SUCCEEDED(hr))
209 hr = pIDOTmp->EnumFormatEtc(dwDirection, ppenumFormatetc);
211 return hr;
214 //------------------------------------------------------------------------
215 // IDataObject->QueryGetData
216 //------------------------------------------------------------------------
218 STDMETHODIMP CAPNDataObject::QueryGetData( LPFORMATETC pFormatetc )
220 HRESULT hr = m_rIDataObjectOrg->QueryGetData( pFormatetc );
222 if (RPC_E_WRONG_THREAD == hr)
224 IDataObjectPtr pIDOTmp;
225 hr = MarshalIDataObjectIntoCurrentApartment( &pIDOTmp );
227 if (SUCCEEDED(hr))
228 hr = pIDOTmp->QueryGetData(pFormatetc);
230 return hr;
233 //------------------------------------------------------------------------
234 // IDataObject->GetDataHere
235 //------------------------------------------------------------------------
237 STDMETHODIMP CAPNDataObject::GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
239 HRESULT hr = m_rIDataObjectOrg->GetDataHere(pFormatetc, pmedium);
241 if (RPC_E_WRONG_THREAD == hr)
243 IDataObjectPtr pIDOTmp;
244 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
246 if (SUCCEEDED(hr))
247 hr = pIDOTmp->GetDataHere(pFormatetc, pmedium);
249 return hr;
252 //------------------------------------------------------------------------
253 // IDataObject->GetCanonicalFormatEtc
254 //------------------------------------------------------------------------
256 STDMETHODIMP CAPNDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut)
258 HRESULT hr = m_rIDataObjectOrg->GetCanonicalFormatEtc( pFormatectIn, pFormatetcOut );
260 if (RPC_E_WRONG_THREAD == hr)
262 IDataObjectPtr pIDOTmp;
263 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
265 if (SUCCEEDED(hr))
266 hr = pIDOTmp->GetCanonicalFormatEtc(pFormatectIn, pFormatetcOut);
268 return hr;
271 //------------------------------------------------------------------------
272 // IDataObject->SetData
273 //------------------------------------------------------------------------
275 STDMETHODIMP CAPNDataObject::SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease )
277 HRESULT hr = m_rIDataObjectOrg->SetData( pFormatetc, pmedium, fRelease );
279 if (RPC_E_WRONG_THREAD == hr)
281 IDataObjectPtr pIDOTmp;
282 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
284 if (SUCCEEDED(hr))
285 hr = pIDOTmp->SetData(pFormatetc, pmedium, fRelease);
287 return hr;
290 //------------------------------------------------------------------------
291 // IDataObject->DAdvise
292 //------------------------------------------------------------------------
294 STDMETHODIMP CAPNDataObject::DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD * pdwConnection )
296 HRESULT hr = m_rIDataObjectOrg->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
298 if (RPC_E_WRONG_THREAD == hr)
300 IDataObjectPtr pIDOTmp;
301 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
303 if (SUCCEEDED(hr))
304 hr = pIDOTmp->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
306 return hr;
309 //------------------------------------------------------------------------
310 // IDataObject->DUnadvise
311 //------------------------------------------------------------------------
313 STDMETHODIMP CAPNDataObject::DUnadvise( DWORD dwConnection )
315 HRESULT hr = m_rIDataObjectOrg->DUnadvise( dwConnection );
317 if (RPC_E_WRONG_THREAD == hr)
319 IDataObjectPtr pIDOTmp;
320 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
322 if (SUCCEEDED(hr))
323 hr = pIDOTmp->DUnadvise(dwConnection);
325 return hr;
328 //------------------------------------------------------------------------
329 // IDataObject->EnumDAdvise
330 //------------------------------------------------------------------------
332 STDMETHODIMP CAPNDataObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise )
334 HRESULT hr = m_rIDataObjectOrg->EnumDAdvise(ppenumAdvise);
336 if (RPC_E_WRONG_THREAD == hr)
338 IDataObjectPtr pIDOTmp;
339 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
341 if (SUCCEEDED(hr))
342 hr = pIDOTmp->EnumDAdvise(ppenumAdvise);
344 return hr;
347 //------------------------------------------------------------------------
348 // for our convenience
349 //------------------------------------------------------------------------
351 CAPNDataObject::operator IDataObject*( )
353 return static_cast< IDataObject* >( this );
356 //------------------------------------------------------------------------
357 // helper function
358 //------------------------------------------------------------------------
360 HRESULT CAPNDataObject::MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj )
362 OSL_ASSERT(NULL != ppIDataObj);
364 *ppIDataObj = NULL;
365 HRESULT hr = E_FAIL;
367 if (m_hGlobal)
369 IStreamPtr pStm;
370 hr = CreateStreamOnHGlobal(m_hGlobal, KEEP_HGLOB_ON_RELEASE, &pStm);
372 OSL_ENSURE(E_INVALIDARG != hr, "CreateStreamOnHGlobal with invalid args called");
374 if (SUCCEEDED(hr))
376 hr = CoUnmarshalInterface(pStm.get(), __uuidof(IDataObject), (void**)ppIDataObj);
377 OSL_ENSURE(CO_E_NOTINITIALIZED != hr, "COM is not initialized");
380 return hr;