From 15d82f05e184b6c5404b402f2bcb5290186b59ed Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 14 Mar 2014 19:21:03 +0000 Subject: [PATCH] Also free internal handlers when wxMSW wxStaticBitmap is destroyed. r76141 fixed the resource leak when wxStaticBitmap image was replaced by another one but the leak still happened at the end, when the wxStaticBitmap was destroyed. Fix it there as well in the same way. Closes #16068. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@76145 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/statbmp.h | 4 ++++ src/msw/statbmp.cpp | 26 +++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/wx/msw/statbmp.h b/include/wx/msw/statbmp.h index 165ddb5af1..7cb93efd06 100644 --- a/include/wx/msw/statbmp.h +++ b/include/wx/msw/statbmp.h @@ -85,6 +85,10 @@ protected: WXHANDLE m_currentHandle; private: + // 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); + 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 7296920f7b..1205600727 100644 --- a/src/msw/statbmp.cpp +++ b/src/msw/statbmp.cpp @@ -190,6 +190,8 @@ wxBitmap wxStaticBitmap::GetBitmap() const void wxStaticBitmap::Free() { + MSWReplaceImageHandle(0); + wxDELETE(m_image); } @@ -251,6 +253,19 @@ void wxStaticBitmap::SetImage( const wxGDIImage* image ) SetImageNoCopy( convertedImage ); } +void wxStaticBitmap::MSWReplaceImageHandle(WXLPARAM handle) +{ + HGDIOBJ oldHandle = (HGDIOBJ)::SendMessage(GetHwnd(), STM_SETIMAGE, + m_isIcon ? IMAGE_ICON : IMAGE_BITMAP, (LPARAM)handle); + // detect if this is still the handle we passed before or + // if the static-control made a copy of the bitmap! + if (oldHandle != 0 && oldHandle != (HGDIOBJ) m_currentHandle) + { + // the static control made a copy and we are responsible for deleting it + ::DeleteObject((HGDIOBJ) oldHandle); + } +} + void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image) { Free(); @@ -290,15 +305,8 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image) LONG style = ::GetWindowLong( (HWND)GetHWND(), GWL_STYLE ) ; ::SetWindowLong( (HWND)GetHWND(), GWL_STYLE, ( style & ~( SS_BITMAP|SS_ICON ) ) | ( m_isIcon ? SS_ICON : SS_BITMAP ) ); - HGDIOBJ oldHandle = (HGDIOBJ)::SendMessage(GetHwnd(), STM_SETIMAGE, - m_isIcon ? IMAGE_ICON : IMAGE_BITMAP, (LPARAM)handle); - // detect if this is still the handle we passed before or - // if the static-control made a copy of the bitmap! - if (oldHandle != 0 && oldHandle != (HGDIOBJ) m_currentHandle) - { - // the static control made a copy and we are responsible for deleting it - ::DeleteObject((HGDIOBJ) oldHandle); - } + + MSWReplaceImageHandle((WXLPARAM)handle); // Save bitmap handle only if it's not a temporary one, otherwise it's // going to be destroyed right now anyhow.