1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
27 #pragma warning(push,1)
37 using namespace ::std
;
39 // OTWrapperDataObject
42 in the constructor we enumerate all formats offered by the transferable
43 and convert the formats into formatetc structures
44 if the transferable supports text in different charsets we use either
45 the charset equal to the charset of the current thread or an arbitrary
46 charset supported by the transferable and the system
47 if the transferable supports only unicodetext we offer in addition to
48 this text in the charset of the current thread
49 in order to allow the consumer of the clipboard to query for the charset
50 of the text in the clipboard we offer a CF_LOCALE
52 CXTDataObject::CXTDataObject( ) :
58 // IUnknown->QueryInterface
60 STDMETHODIMP
CXTDataObject::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
62 OSL_ASSERT( NULL
!= ppvObject
);
64 if ( NULL
== ppvObject
)
67 HRESULT hr
= E_NOINTERFACE
;
71 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IDataObject
) == iid
) )
73 *ppvObject
= static_cast< IUnknown
* >( this );
74 ( (LPUNKNOWN
)*ppvObject
)->AddRef( );
83 STDMETHODIMP_(ULONG
) CXTDataObject::AddRef( )
85 return static_cast< ULONG
>( InterlockedIncrement( &m_nRefCnt
) );
90 STDMETHODIMP_(ULONG
) CXTDataObject::Release( )
92 // we need a helper variable because it's
93 // not allowed to access a member variable
94 // after an object is destroyed
95 ULONG nRefCnt
= static_cast< ULONG
>( InterlockedDecrement( &m_nRefCnt
) );
105 /*------------------------------------------------------------------------
108 we deliver data only into global memory
111 1. convert the given formatect struct into a valid dataflavor
112 2. if the transferable directly supports the requested format
113 2.1. if text data requested add a trailing '\0' in order to prevent
114 problems (windows needs '\0' terminated strings
115 2.2. we expect unicode data as Sequence< sal_Unicode > and all other
116 text and raw data as Sequence< sal_Int8 >
118 ------------------------------------------------------------------------*/
120 STDMETHODIMP
CXTDataObject::GetData( LPFORMATETC pFormatetc
, LPSTGMEDIUM pmedium
)
122 if ( ( NULL
== pFormatetc
) || ( NULL
== pmedium
) )
127 if ( CF_TEXT
== pFormatetc
->cfFormat
)
129 CHGlobalHelper
hGlobHlp( TRUE
);
131 char pBuff
[] = "Test OleClipboard";
132 hGlobHlp
.Write( pBuff
, sizeof( pBuff
), NULL
);
134 pmedium
->tymed
= TYMED_HGLOBAL
;
135 pmedium
->hGlobal
= hGlobHlp
.GetHGlobal( );
136 pmedium
->pUnkForRelease
= NULL
;
144 // IDataObject->EnumFormatEtc
146 STDMETHODIMP
CXTDataObject::EnumFormatEtc( DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatetc
)
148 if ( ( NULL
== ppenumFormatetc
) || ( DATADIR_SET
== dwDirection
) )
151 *ppenumFormatetc
= NULL
;
155 if ( DATADIR_GET
== dwDirection
)
157 *ppenumFormatetc
= new CEnumFormatEtc( this );
158 static_cast< LPUNKNOWN
>( *ppenumFormatetc
)->AddRef( );
165 // IDataObject->QueryGetData
167 STDMETHODIMP
CXTDataObject::QueryGetData( LPFORMATETC pFormatetc
)
172 // IDataObject->GetDataHere
174 STDMETHODIMP
CXTDataObject::GetDataHere( LPFORMATETC
, LPSTGMEDIUM
)
179 // IDataObject->GetCanonicalFormatEtc
181 STDMETHODIMP
CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC
, LPFORMATETC
)
186 // IDataObject->SetData
188 STDMETHODIMP
CXTDataObject::SetData( LPFORMATETC
, LPSTGMEDIUM
, BOOL
)
193 // IDataObject->DAdvise
195 STDMETHODIMP
CXTDataObject::DAdvise( LPFORMATETC
, DWORD
, LPADVISESINK
, DWORD
* )
200 // IDataObject->DUnadvise
202 STDMETHODIMP
CXTDataObject::DUnadvise( DWORD
)
207 // IDataObject->EnumDAdvise
209 STDMETHODIMP
CXTDataObject::EnumDAdvise( LPENUMSTATDATA
* )
214 CXTDataObject::operator IDataObject
*( )
216 return static_cast< IDataObject
* >( this );
219 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj
) :
221 m_pUnkDataObj( pUnkDataObj
),
226 // IUnknown->QueryInterface
228 STDMETHODIMP
CEnumFormatEtc::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
230 if ( NULL
== ppvObject
)
233 HRESULT hr
= E_NOINTERFACE
;
237 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IEnumFORMATETC
) == iid
) )
239 *ppvObject
= static_cast< IUnknown
* >( this );
240 static_cast< LPUNKNOWN
>( *ppvObject
)->AddRef( );
249 STDMETHODIMP_(ULONG
) CEnumFormatEtc::AddRef( )
251 // keep the dataobject alive
252 m_pUnkDataObj
->AddRef( );
253 return InterlockedIncrement( &m_nRefCnt
);
258 STDMETHODIMP_(ULONG
) CEnumFormatEtc::Release( )
260 // release the outer dataobject
261 m_pUnkDataObj
->Release( );
263 // we need a helper variable because it's
264 // not allowed to access a member variable
265 // after an object is destroyed
266 ULONG nRefCnt
= InterlockedDecrement( &m_nRefCnt
);
273 // IEnumFORMATETC->Next
275 STDMETHODIMP
CEnumFormatEtc::Next( ULONG celt
, LPFORMATETC rgelt
, ULONG
* pceltFetched
)
277 if ( ( 0 != celt
) && ( NULL
== rgelt
) )
281 ULONG ulToFetch
= celt
;
282 HRESULT hr
= S_FALSE
;
284 while( m_nCurrPos
< 1 )
286 rgelt
->cfFormat
= CF_TEXT
;
288 rgelt
->dwAspect
= DVASPECT_CONTENT
;
290 rgelt
->tymed
= TYMED_HGLOBAL
;
298 if ( ulFetched
== celt
)
301 if ( NULL
!= pceltFetched
)
303 *pceltFetched
= ulFetched
;
309 // IEnumFORMATETC->Skip
311 STDMETHODIMP
CEnumFormatEtc::Skip( ULONG celt
)
313 HRESULT hr
= S_FALSE
;
316 if ( ( m_nCurrPos + celt ) < m_nClipFormats )
326 // IEnumFORMATETC->Reset
328 STDMETHODIMP
CEnumFormatEtc::Reset( )
334 // IEnumFORMATETC->Clone
336 STDMETHODIMP
CEnumFormatEtc::Clone( IEnumFORMATETC
** ppenum
)
338 OSL_ASSERT( NULL
!= ppenum
);
340 if ( NULL
== ppenum
)
347 CEnumFormatEtc
* pCEnumFEtc
= new CEnumFormatEtc( m_pUnkDataObj
);
348 if ( NULL
!= pCEnumFEtc
)
350 pCEnumFEtc
->m_nCurrPos
= m_nCurrPos
;
351 *ppenum
= static_cast< IEnumFORMATETC
* >( pCEnumFEtc
);
352 static_cast< LPUNKNOWN
>( *ppenum
)->AddRef( );
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */