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)
36 using namespace ::std
;
38 // OTWrapperDataObject
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
51 CXTDataObject::CXTDataObject( ) :
57 // IUnknown->QueryInterface
59 STDMETHODIMP
CXTDataObject::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
61 OSL_ASSERT( NULL
!= ppvObject
);
63 if ( NULL
== ppvObject
)
66 HRESULT hr
= E_NOINTERFACE
;
70 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IDataObject
) == iid
) )
72 *ppvObject
= static_cast< IUnknown
* >( this );
73 ( (LPUNKNOWN
)*ppvObject
)->AddRef( );
82 STDMETHODIMP_(ULONG
) CXTDataObject::AddRef( )
84 return static_cast< ULONG
>( InterlockedIncrement( &m_nRefCnt
) );
89 STDMETHODIMP_(ULONG
) CXTDataObject::Release( )
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
) );
104 /*------------------------------------------------------------------------
107 we deliver data only into global memory
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 >
117 ------------------------------------------------------------------------*/
119 STDMETHODIMP
CXTDataObject::GetData( LPFORMATETC pFormatetc
, LPSTGMEDIUM pmedium
)
121 if ( ( NULL
== pFormatetc
) || ( NULL
== pmedium
) )
126 if ( CF_TEXT
== pFormatetc
->cfFormat
)
128 CHGlobalHelper
hGlobHlp( TRUE
);
130 char pBuff
[] = "Test OleClipboard";
131 hGlobHlp
.Write( pBuff
, sizeof( pBuff
), NULL
);
133 pmedium
->tymed
= TYMED_HGLOBAL
;
134 pmedium
->hGlobal
= hGlobHlp
.GetHGlobal( );
135 pmedium
->pUnkForRelease
= NULL
;
143 // IDataObject->EnumFormatEtc
145 STDMETHODIMP
CXTDataObject::EnumFormatEtc( DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatetc
)
147 if ( ( NULL
== ppenumFormatetc
) || ( DATADIR_SET
== dwDirection
) )
150 *ppenumFormatetc
= NULL
;
154 if ( DATADIR_GET
== dwDirection
)
156 *ppenumFormatetc
= new CEnumFormatEtc( this );
157 static_cast< LPUNKNOWN
>( *ppenumFormatetc
)->AddRef( );
164 // IDataObject->QueryGetData
166 STDMETHODIMP
CXTDataObject::QueryGetData( LPFORMATETC pFormatetc
)
171 // IDataObject->GetDataHere
173 STDMETHODIMP
CXTDataObject::GetDataHere( LPFORMATETC
, LPSTGMEDIUM
)
178 // IDataObject->GetCanonicalFormatEtc
180 STDMETHODIMP
CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC
, LPFORMATETC
)
185 // IDataObject->SetData
187 STDMETHODIMP
CXTDataObject::SetData( LPFORMATETC
, LPSTGMEDIUM
, BOOL
)
192 // IDataObject->DAdvise
194 STDMETHODIMP
CXTDataObject::DAdvise( LPFORMATETC
, DWORD
, LPADVISESINK
, DWORD
* )
199 // IDataObject->DUnadvise
201 STDMETHODIMP
CXTDataObject::DUnadvise( DWORD
)
206 // IDataObject->EnumDAdvise
208 STDMETHODIMP
CXTDataObject::EnumDAdvise( LPENUMSTATDATA
* )
213 CXTDataObject::operator IDataObject
*( )
215 return static_cast< IDataObject
* >( this );
218 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj
) :
220 m_pUnkDataObj( pUnkDataObj
),
225 // IUnknown->QueryInterface
227 STDMETHODIMP
CEnumFormatEtc::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
229 if ( NULL
== ppvObject
)
232 HRESULT hr
= E_NOINTERFACE
;
236 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IEnumFORMATETC
) == iid
) )
238 *ppvObject
= static_cast< IUnknown
* >( this );
239 static_cast< LPUNKNOWN
>( *ppvObject
)->AddRef( );
248 STDMETHODIMP_(ULONG
) CEnumFormatEtc::AddRef( )
250 // keep the dataobject alive
251 m_pUnkDataObj
->AddRef( );
252 return InterlockedIncrement( &m_nRefCnt
);
257 STDMETHODIMP_(ULONG
) CEnumFormatEtc::Release( )
259 // release the outer dataobject
260 m_pUnkDataObj
->Release( );
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
);
272 // IEnumFORMATETC->Next
274 STDMETHODIMP
CEnumFormatEtc::Next( ULONG celt
, LPFORMATETC rgelt
, ULONG
* pceltFetched
)
276 if ( ( 0 != celt
) && ( NULL
== rgelt
) )
280 ULONG ulToFetch
= celt
;
281 HRESULT hr
= S_FALSE
;
283 while( m_nCurrPos
< 1 )
285 rgelt
->cfFormat
= CF_TEXT
;
287 rgelt
->dwAspect
= DVASPECT_CONTENT
;
289 rgelt
->tymed
= TYMED_HGLOBAL
;
297 if ( ulFetched
== celt
)
300 if ( NULL
!= pceltFetched
)
302 *pceltFetched
= ulFetched
;
308 // IEnumFORMATETC->Skip
310 STDMETHODIMP
CEnumFormatEtc::Skip( ULONG celt
)
312 HRESULT hr
= S_FALSE
;
315 if ( ( m_nCurrPos + celt ) < m_nClipFormats )
325 // IEnumFORMATETC->Reset
327 STDMETHODIMP
CEnumFormatEtc::Reset( )
333 // IEnumFORMATETC->Clone
335 STDMETHODIMP
CEnumFormatEtc::Clone( IEnumFORMATETC
** ppenum
)
337 OSL_ASSERT( NULL
!= ppenum
);
339 if ( NULL
== ppenum
)
346 CEnumFormatEtc
* pCEnumFEtc
= new CEnumFormatEtc( m_pUnkDataObj
);
347 if ( NULL
!= pCEnumFEtc
)
349 pCEnumFEtc
->m_nCurrPos
= m_nCurrPos
;
350 *ppenum
= static_cast< IEnumFORMATETC
* >( pCEnumFEtc
);
351 static_cast< LPUNKNOWN
>( *ppenum
)->AddRef( );
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */