From a8e24848f67a655c6845420caf00a29100e38d9f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 9 Feb 2006 03:45:14 +0000 Subject: [PATCH] don't put the size of the data with the data itself by default (but allow it for compatibility with previous versions) (modified patch 1288868) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37406 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/ole/dataobj.h | 14 +++++++ src/msw/ole/dataobj.cpp | 75 ++++++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/include/wx/msw/ole/dataobj.h b/include/wx/msw/ole/dataobj.h index 0553a5a8c8..0cb65ba03c 100644 --- a/include/wx/msw/ole/dataobj.h +++ b/include/wx/msw/ole/dataobj.h @@ -40,6 +40,19 @@ public: bool IsSupportedFormat(const wxDataFormat& format) const { return wxDataObjectBase::IsSupported(format, Get); } + // if this method returns false, this wxDataObject will be copied to + // the clipboard with its size prepended to it, which is compatible with + // older wx versions + // + // if returns true, then this wxDataObject will be copied to the clipboard + // without any additional information and ::HeapSize() function will be used + // to get the size of that data + virtual bool NeedsVerbatimData(const wxDataFormat& WXUNUSED(format)) const + { + // return false from here only for compatibility with earlier wx versions + return true; + } + // function to return symbolic name of clipboard format (for debug messages) #ifdef __WXDEBUG__ static const wxChar *GetFormatName(wxDataFormat format); @@ -56,6 +69,7 @@ public: virtual void* SetSizeInBuffer( void* buffer, size_t size, const wxDataFormat& format ); virtual size_t GetBufferOffset( const wxDataFormat& format ); + private: IDataObject *m_pIDataObject; // pointer to the COM interface diff --git a/src/msw/ole/dataobj.cpp b/src/msw/ole/dataobj.cpp index 2f71260198..ded312e08d 100644 --- a/src/msw/ole/dataobj.cpp +++ b/src/msw/ole/dataobj.cpp @@ -319,13 +319,8 @@ STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) return DV_E_FORMATETC; } - if ( !format.IsStandard() ) { - // for custom formats, put the size with the data - alloc the - // space for it - // MB: not completely sure this is correct, - // even if I can't figure out what's wrong - size += m_pDataObject->GetBufferOffset( format ); - } + // we may need extra space for the buffer size + size += m_pDataObject->GetBufferOffset( format ); HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, size); if ( hGlobal == NULL ) { @@ -387,10 +382,14 @@ STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc, } wxDataFormat format = pformatetc->cfFormat; - if ( !format.IsStandard() ) { - // for custom formats, put the size with the data - pBuf = m_pDataObject->SetSizeInBuffer( pBuf, GlobalSize(hGlobal), format ); - } + + // possibly put the size in the beginning of the buffer + pBuf = m_pDataObject->SetSizeInBuffer + ( + pBuf, + ::GlobalSize(hGlobal), + format + ); if ( !m_pDataObject->GetDataHere(format, pBuf) ) return E_UNEXPECTED; @@ -492,14 +491,9 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc, break; #endif default: - { - // we suppose that the size precedes the data - pBuf = m_pDataObject->GetSizeFromBuffer( pBuf, &size, format ); - if (! format.IsStandard() ) { - // see GetData for corresponding increment - size -= m_pDataObject->GetBufferOffset( format ); - } - } + pBuf = m_pDataObject-> + GetSizeFromBuffer(pBuf, &size, format); + size -= m_pDataObject->GetBufferOffset(format); } bool ok = m_pDataObject->SetData(format, size, pBuf); @@ -683,27 +677,50 @@ void wxDataObject::SetAutoDelete() m_pIDataObject = NULL; } -size_t wxDataObject::GetBufferOffset( const wxDataFormat& WXUNUSED(format) ) +size_t wxDataObject::GetBufferOffset(const wxDataFormat& format ) { - return sizeof(size_t); + // if we prepend the size of the data to the buffer itself, account for it + return NeedsVerbatimData(format) ? 0 : sizeof(size_t); } const void* wxDataObject::GetSizeFromBuffer( const void* buffer, size_t* size, - const wxDataFormat& WXUNUSED(format) ) + const wxDataFormat& format ) { - size_t* p = (size_t*)buffer; - *size = *p; + SIZE_T realsz = ::HeapSize(::GetProcessHeap(), 0, buffer); + if ( realsz == (SIZE_T)-1 ) + { + // note that HeapSize() does not set last error + wxLogApiError(wxT("HeapSize"), 0); + return NULL; + } + + *size = realsz; - return p + 1; + // check if this data has its size prepended (as it was by default for wx + // programs prior 2.6.3): + size_t *p = (size_t *)buffer; + if ( *p == realsz ) + { + if ( NeedsVerbatimData(format) ) + wxLogDebug(wxT("Apparent data format mismatch: size not needed")); + + p++; // this data has its size prepended; skip first DWORD + } + + return p; } void* wxDataObject::SetSizeInBuffer( void* buffer, size_t size, - const wxDataFormat& WXUNUSED(format) ) + const wxDataFormat& format ) { - size_t* p = (size_t*)buffer; - *p = size; + size_t* p = (size_t *)buffer; + if ( !NeedsVerbatimData(format) ) + { + // prepend the size to the data and skip it + *p++ = size; + } - return p + 1; + return p; } #ifdef __WXDEBUG__ -- 2.45.2