Fix crash when using wxDataObjectComposite with bitmap in wxMSW
This reverts the changes of b1fad4da44 (Convert 0RGB wxBitmaps to RGB
when copying them to clipboard, 2017-04-30) that added a cast from
wxDataObject to wxBitmapDataObject for any object supporting bitmaps,
which resulted in a crash when this happened to be wxDataObjectComposite
and not wxBitmapDataObject, and does the same thing in
wxBitmapDataObject itself which now converts 0RGB bitmaps to RGB ones
when asked for the bitmap data.
The main change is that the code using wxDataObjectComposite doesn't
crash any longer, but another nice side effect is that this is possibly
more efficient as well because the conversion could be skipped entirely
if the bitmap is never pasted.
See #17640.
Closes #23564.
This commit is contained in:
parent
cec057519e
commit
675728e1c0
2 changed files with 38 additions and 22 deletions
|
|
@ -34,7 +34,6 @@
|
|||
#include "wx/intl.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/dataobj.h"
|
||||
#include "wx/dcmemory.h"
|
||||
#endif
|
||||
|
||||
#if wxUSE_METAFILE
|
||||
|
|
@ -585,26 +584,6 @@ bool wxClipboard::AddData( wxDataObject *data )
|
|||
|
||||
wxCHECK_MSG( data, false, wxT("data is invalid") );
|
||||
|
||||
const wxDataFormat format = data->GetPreferredFormat();
|
||||
if ( format == wxDF_BITMAP || format == wxDF_DIB )
|
||||
{
|
||||
wxBitmapDataObject* bmpData = (wxBitmapDataObject*)data;
|
||||
wxBitmap bmp = bmpData->GetBitmap();
|
||||
wxASSERT_MSG( bmp.IsOk(), wxS("Invalid bitmap") );
|
||||
// Replace 0RGB bitmap with its RGB copy
|
||||
// to ensure compatibility with applications
|
||||
// not recognizing bitmaps in 0RGB format.
|
||||
if ( bmp.GetDepth() == 32 && !bmp.HasAlpha() )
|
||||
{
|
||||
wxBitmap bmpRGB(bmp.GetSize(), 24);
|
||||
wxMemoryDC dc(bmpRGB);
|
||||
dc.DrawBitmap(bmp, 0, 0);
|
||||
dc.SelectObject(wxNullBitmap);
|
||||
|
||||
bmpData->SetBitmap(bmpRGB);
|
||||
}
|
||||
}
|
||||
|
||||
#if wxUSE_OLE_CLIPBOARD
|
||||
HRESULT hr = OleSetClipboard(data->GetInterface());
|
||||
if ( FAILED(hr) )
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#if wxUSE_DATAOBJ
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/dcmemory.h"
|
||||
#include "wx/intl.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/utils.h"
|
||||
|
|
@ -1042,9 +1043,41 @@ const wxChar *wxDataObject::GetFormatName(wxDataFormat format)
|
|||
// wxBitmapDataObject supports CF_DIB format
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Modify bitmap if necessary, i.e. if it uses 0RGB format in which alpha
|
||||
// channel is present but is entirely 0, to make it just plain RGB, i.e.
|
||||
// without alpha channel at all, to ensure compatibility with the applications
|
||||
// not recognizing the special case of 0RGB and handling such bitmaps as
|
||||
// completely transparent, see #17640.
|
||||
void RemoveAlphaIfNecessary(wxBitmap& bmp)
|
||||
{
|
||||
// Replace 0RGB bitmap with its RGB copy to ensure compatibility with
|
||||
// applications not recognizing bitmaps in 0RGB format, see #17640.
|
||||
if ( bmp.GetDepth() == 32 && !bmp.HasAlpha() )
|
||||
{
|
||||
wxBitmap bmpRGB(bmp.GetSize(), 24);
|
||||
{
|
||||
wxMemoryDC dc(bmpRGB);
|
||||
dc.DrawBitmap(bmp, 0, 0);
|
||||
}
|
||||
|
||||
bmp = bmpRGB;
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
size_t wxBitmapDataObject::GetDataSize() const
|
||||
{
|
||||
#if wxUSE_WXDIB
|
||||
wxBitmap& bmp = const_cast<wxBitmapDataObject*>(this)->m_bitmap;
|
||||
|
||||
// Note that we need to do this here too and not just in GetDataHere()
|
||||
// because the size of the bitmap without the alpha channel is different.
|
||||
RemoveAlphaIfNecessary(bmp);
|
||||
|
||||
return wxDIB::ConvertFromBitmap(nullptr, GetHbitmapOf(GetBitmap()));
|
||||
#else
|
||||
return 0;
|
||||
|
|
@ -1054,9 +1087,13 @@ size_t wxBitmapDataObject::GetDataSize() const
|
|||
bool wxBitmapDataObject::GetDataHere(void *buf) const
|
||||
{
|
||||
#if wxUSE_WXDIB
|
||||
wxBitmap& bmp = const_cast<wxBitmapDataObject*>(this)->m_bitmap;
|
||||
|
||||
RemoveAlphaIfNecessary(bmp);
|
||||
|
||||
BITMAPINFO * const pbi = (BITMAPINFO *)buf;
|
||||
|
||||
return wxDIB::ConvertFromBitmap(pbi, GetHbitmapOf(GetBitmap())) != 0;
|
||||
return wxDIB::ConvertFromBitmap(pbi, GetHbitmapOf(bmp)) != 0;
|
||||
#else
|
||||
wxUnusedVar(buf);
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue