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:
@@ -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
|
||||||
|
|
||||||
|
@@ -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__
|
||||||
|
Reference in New Issue
Block a user