diff --git a/include/wx/msw/statbmp.h b/include/wx/msw/statbmp.h index 7cb93efd06..55231a2192 100644 --- a/include/wx/msw/statbmp.h +++ b/include/wx/msw/statbmp.h @@ -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); diff --git a/src/msw/statbmp.cpp b/src/msw/statbmp.cpp index 1205600727..a59f96e64a 100644 --- a/src/msw/statbmp.cpp +++ b/src/msw/statbmp.cpp @@ -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