Branch libreoffice-5-0-4
[LibreOffice.git] / dtrans / source / win32 / workbench / XTDo.cxx
blob8961285763d646afd5b6cf1c9c7c4ddef5614dce
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 "../DTransHelper.hxx"
24 #include "XTDo.hxx"
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 #include <tchar.h>
37 // namespace directives
39 using namespace ::std;
41 // OTWrapperDataObject
43 // ctor
46 in the constructor we enumerate all formats offered by the transferable
47 and convert the formats into formatetc structures
48 if the transferable supports text in different charsets we use either
49 the charset equal to the charset of the current thread or an arbitrary
50 charset supported by the transferable and the system
51 if the transferable supports only unicodetext we offer in addition to
52 this text in the charset of the current thread
53 in order to allow the consumer of the clipboard to query for the charset
54 of the text in the clipboard we offer a CF_LOCALE
56 CXTDataObject::CXTDataObject( ) :
57 m_nRefCnt( 0 )
62 // IUnknown->QueryInterface
64 STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
66 OSL_ASSERT( NULL != ppvObject );
68 if ( NULL == ppvObject )
69 return E_INVALIDARG;
71 HRESULT hr = E_NOINTERFACE;
73 *ppvObject = NULL;
75 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
77 *ppvObject = static_cast< IUnknown* >( this );
78 ( (LPUNKNOWN)*ppvObject )->AddRef( );
79 hr = S_OK;
82 return hr;
85 // IUnknown->AddRef
87 STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
89 return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
92 // IUnknown->Release
94 STDMETHODIMP_(ULONG) CXTDataObject::Release( )
96 // we need a helper variable because it's
97 // not allowed to access a member variable
98 // after an object is destroyed
99 ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
101 if ( 0 == nRefCnt )
103 delete this;
106 return nRefCnt;
109 /*------------------------------------------------------------------------
111 IDataObject->GetData
112 we deliver data only into global memory
114 algo:
115 1. convert the given formatect struct into a valid dataflavor
116 2. if the transferable directly supports the requested format
117 2.1. if text data requested add a trailing '\0' in order to prevent
118 problems (windows needs '\0' terminated strings
119 2.2. we expect unicode data as Sequence< sal_Unicode > and all other
120 text and raw data as Sequence< sal_Int8 >
122 ------------------------------------------------------------------------*/
124 STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
126 if ( ( NULL == pFormatetc ) || ( NULL == pmedium ) )
127 return E_INVALIDARG;
129 HRESULT hr = E_FAIL;
131 if ( CF_TEXT == pFormatetc->cfFormat )
133 CHGlobalHelper hGlobHlp( TRUE );
135 char pBuff[] = "Test OleClipboard";
136 hGlobHlp.Write( pBuff, sizeof( pBuff ), NULL );
138 pmedium->tymed = TYMED_HGLOBAL;
139 pmedium->hGlobal = hGlobHlp.GetHGlobal( );
140 pmedium->pUnkForRelease = NULL;
142 hr = S_OK;
145 return hr;
148 // IDataObject->EnumFormatEtc
150 STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
152 if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) )
153 return E_INVALIDARG;
155 *ppenumFormatetc = NULL;
157 HRESULT hr = E_FAIL;
159 if ( DATADIR_GET == dwDirection )
161 *ppenumFormatetc = new CEnumFormatEtc( this );
162 static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
163 hr = S_OK;
166 return hr;
169 // IDataObject->QueryGetData
171 STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
173 return E_NOTIMPL;
176 // IDataObject->GetDataHere
178 STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
180 return E_NOTIMPL;
183 // IDataObject->GetCanonicalFormatEtc
185 STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
187 return E_NOTIMPL;
190 // IDataObject->SetData
192 STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
194 return E_NOTIMPL;
197 // IDataObject->DAdvise
199 STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
201 return E_NOTIMPL;
204 // IDataObject->DUnadvise
206 STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
208 return E_NOTIMPL;
211 // IDataObject->EnumDAdvise
213 STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
215 return E_NOTIMPL;
218 // for our convenience
220 CXTDataObject::operator IDataObject*( )
222 return static_cast< IDataObject* >( this );
225 // CEnumFormatEtc
227 // ctor
229 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) :
230 m_nRefCnt( 0 ),
231 m_pUnkDataObj( pUnkDataObj ),
232 m_nCurrPos( 0 )
236 // IUnknown->QueryInterface
238 STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
240 if ( NULL == ppvObject )
241 return E_INVALIDARG;
243 HRESULT hr = E_NOINTERFACE;
245 *ppvObject = NULL;
247 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) )
249 *ppvObject = static_cast< IUnknown* >( this );
250 static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
251 hr = S_OK;
254 return hr;
257 // IUnknown->AddRef
259 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
261 // keep the dataobject alive
262 m_pUnkDataObj->AddRef( );
263 return InterlockedIncrement( &m_nRefCnt );
266 // IUnknown->Release
268 STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
270 // release the outer dataobject
271 m_pUnkDataObj->Release( );
273 // we need a helper variable because it's
274 // not allowed to access a member variable
275 // after an object is destroyed
276 ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
277 if ( 0 == nRefCnt )
278 delete this;
280 return nRefCnt;
283 // IEnumFORMATETC->Next
285 STDMETHODIMP CEnumFormatEtc::Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched )
287 if ( ( 0 != celt ) && ( NULL == rgelt ) )
288 return E_INVALIDARG;
290 ULONG ulFetched = 0;
291 ULONG ulToFetch = celt;
292 HRESULT hr = S_FALSE;
294 while( m_nCurrPos < 1 )
296 rgelt->cfFormat = CF_TEXT;
297 rgelt->ptd = NULL;
298 rgelt->dwAspect = DVASPECT_CONTENT;
299 rgelt->lindex = -1;
300 rgelt->tymed = TYMED_HGLOBAL;
302 ++m_nCurrPos;
303 ++rgelt;
304 --ulToFetch;
305 ++ulFetched;
308 if ( ulFetched == celt )
309 hr = S_OK;
311 if ( NULL != pceltFetched )
313 *pceltFetched = ulFetched;
316 return hr;
319 // IEnumFORMATETC->Skip
321 STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
323 HRESULT hr = S_FALSE;
326 if ( ( m_nCurrPos + celt ) < m_nClipFormats )
328 m_nCurrPos += celt;
329 hr = S_OK;
333 return hr;
336 // IEnumFORMATETC->Reset
338 STDMETHODIMP CEnumFormatEtc::Reset( )
340 m_nCurrPos = 0;
341 return S_OK;
344 // IEnumFORMATETC->Clone
346 STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
348 OSL_ASSERT( NULL != ppenum );
350 if ( NULL == ppenum )
351 return E_INVALIDARG;
353 HRESULT hr = E_FAIL;
355 *ppenum = NULL;
357 CEnumFormatEtc* pCEnumFEtc = new CEnumFormatEtc( m_pUnkDataObj );
358 if ( NULL != pCEnumFEtc )
360 pCEnumFEtc->m_nCurrPos = m_nCurrPos;
361 *ppenum = static_cast< IEnumFORMATETC* >( pCEnumFEtc );
362 static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
363 hr = NOERROR;
366 return hr;
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */