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 // namespace directives
39 using namespace ::std
;
41 // OTWrapperDataObject
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( ) :
62 // IUnknown->QueryInterface
64 STDMETHODIMP
CXTDataObject::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
66 OSL_ASSERT( NULL
!= ppvObject
);
68 if ( NULL
== ppvObject
)
71 HRESULT hr
= E_NOINTERFACE
;
75 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IDataObject
) == iid
) )
77 *ppvObject
= static_cast< IUnknown
* >( this );
78 ( (LPUNKNOWN
)*ppvObject
)->AddRef( );
87 STDMETHODIMP_(ULONG
) CXTDataObject::AddRef( )
89 return static_cast< ULONG
>( InterlockedIncrement( &m_nRefCnt
) );
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
) );
109 /*------------------------------------------------------------------------
112 we deliver data only into global memory
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
) )
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
;
148 // IDataObject->EnumFormatEtc
150 STDMETHODIMP
CXTDataObject::EnumFormatEtc( DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatetc
)
152 if ( ( NULL
== ppenumFormatetc
) || ( DATADIR_SET
== dwDirection
) )
155 *ppenumFormatetc
= NULL
;
159 if ( DATADIR_GET
== dwDirection
)
161 *ppenumFormatetc
= new CEnumFormatEtc( this );
162 static_cast< LPUNKNOWN
>( *ppenumFormatetc
)->AddRef( );
169 // IDataObject->QueryGetData
171 STDMETHODIMP
CXTDataObject::QueryGetData( LPFORMATETC pFormatetc
)
176 // IDataObject->GetDataHere
178 STDMETHODIMP
CXTDataObject::GetDataHere( LPFORMATETC
, LPSTGMEDIUM
)
183 // IDataObject->GetCanonicalFormatEtc
185 STDMETHODIMP
CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC
, LPFORMATETC
)
190 // IDataObject->SetData
192 STDMETHODIMP
CXTDataObject::SetData( LPFORMATETC
, LPSTGMEDIUM
, BOOL
)
197 // IDataObject->DAdvise
199 STDMETHODIMP
CXTDataObject::DAdvise( LPFORMATETC
, DWORD
, LPADVISESINK
, DWORD
* )
204 // IDataObject->DUnadvise
206 STDMETHODIMP
CXTDataObject::DUnadvise( DWORD
)
211 // IDataObject->EnumDAdvise
213 STDMETHODIMP
CXTDataObject::EnumDAdvise( LPENUMSTATDATA
* )
218 // for our convenience
220 CXTDataObject::operator IDataObject
*( )
222 return static_cast< IDataObject
* >( this );
229 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj
) :
231 m_pUnkDataObj( pUnkDataObj
),
236 // IUnknown->QueryInterface
238 STDMETHODIMP
CEnumFormatEtc::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
240 if ( NULL
== ppvObject
)
243 HRESULT hr
= E_NOINTERFACE
;
247 if ( ( __uuidof( IUnknown
) == iid
) || ( __uuidof( IEnumFORMATETC
) == iid
) )
249 *ppvObject
= static_cast< IUnknown
* >( this );
250 static_cast< LPUNKNOWN
>( *ppvObject
)->AddRef( );
259 STDMETHODIMP_(ULONG
) CEnumFormatEtc::AddRef( )
261 // keep the dataobject alive
262 m_pUnkDataObj
->AddRef( );
263 return InterlockedIncrement( &m_nRefCnt
);
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
);
283 // IEnumFORMATETC->Next
285 STDMETHODIMP
CEnumFormatEtc::Next( ULONG celt
, LPFORMATETC rgelt
, ULONG
* pceltFetched
)
287 if ( ( 0 != celt
) && ( NULL
== rgelt
) )
291 ULONG ulToFetch
= celt
;
292 HRESULT hr
= S_FALSE
;
294 while( m_nCurrPos
< 1 )
296 rgelt
->cfFormat
= CF_TEXT
;
298 rgelt
->dwAspect
= DVASPECT_CONTENT
;
300 rgelt
->tymed
= TYMED_HGLOBAL
;
308 if ( ulFetched
== celt
)
311 if ( NULL
!= pceltFetched
)
313 *pceltFetched
= ulFetched
;
319 // IEnumFORMATETC->Skip
321 STDMETHODIMP
CEnumFormatEtc::Skip( ULONG celt
)
323 HRESULT hr
= S_FALSE
;
326 if ( ( m_nCurrPos + celt ) < m_nClipFormats )
336 // IEnumFORMATETC->Reset
338 STDMETHODIMP
CEnumFormatEtc::Reset( )
344 // IEnumFORMATETC->Clone
346 STDMETHODIMP
CEnumFormatEtc::Clone( IEnumFORMATETC
** ppenum
)
348 OSL_ASSERT( NULL
!= ppenum
);
350 if ( NULL
== ppenum
)
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( );
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */