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
This commit is contained in:
Vadim Zeitlin
2006-02-09 03:45:14 +00:00
parent 69e72fda93
commit a8e24848f6
2 changed files with 60 additions and 29 deletions

View File

@@ -40,6 +40,19 @@ public:
bool IsSupportedFormat(const wxDataFormat& format) const bool IsSupportedFormat(const wxDataFormat& format) const
{ return wxDataObjectBase::IsSupported(format, Get); } { 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) // function to return symbolic name of clipboard format (for debug messages)
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
static const wxChar *GetFormatName(wxDataFormat format); static const wxChar *GetFormatName(wxDataFormat format);
@@ -56,6 +69,7 @@ public:
virtual void* SetSizeInBuffer( void* buffer, size_t size, virtual void* SetSizeInBuffer( void* buffer, size_t size,
const wxDataFormat& format ); const wxDataFormat& format );
virtual size_t GetBufferOffset( const wxDataFormat& format ); virtual size_t GetBufferOffset( const wxDataFormat& format );
private: private:
IDataObject *m_pIDataObject; // pointer to the COM interface IDataObject *m_pIDataObject; // pointer to the COM interface

View File

@@ -319,13 +319,8 @@ STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
return DV_E_FORMATETC; return DV_E_FORMATETC;
} }
if ( !format.IsStandard() ) { // we may need extra space for the buffer size
// for custom formats, put the size with the data - alloc the size += m_pDataObject->GetBufferOffset( format );
// 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 );
}
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, size); HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, size);
if ( hGlobal == NULL ) { if ( hGlobal == NULL ) {
@@ -387,10 +382,14 @@ STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc,
} }
wxDataFormat format = pformatetc->cfFormat; wxDataFormat format = pformatetc->cfFormat;
if ( !format.IsStandard() ) {
// for custom formats, put the size with the data // possibly put the size in the beginning of the buffer
pBuf = m_pDataObject->SetSizeInBuffer( pBuf, GlobalSize(hGlobal), format ); pBuf = m_pDataObject->SetSizeInBuffer
} (
pBuf,
::GlobalSize(hGlobal),
format
);
if ( !m_pDataObject->GetDataHere(format, pBuf) ) if ( !m_pDataObject->GetDataHere(format, pBuf) )
return E_UNEXPECTED; return E_UNEXPECTED;
@@ -492,14 +491,9 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
break; break;
#endif #endif
default: default:
{ pBuf = m_pDataObject->
// we suppose that the size precedes the data GetSizeFromBuffer(pBuf, &size, format);
pBuf = m_pDataObject->GetSizeFromBuffer( pBuf, &size, format ); size -= m_pDataObject->GetBufferOffset(format);
if (! format.IsStandard() ) {
// see GetData for corresponding increment
size -= m_pDataObject->GetBufferOffset( format );
}
}
} }
bool ok = m_pDataObject->SetData(format, size, pBuf); bool ok = m_pDataObject->SetData(format, size, pBuf);
@@ -683,27 +677,50 @@ void wxDataObject::SetAutoDelete()
m_pIDataObject = NULL; 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 void* wxDataObject::GetSizeFromBuffer( const void* buffer, size_t* size,
const wxDataFormat& WXUNUSED(format) ) const wxDataFormat& format )
{ {
size_t* p = (size_t*)buffer; SIZE_T realsz = ::HeapSize(::GetProcessHeap(), 0, buffer);
*size = *p; if ( realsz == (SIZE_T)-1 )
{
// note that HeapSize() does not set last error
wxLogApiError(wxT("HeapSize"), 0);
return NULL;
}
return p + 1; *size = realsz;
// 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, void* wxDataObject::SetSizeInBuffer( void* buffer, size_t size,
const wxDataFormat& WXUNUSED(format) ) const wxDataFormat& format )
{ {
size_t* p = (size_t*)buffer; size_t* p = (size_t *)buffer;
*p = size; if ( !NeedsVerbatimData(format) )
{
// prepend the size to the data and skip it
*p++ = size;
}
return p + 1; return p;
} }
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__