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