Fix showing of 32bpp bitmaps without alpha in wxMSW wxStaticBitmap.

The native control doesn't make a secret copy of the image in this case (0RGB
bitmap, i.e. 32bpp ARGB bitmap with all alpha values set to 0) and just shows
the bitmap we assigned to it directly, so we must not delete it in this case,
otherwise nothing is shown at all.

Closes #16084.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76148 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-03-14 19:22:31 +00:00
parent 6b296279ba
commit f9b4d6b18c
2 changed files with 36 additions and 10 deletions

View File

@@ -60,7 +60,7 @@ protected:
virtual wxSize DoGetBestClientSize() const;
// ctor/dtor helpers
void Init() { m_isIcon = true; m_image = NULL; m_currentHandle = 0; }
void Init();
void Free();
// true if icon/bitmap is valid
@@ -85,10 +85,17 @@ protected:
WXHANDLE m_currentHandle;
private:
// Flag indicating whether we own m_currentHandle, i.e. should delete it.
bool m_ownsCurrentHandle;
// Replace the image at the native control level with the given HBITMAP or
// HICON (which can be 0) and destroy the previous image if necessary.
void MSWReplaceImageHandle(WXLPARAM handle);
// Delete the current handle only if we own it.
void DeleteCurrentHandleIfNeeded();
DECLARE_DYNAMIC_CLASS(wxStaticBitmap)
wxDECLARE_EVENT_TABLE();
wxDECLARE_NO_COPY_CLASS(wxStaticBitmap);

View File

@@ -188,10 +188,29 @@ wxBitmap wxStaticBitmap::GetBitmap() const
}
}
void wxStaticBitmap::Init()
{
m_isIcon = true;
m_image = NULL;
m_currentHandle = 0;
m_ownsCurrentHandle = false;
}
void wxStaticBitmap::DeleteCurrentHandleIfNeeded()
{
if ( m_ownsCurrentHandle )
{
::DeleteObject(m_currentHandle);
m_ownsCurrentHandle = false;
}
}
void wxStaticBitmap::Free()
{
MSWReplaceImageHandle(0);
DeleteCurrentHandleIfNeeded();
wxDELETE(m_image);
}
@@ -281,9 +300,12 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image)
GetSize(&w, &h);
#ifdef __WIN32__
HANDLE handle = (HANDLE)m_image->GetHandle();
// Normally we just use the handle of provided image but in some cases we
// create our own temporary bitmap, so the actual handle may end up being
// different from the original one.
const HANDLE handleOrig = (HANDLE)m_image->GetHandle();
HANDLE handle = handleOrig;
AutoHBITMAP hbmpRelease;
if ( !m_isIcon )
{
// wxBitmap normally stores alpha in pre-multiplied format but
@@ -297,9 +319,6 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image)
// not-premultiplied alpha values.
handle = wxDIB(bmp.ConvertToImage(),
wxDIB::PixelFormat_NotPreMultiplied).Detach();
// Ensure that this temporary HBITMAP will be destroyed.
hbmpRelease.Init((HBITMAP)handle);
}
}
LONG style = ::GetWindowLong( (HWND)GetHWND(), GWL_STYLE ) ;
@@ -308,10 +327,10 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image)
MSWReplaceImageHandle((WXLPARAM)handle);
// Save bitmap handle only if it's not a temporary one, otherwise it's
// going to be destroyed right now anyhow.
if ( !hbmpRelease )
m_currentHandle = (WXHANDLE)handle;
DeleteCurrentHandleIfNeeded();
m_currentHandle = (WXHANDLE)handle;
m_ownsCurrentHandle = handle != handleOrig;
#endif // Win32