433 lines
12 KiB
C++
433 lines
12 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_dtrans.hxx"
|
|
|
|
//------------------------------------------------------------------------
|
|
// includes
|
|
//------------------------------------------------------------------------
|
|
#include <osl/diagnose.h>
|
|
|
|
#include "../DTransHelper.hxx"
|
|
|
|
#include "XTDo.hxx"
|
|
|
|
#if defined _MSC_VER
|
|
#pragma warning(push,1)
|
|
#endif
|
|
#include <windows.h>
|
|
#include <ole2.h>
|
|
#if defined _MSC_VER
|
|
#pragma warning(pop)
|
|
#endif
|
|
#include <memory>
|
|
#include <tchar.h>
|
|
|
|
//------------------------------------------------------------------------
|
|
// namespace directives
|
|
//------------------------------------------------------------------------
|
|
|
|
using namespace ::std;
|
|
|
|
//============================================================================
|
|
// OTWrapperDataObject
|
|
//============================================================================
|
|
|
|
//------------------------------------------------------------------------
|
|
// ctor
|
|
//------------------------------------------------------------------------
|
|
/*
|
|
in the constructor we enumerate all formats offered by the transferable
|
|
and convert the formats into formatetc structures
|
|
if the transferable supports text in different charsets we use either
|
|
the charset equal to the charset of the current thread or an arbitrary
|
|
charset supported by the transferable and the system
|
|
if the transferable supports only unicodetext we offer in addition to
|
|
this text in the charset of the current thread
|
|
in order to allow the consumer of the clipboard to query for the charset
|
|
of the text in the clipboard we offer a CF_LOCALE
|
|
*/
|
|
CXTDataObject::CXTDataObject( ) :
|
|
m_nRefCnt( 0 )
|
|
{
|
|
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IUnknown->QueryInterface
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
|
|
{
|
|
OSL_ASSERT( NULL != ppvObject );
|
|
|
|
if ( NULL == ppvObject )
|
|
return E_INVALIDARG;
|
|
|
|
HRESULT hr = E_NOINTERFACE;
|
|
|
|
*ppvObject = NULL;
|
|
|
|
if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
|
|
{
|
|
*ppvObject = static_cast< IUnknown* >( this );
|
|
( (LPUNKNOWN)*ppvObject )->AddRef( );
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IUnknown->AddRef
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
|
|
{
|
|
return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IUnknown->Release
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP_(ULONG) CXTDataObject::Release( )
|
|
{
|
|
// we need a helper variable because it's
|
|
// not allowed to access a member variable
|
|
// after an object is destroyed
|
|
ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
|
|
|
|
if ( 0 == nRefCnt )
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return nRefCnt;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------
|
|
|
|
IDataObject->GetData
|
|
we deliver data only into global memory
|
|
|
|
algo:
|
|
1. convert the given formatect struct into a valid dataflavor
|
|
2. if the transferable directly supports the requested format
|
|
2.1. if text data requested add a trailing '\0' in order to prevent
|
|
problems (windows needs '\0' terminated strings
|
|
2.2. we expect unicode data as Sequence< sal_Unicode > and all other
|
|
text and raw data as Sequence< sal_Int8 >
|
|
|
|
------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
|
|
{
|
|
if ( ( NULL == pFormatetc ) || ( NULL == pmedium ) )
|
|
return E_INVALIDARG;
|
|
|
|
HRESULT hr = E_FAIL;
|
|
char pBuff[] = "Test OleClipboard";
|
|
|
|
if ( CF_TEXT == pFormatetc->cfFormat )
|
|
{
|
|
CHGlobalHelper hGlobHlp( TRUE );
|
|
|
|
hGlobHlp.Write( pBuff, sizeof( pBuff ), NULL );
|
|
|
|
pmedium->tymed = TYMED_HGLOBAL;
|
|
pmedium->hGlobal = hGlobHlp.GetHGlobal( );
|
|
pmedium->pUnkForRelease = NULL;
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IDataObject->EnumFormatEtc
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
|
|
{
|
|
if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) )
|
|
return E_INVALIDARG;
|
|
|
|
*ppenumFormatetc = NULL;
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if ( DATADIR_GET == dwDirection )
|
|
{
|
|
*ppenumFormatetc = new CEnumFormatEtc( this );
|
|
static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IDataObject->QueryGetData
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IDataObject->GetDataHere
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IDataObject->GetCanonicalFormatEtc
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IDataObject->SetData
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IDataObject->DAdvise
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IDataObject->DUnadvise
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// IDataObject->EnumDAdvise
|
|
//------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// for our convenience
|
|
//------------------------------------------------------------------------
|
|
|
|
CXTDataObject::operator IDataObject*( )
|
|
{
|
|
return static_cast< IDataObject* >( this );
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
// CEnumFormatEtc
|
|
//============================================================================
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ctor
|
|
//----------------------------------------------------------------------------
|
|
|
|
CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) :
|
|
m_nRefCnt( 0 ),
|
|
m_pUnkDataObj( pUnkDataObj ),
|
|
m_nCurrPos( 0 )
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IUnknown->QueryInterface
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
|
|
{
|
|
if ( NULL == ppvObject )
|
|
return E_INVALIDARG;
|
|
|
|
HRESULT hr = E_NOINTERFACE;
|
|
|
|
*ppvObject = NULL;
|
|
|
|
if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) )
|
|
{
|
|
*ppvObject = static_cast< IUnknown* >( this );
|
|
static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IUnknown->AddRef
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
|
|
{
|
|
// keep the dataobject alive
|
|
m_pUnkDataObj->AddRef( );
|
|
return InterlockedIncrement( &m_nRefCnt );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IUnknown->Release
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
|
|
{
|
|
// release the outer dataobject
|
|
m_pUnkDataObj->Release( );
|
|
|
|
// we need a helper variable because it's
|
|
// not allowed to access a member variable
|
|
// after an object is destroyed
|
|
ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
|
|
if ( 0 == nRefCnt )
|
|
delete this;
|
|
|
|
return nRefCnt;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IEnumFORMATETC->Next
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CEnumFormatEtc::Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched )
|
|
{
|
|
if ( ( 0 != celt ) && ( NULL == rgelt ) )
|
|
return E_INVALIDARG;
|
|
|
|
ULONG ulFetched = 0;
|
|
ULONG ulToFetch = celt;
|
|
HRESULT hr = S_FALSE;
|
|
|
|
while( m_nCurrPos < 1 )
|
|
{
|
|
rgelt->cfFormat = CF_TEXT;
|
|
rgelt->ptd = NULL;
|
|
rgelt->dwAspect = DVASPECT_CONTENT;
|
|
rgelt->lindex = -1;
|
|
rgelt->tymed = TYMED_HGLOBAL;
|
|
|
|
++m_nCurrPos;
|
|
++rgelt;
|
|
--ulToFetch;
|
|
++ulFetched;
|
|
}
|
|
|
|
if ( ulFetched == celt )
|
|
hr = S_OK;
|
|
|
|
if ( NULL != pceltFetched )
|
|
{
|
|
*pceltFetched = ulFetched;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IEnumFORMATETC->Skip
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
/*
|
|
if ( ( m_nCurrPos + celt ) < m_nClipFormats )
|
|
{
|
|
m_nCurrPos += celt;
|
|
hr = S_OK;
|
|
}
|
|
*/
|
|
|
|
return hr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IEnumFORMATETC->Reset
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CEnumFormatEtc::Reset( )
|
|
{
|
|
m_nCurrPos = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IEnumFORMATETC->Clone
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
|
|
{
|
|
OSL_ASSERT( NULL != ppenum );
|
|
|
|
if ( NULL == ppenum )
|
|
return E_INVALIDARG;
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
*ppenum = NULL;
|
|
|
|
CEnumFormatEtc* pCEnumFEtc = new CEnumFormatEtc( m_pUnkDataObj );
|
|
if ( NULL != pCEnumFEtc )
|
|
{
|
|
pCEnumFEtc->m_nCurrPos = m_nCurrPos;
|
|
*ppenum = static_cast< IEnumFORMATETC* >( pCEnumFEtc );
|
|
static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
|
|
hr = NOERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|