LibreOffice Module dtrans (master)  1
XTDo.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <osl/diagnose.h>
21 
22 #include "../DTransHelper.hxx"
23 
24 #include "XTDo.hxx"
25 
26 #if defined _MSC_VER
27 #pragma warning(push,1)
28 #endif
29 #include <windows.h>
30 #include <ole2.h>
31 #if defined _MSC_VER
32 #pragma warning(pop)
33 #endif
34 #include <memory>
35 
36 using namespace ::std;
37 
38 // OTWrapperDataObject
39 
40 /*
41  in the constructor we enumerate all formats offered by the transferable
42  and convert the formats into formatetc structures
43  if the transferable supports text in different charsets we use either
44  the charset equal to the charset of the current thread or an arbitrary
45  charset supported by the transferable and the system
46  if the transferable supports only unicodetext we offer in addition to
47  this text in the charset of the current thread
48  in order to allow the consumer of the clipboard to query for the charset
49  of the text in the clipboard we offer a CF_LOCALE
50 */
52  m_nRefCnt( 0 )
53 {
54 
55 }
56 
57 // IUnknown->QueryInterface
58 
59 STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
60 {
61  OSL_ASSERT( NULL != ppvObject );
62 
63  if ( NULL == ppvObject )
64  return E_INVALIDARG;
65 
66  HRESULT hr = E_NOINTERFACE;
67 
68  *ppvObject = NULL;
69 
70  if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
71  {
72  *ppvObject = static_cast< IUnknown* >( this );
73  ( (LPUNKNOWN)*ppvObject )->AddRef( );
74  hr = S_OK;
75  }
76 
77  return hr;
78 }
79 
80 // IUnknown->AddRef
81 
82 STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
83 {
84  return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
85 }
86 
87 // IUnknown->Release
88 
89 STDMETHODIMP_(ULONG) CXTDataObject::Release( )
90 {
91  // we need a helper variable because it's
92  // not allowed to access a member variable
93  // after an object is destroyed
94  ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
95 
96  if ( 0 == nRefCnt )
97  {
98  delete this;
99  }
100 
101  return nRefCnt;
102 }
103 
104 /*------------------------------------------------------------------------
105 
106  IDataObject->GetData
107  we deliver data only into global memory
108 
109  algo:
110  1. convert the given formatect struct into a valid dataflavor
111  2. if the transferable directly supports the requested format
112  2.1. if text data requested add a trailing '\0' in order to prevent
113  problems (windows needs '\0' terminated strings
114  2.2. we expect unicode data as Sequence< sal_Unicode > and all other
115  text and raw data as Sequence< sal_Int8 >
116 
117 ------------------------------------------------------------------------*/
118 
119 STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
120 {
121  if ( ( NULL == pFormatetc ) || ( NULL == pmedium ) )
122  return E_INVALIDARG;
123 
124  HRESULT hr = E_FAIL;
125 
126  if ( CF_TEXT == pFormatetc->cfFormat )
127  {
128  CHGlobalHelper hGlobHlp( TRUE );
129 
130  char pBuff[] = "Test OleClipboard";
131  hGlobHlp.Write( pBuff, sizeof( pBuff ), NULL );
132 
133  pmedium->tymed = TYMED_HGLOBAL;
134  pmedium->hGlobal = hGlobHlp.GetHGlobal( );
135  pmedium->pUnkForRelease = NULL;
136 
137  hr = S_OK;
138  }
139 
140  return hr;
141 }
142 
143 // IDataObject->EnumFormatEtc
144 
145 STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
146 {
147  if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) )
148  return E_INVALIDARG;
149 
150  *ppenumFormatetc = NULL;
151 
152  HRESULT hr = E_FAIL;
153 
154  if ( DATADIR_GET == dwDirection )
155  {
156  *ppenumFormatetc = new CEnumFormatEtc( this );
157  static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
158  hr = S_OK;
159  }
160 
161  return hr;
162 }
163 
164 // IDataObject->QueryGetData
165 
166 STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
167 {
168  return E_NOTIMPL;
169 }
170 
171 // IDataObject->GetDataHere
172 
173 STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
174 {
175  return E_NOTIMPL;
176 }
177 
178 // IDataObject->GetCanonicalFormatEtc
179 
180 STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
181 {
182  return E_NOTIMPL;
183 }
184 
185 // IDataObject->SetData
186 
187 STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
188 {
189  return E_NOTIMPL;
190 }
191 
192 // IDataObject->DAdvise
193 
194 STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
195 {
196  return E_NOTIMPL;
197 }
198 
199 // IDataObject->DUnadvise
200 
201 STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
202 {
203  return E_NOTIMPL;
204 }
205 
206 // IDataObject->EnumDAdvise
207 
208 STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
209 {
210  return E_NOTIMPL;
211 }
212 
213 CXTDataObject::operator IDataObject*( )
214 {
215  return static_cast< IDataObject* >( this );
216 }
217 
218 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) :
219  m_nRefCnt( 0 ),
220  m_pUnkDataObj( pUnkDataObj ),
221  m_nCurrPos( 0 )
222 {
223 }
224 
225 // IUnknown->QueryInterface
226 
227 STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
228 {
229  if ( NULL == ppvObject )
230  return E_INVALIDARG;
231 
232  HRESULT hr = E_NOINTERFACE;
233 
234  *ppvObject = NULL;
235 
236  if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) )
237  {
238  *ppvObject = static_cast< IUnknown* >( this );
239  static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
240  hr = S_OK;
241  }
242 
243  return hr;
244 }
245 
246 // IUnknown->AddRef
247 
248 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
249 {
250  // keep the dataobject alive
251  m_pUnkDataObj->AddRef( );
252  return InterlockedIncrement( &m_nRefCnt );
253 }
254 
255 // IUnknown->Release
256 
257 STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
258 {
259  // release the outer dataobject
260  m_pUnkDataObj->Release( );
261 
262  // we need a helper variable because it's
263  // not allowed to access a member variable
264  // after an object is destroyed
265  ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
266  if ( 0 == nRefCnt )
267  delete this;
268 
269  return nRefCnt;
270 }
271 
272 // IEnumFORMATETC->Next
273 
274 STDMETHODIMP CEnumFormatEtc::Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched )
275 {
276  if ( ( 0 != celt ) && ( NULL == rgelt ) )
277  return E_INVALIDARG;
278 
279  ULONG ulFetched = 0;
280  ULONG ulToFetch = celt;
281  HRESULT hr = S_FALSE;
282 
283  while( m_nCurrPos < 1 )
284  {
285  rgelt->cfFormat = CF_TEXT;
286  rgelt->ptd = NULL;
287  rgelt->dwAspect = DVASPECT_CONTENT;
288  rgelt->lindex = -1;
289  rgelt->tymed = TYMED_HGLOBAL;
290 
291  ++m_nCurrPos;
292  ++rgelt;
293  --ulToFetch;
294  ++ulFetched;
295  }
296 
297  if ( ulFetched == celt )
298  hr = S_OK;
299 
300  if ( NULL != pceltFetched )
301  {
302  *pceltFetched = ulFetched;
303  }
304 
305  return hr;
306 }
307 
308 // IEnumFORMATETC->Skip
309 
310 STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
311 {
312  HRESULT hr = S_FALSE;
313 
314  /*
315  if ( ( m_nCurrPos + celt ) < m_nClipFormats )
316  {
317  m_nCurrPos += celt;
318  hr = S_OK;
319  }
320  */
321 
322  return hr;
323 }
324 
325 // IEnumFORMATETC->Reset
326 
327 STDMETHODIMP CEnumFormatEtc::Reset( )
328 {
329  m_nCurrPos = 0;
330  return S_OK;
331 }
332 
333 // IEnumFORMATETC->Clone
334 
335 STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
336 {
337  OSL_ASSERT( NULL != ppenum );
338 
339  if ( NULL == ppenum )
340  return E_INVALIDARG;
341 
342  HRESULT hr = E_FAIL;
343 
344  *ppenum = NULL;
345 
346  CEnumFormatEtc* pCEnumFEtc = new CEnumFormatEtc( m_pUnkDataObj );
347  if ( NULL != pCEnumFEtc )
348  {
349  pCEnumFEtc->m_nCurrPos = m_nCurrPos;
350  *ppenum = static_cast< IEnumFORMATETC* >( pCEnumFEtc );
351  static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
352  hr = NOERROR;
353  }
354 
355  return hr;
356 }
357 
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *pFormatectIn, FORMATETC *pFormatetcOut) override
STDMETHODIMP Reset() override
STDMETHODIMP DAdvise(FORMATETC *pFormatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) override
STDMETHODIMP Next(ULONG nRequested, FORMATETC *lpDest, ULONG *lpFetched) override
EXTERN_C BOOL BOOL const wchar_t *pProgramPath HRESULT hr
STDMETHODIMP Skip(ULONG celt) override
STDMETHODIMP GetDataHere(FORMATETC *pFormatetc, STGMEDIUM *pmedium) override
STDMETHODIMP Clone(IEnumFORMATETC **ppenum) override
return NULL
STDMETHODIMP GetData(FORMATETC *pFormatetc, STGMEDIUM *pmedium) override
const wchar_t *typedef BOOL
STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject) override
STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject) override
STDMETHODIMP QueryGetData(FORMATETC *pFormatetc) override
ULONG m_nCurrPos
Definition: XTDo.hxx:107
LPUNKNOWN m_pUnkDataObj
Definition: XTDo.hxx:106
#define TRUE
STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatetc) override
STDMETHODIMP DUnadvise(DWORD dwConnection) override
STDMETHODIMP SetData(FORMATETC *pFormatetc, STGMEDIUM *pmedium, BOOL fRelease) override
STDMETHODIMP_(ULONG) CXTDataObject
Definition: XTDo.cxx:82
CEnumFormatEtc(LPUNKNOWN lpUnkOuter, const CFormatEtcContainer &aFormatEtcContainer)
STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenumAdvise) override
CXTDataObject()
Definition: XTDo.cxx:51