xref: /trunk/main/dtrans/source/win32/workbench/XTDo.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dtrans.hxx"
30 
31 //------------------------------------------------------------------------
32 // includes
33 //------------------------------------------------------------------------
34 #include <osl/diagnose.h>
35 
36 #include "..\DTransHelper.hxx"
37 
38 #ifndef _TWRAPPERDATAOBJECT_HXX_
39 #include "XTDo.hxx"
40 #endif
41 
42 #if defined _MSC_VER
43 #pragma warning(push,1)
44 #endif
45 #include <windows.h>
46 #include <ole2.h>
47 #if defined _MSC_VER
48 #pragma warning(pop)
49 #endif
50 #include <memory>
51 #include <tchar.h>
52 
53 //------------------------------------------------------------------------
54 // namespace directives
55 //------------------------------------------------------------------------
56 
57 using namespace ::std;
58 
59 //============================================================================
60 // OTWrapperDataObject
61 //============================================================================
62 
63 //------------------------------------------------------------------------
64 // ctor
65 //------------------------------------------------------------------------
66 /*
67     in the constructor we enumerate all formats offered by the transferable
68     and convert the formats into formatetc structures
69     if the transferable supports text in different charsets we use either
70     the charset equal to the charset of the current thread or an arbitrary
71     charset supported by the transferable and the system
72     if the transferable supports only unicodetext we offer in addition to
73     this text in the charset of the current thread
74     in order to allow the consumer of the clipboard to query for the charset
75     of the text in the clipboard we offer a CF_LOCALE
76 */
77 CXTDataObject::CXTDataObject( ) :
78     m_nRefCnt( 0 )
79 {
80 
81 }
82 
83 //------------------------------------------------------------------------
84 // IUnknown->QueryInterface
85 //------------------------------------------------------------------------
86 
87 STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
88 {
89     OSL_ASSERT( NULL != ppvObject );
90 
91     if ( NULL == ppvObject )
92         return E_INVALIDARG;
93 
94     HRESULT hr = E_NOINTERFACE;
95 
96     *ppvObject = NULL;
97 
98     if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
99     {
100         *ppvObject = static_cast< IUnknown* >( this );
101         ( (LPUNKNOWN)*ppvObject )->AddRef( );
102         hr = S_OK;
103     }
104 
105     return hr;
106 }
107 
108 //------------------------------------------------------------------------
109 // IUnknown->AddRef
110 //------------------------------------------------------------------------
111 
112 STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
113 {
114     return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
115 }
116 
117 //------------------------------------------------------------------------
118 // IUnknown->Release
119 //------------------------------------------------------------------------
120 
121 STDMETHODIMP_(ULONG) CXTDataObject::Release( )
122 {
123     // we need a helper variable because it's
124     // not allowed to access a member variable
125     // after an object is destroyed
126     ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
127 
128     if ( 0 == nRefCnt )
129     {
130         delete this;
131     }
132 
133     return nRefCnt;
134 }
135 
136 /*------------------------------------------------------------------------
137 
138  IDataObject->GetData
139  we deliver data only into global memory
140 
141  algo:
142  1. convert the given formatect struct into a valid dataflavor
143  2. if the transferable directly supports the requested format
144  2.1. if text data requested add a trailing '\0' in order to prevent
145         problems (windows needs '\0' terminated strings
146  2.2. we expect unicode data as Sequence< sal_Unicode > and all other
147         text and raw data as Sequence< sal_Int8 >
148 
149 ------------------------------------------------------------------------*/
150 
151 STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
152 {
153     if ( ( NULL == pFormatetc ) || ( NULL == pmedium ) )
154         return E_INVALIDARG;
155 
156     HRESULT hr = E_FAIL;
157     char    pBuff[] = "Test OleClipboard";
158 
159     if ( CF_TEXT == pFormatetc->cfFormat )
160     {
161         CHGlobalHelper hGlobHlp( TRUE );
162 
163         hGlobHlp.Write( pBuff, sizeof( pBuff ), NULL );
164 
165         pmedium->tymed          = TYMED_HGLOBAL;
166         pmedium->hGlobal        = hGlobHlp.GetHGlobal( );
167         pmedium->pUnkForRelease = NULL;
168 
169         hr = S_OK;
170     }
171 
172     return hr;
173 }
174 
175 //------------------------------------------------------------------------
176 // IDataObject->EnumFormatEtc
177 //------------------------------------------------------------------------
178 
179 STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
180 {
181     if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) )
182         return E_INVALIDARG;
183 
184     *ppenumFormatetc = NULL;
185 
186     HRESULT hr = E_FAIL;
187 
188     if ( DATADIR_GET == dwDirection )
189     {
190         *ppenumFormatetc = new CEnumFormatEtc( this );
191         static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
192         hr = S_OK;
193     }
194 
195     return hr;
196 }
197 
198 //------------------------------------------------------------------------
199 // IDataObject->QueryGetData
200 //------------------------------------------------------------------------
201 
202 STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
203 {
204     return E_NOTIMPL;
205 }
206 
207 //------------------------------------------------------------------------
208 // IDataObject->GetDataHere
209 //------------------------------------------------------------------------
210 
211 STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
212 {
213     return E_NOTIMPL;
214 }
215 
216 //------------------------------------------------------------------------
217 // IDataObject->GetCanonicalFormatEtc
218 //------------------------------------------------------------------------
219 
220 STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
221 {
222     return E_NOTIMPL;
223 }
224 
225 //------------------------------------------------------------------------
226 // IDataObject->SetData
227 //------------------------------------------------------------------------
228 
229 STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
230 {
231     return E_NOTIMPL;
232 }
233 
234 //------------------------------------------------------------------------
235 // IDataObject->DAdvise
236 //------------------------------------------------------------------------
237 
238 STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
239 {
240     return E_NOTIMPL;
241 }
242 
243 //------------------------------------------------------------------------
244 // IDataObject->DUnadvise
245 //------------------------------------------------------------------------
246 
247 STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
248 {
249     return E_NOTIMPL;
250 }
251 
252 //------------------------------------------------------------------------
253 // IDataObject->EnumDAdvise
254 //------------------------------------------------------------------------
255 
256 STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
257 {
258     return E_NOTIMPL;
259 }
260 
261 //------------------------------------------------------------------------
262 // for our convenience
263 //------------------------------------------------------------------------
264 
265 CXTDataObject::operator IDataObject*( )
266 {
267     return static_cast< IDataObject* >( this );
268 }
269 
270 
271 //============================================================================
272 // CEnumFormatEtc
273 //============================================================================
274 
275 //----------------------------------------------------------------------------
276 // ctor
277 //----------------------------------------------------------------------------
278 
279 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) :
280     m_nRefCnt( 0 ),
281     m_pUnkDataObj( pUnkDataObj ),
282     m_nCurrPos( 0 )
283 {
284 }
285 
286 //----------------------------------------------------------------------------
287 // IUnknown->QueryInterface
288 //----------------------------------------------------------------------------
289 
290 STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
291 {
292     if ( NULL == ppvObject )
293         return E_INVALIDARG;
294 
295     HRESULT hr = E_NOINTERFACE;
296 
297     *ppvObject = NULL;
298 
299     if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) )
300     {
301         *ppvObject = static_cast< IUnknown* >( this );
302         static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
303         hr = S_OK;
304     }
305 
306     return hr;
307 }
308 
309 //----------------------------------------------------------------------------
310 // IUnknown->AddRef
311 //----------------------------------------------------------------------------
312 
313 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
314 {
315     // keep the dataobject alive
316     m_pUnkDataObj->AddRef( );
317     return InterlockedIncrement( &m_nRefCnt );
318 }
319 
320 //----------------------------------------------------------------------------
321 // IUnknown->Release
322 //----------------------------------------------------------------------------
323 
324 STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
325 {
326     // release the outer dataobject
327     m_pUnkDataObj->Release( );
328 
329     // we need a helper variable because it's
330     // not allowed to access a member variable
331     // after an object is destroyed
332     ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
333     if ( 0 == nRefCnt )
334         delete this;
335 
336     return nRefCnt;
337 }
338 
339 //----------------------------------------------------------------------------
340 // IEnumFORMATETC->Next
341 //----------------------------------------------------------------------------
342 
343 STDMETHODIMP CEnumFormatEtc::Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched )
344 {
345     if ( ( 0 != celt ) && ( NULL == rgelt ) )
346         return E_INVALIDARG;
347 
348     ULONG   ulFetched = 0;
349     ULONG   ulToFetch = celt;
350     HRESULT hr        = S_FALSE;
351 
352     while( m_nCurrPos < 1 )
353     {
354         rgelt->cfFormat = CF_TEXT;
355         rgelt->ptd      = NULL;
356         rgelt->dwAspect = DVASPECT_CONTENT;
357         rgelt->lindex   = -1;
358         rgelt->tymed    = TYMED_HGLOBAL;
359 
360         ++m_nCurrPos;
361         ++rgelt;
362         --ulToFetch;
363         ++ulFetched;
364     }
365 
366     if ( ulFetched == celt )
367         hr = S_OK;
368 
369     if ( NULL != pceltFetched )
370     {
371         *pceltFetched = ulFetched;
372     }
373 
374     return hr;
375 }
376 
377 //----------------------------------------------------------------------------
378 // IEnumFORMATETC->Skip
379 //----------------------------------------------------------------------------
380 
381 STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
382 {
383     HRESULT hr = S_FALSE;
384 
385     /*
386     if ( ( m_nCurrPos + celt ) < m_nClipFormats )
387     {
388         m_nCurrPos += celt;
389         hr = S_OK;
390     }
391     */
392 
393     return hr;
394 }
395 
396 //----------------------------------------------------------------------------
397 // IEnumFORMATETC->Reset
398 //----------------------------------------------------------------------------
399 
400 STDMETHODIMP CEnumFormatEtc::Reset( )
401 {
402     m_nCurrPos = 0;
403     return S_OK;
404 }
405 
406 //----------------------------------------------------------------------------
407 // IEnumFORMATETC->Clone
408 //----------------------------------------------------------------------------
409 
410 STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
411 {
412     OSL_ASSERT( NULL != ppenum );
413 
414     if ( NULL == ppenum )
415         return E_INVALIDARG;
416 
417     HRESULT hr = E_FAIL;
418 
419     *ppenum = NULL;
420 
421     CEnumFormatEtc* pCEnumFEtc = new CEnumFormatEtc( m_pUnkDataObj );
422     if ( NULL != pCEnumFEtc )
423     {
424         pCEnumFEtc->m_nCurrPos = m_nCurrPos;
425         *ppenum = static_cast< IEnumFORMATETC* >( pCEnumFEtc );
426         static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
427         hr = NOERROR;
428     }
429 
430     return hr;
431 }
432