From 6c59a4e7af6bdbc072273daa7eb29388302e0269 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 16 May 2019 22:10:43 +0200 Subject: [PATCH 1/6] Fix wxStaticBitmap auto-resizing under MSW wxStaticBitmap tried to automatically resize itself to its new size, but did it wrongly (since what looks like ever, or at least since the first version in the VCS, which is 2bda0e173844e8e0f8acf4e8ad8b5c26e5c6fe5d, from 21 years ago) because it assumed that the size of wxStaticBitmap window is the same as the size of the bitmap it is showing, which is not the case when it uses border style such as wxBORDER_RAISED. Fix this by resizing it to the current size adjusted by the difference between the old and new bitmap sizes. Alternative approach would be to just use SetSize(GetBestSize()), as the other ports do, but keep the changes to the minimum for now. Closes #18398. --- src/msw/statbmp.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/msw/statbmp.cpp b/src/msw/statbmp.cpp index c574663f6c..c21fbd8fa0 100644 --- a/src/msw/statbmp.cpp +++ b/src/msw/statbmp.cpp @@ -278,6 +278,14 @@ void wxStaticBitmap::MSWReplaceImageHandle(WXLPARAM handle) void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image) { + wxSize sizeOld; + if ( m_image ) + sizeOld = m_image->GetSize(); + + wxSize sizeNew; + if ( image ) + sizeNew = image->GetSize(); + Free(); InvalidateBestSize(); @@ -324,17 +332,12 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image) m_currentHandle = (WXHANDLE)handle; m_ownsCurrentHandle = handle != handleOrig; - if ( ImageIsOk() ) + if ( sizeNew != sizeOld ) { - int width = image->GetWidth(), - height = image->GetHeight(); - if ( width && height ) - { - w = width; - h = height; + w += sizeNew.x - sizeOld.x; + h += sizeNew.y - sizeOld.y; - MSWMoveWindowToAnyPosition(GetHwnd(), x, y, width, height, false); - } + MSWMoveWindowToAnyPosition(GetHwnd(), x, y, w, h, false); } RECT rect; From 65e5c3dbc7393d4d18bcaeb9a58486e5aed416ee Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 16 May 2019 22:17:06 +0200 Subject: [PATCH 2/6] Avoid invalidating the best size in wxStaticBitmap unnecessarily This is just a micro-optimization: there is no need to call InvalidateBestSize() if the size of the bitmap doesn't actually change (as will most often be the case when this method is called after the control creation). --- src/msw/statbmp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/msw/statbmp.cpp b/src/msw/statbmp.cpp index c21fbd8fa0..2a0ad74624 100644 --- a/src/msw/statbmp.cpp +++ b/src/msw/statbmp.cpp @@ -287,7 +287,9 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image) sizeNew = image->GetSize(); Free(); - InvalidateBestSize(); + + if ( sizeNew != sizeOld ) + InvalidateBestSize(); m_isIcon = image->IsKindOf( wxCLASSINFO(wxIcon) ); // the image has already been copied From 8a1e679640fd5f55b58bd2e2c9f40e1e5a25f478 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 16 May 2019 22:18:38 +0200 Subject: [PATCH 3/6] Remove another unnecessary call from MSW wxStaticBitmap DeleteCurrentHandleIfNeeded() is already called from Free() which is unconditionally called at the beginning of the function, so there is no need to call it again. --- src/msw/statbmp.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/msw/statbmp.cpp b/src/msw/statbmp.cpp index 2a0ad74624..32a4a41c8e 100644 --- a/src/msw/statbmp.cpp +++ b/src/msw/statbmp.cpp @@ -329,8 +329,6 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image) MSWReplaceImageHandle((WXLPARAM)handle); - DeleteCurrentHandleIfNeeded(); - m_currentHandle = (WXHANDLE)handle; m_ownsCurrentHandle = handle != handleOrig; From f69c3c203e6588c5d4330d9e4115c56ed8d76080 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 16 May 2019 22:22:37 +0200 Subject: [PATCH 4/6] Remove redundant wxStaticBitmap::m_isIcon assignment No need to set m_isIcon before overwriting it just 2 lines below. --- src/msw/statbmp.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/msw/statbmp.cpp b/src/msw/statbmp.cpp index 32a4a41c8e..faeb3855df 100644 --- a/src/msw/statbmp.cpp +++ b/src/msw/statbmp.cpp @@ -104,8 +104,6 @@ bool wxStaticBitmap::Create(wxWindow *parent, // we may have either bitmap or icon: if a bitmap with mask is passed, we // will transform it to an icon ourselves because otherwise the mask will // be ignored by Windows - m_isIcon = bitmap.IsKindOf(wxCLASSINFO(wxIcon)); - wxGDIImage *image = ConvertImage( bitmap ); m_isIcon = image->IsKindOf( wxCLASSINFO(wxIcon) ); From eb0fc45d9254d0bc84a45825825f6e4b430fa0d0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 16 May 2019 22:24:07 +0200 Subject: [PATCH 5/6] Add a comment explaining why m_isIcon needs to be set early No changes, just explain why we can't simply let SetImageNoCopy() set m_isIcon to the correct value and need to do it here instead. --- src/msw/statbmp.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/msw/statbmp.cpp b/src/msw/statbmp.cpp index faeb3855df..f19dc32f81 100644 --- a/src/msw/statbmp.cpp +++ b/src/msw/statbmp.cpp @@ -105,6 +105,11 @@ bool wxStaticBitmap::Create(wxWindow *parent, // will transform it to an icon ourselves because otherwise the mask will // be ignored by Windows wxGDIImage *image = ConvertImage( bitmap ); + + // Note that m_isIcon must be set before calling MSWCreateControl() so that + // it creates the control with the correct style, as returned by + // MSWGetStyle(), which uses m_isIcon to determine whether to use SS_ICON + // or SS_BITMAP. m_isIcon = image->IsKindOf( wxCLASSINFO(wxIcon) ); // create the native control From 2039d864ba312a74ee504c3794ba848c0bedd492 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 16 May 2019 22:26:13 +0200 Subject: [PATCH 6/6] Avoid updating wxStaticBitmap unnecessarily If the kind of the bitmap/icon used by the control didn't change (which will be most often the case, as using both an icon and a bitmap with the same control is vanishingly rare), there is no need to update the window style. No real changes, this is just a micro-optimization. --- src/msw/statbmp.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/msw/statbmp.cpp b/src/msw/statbmp.cpp index f19dc32f81..46b7ee876c 100644 --- a/src/msw/statbmp.cpp +++ b/src/msw/statbmp.cpp @@ -289,6 +289,8 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image) if ( image ) sizeNew = image->GetSize(); + const bool wasIcon = m_isIcon; + Free(); if ( sizeNew != sizeOld ) @@ -326,9 +328,13 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image) } } #endif // wxUSE_WXDIB - wxMSWWinStyleUpdater(GetHwnd()) - .TurnOff(SS_BITMAP | SS_ICON) - .TurnOn(m_isIcon ? SS_ICON : SS_BITMAP); + + if ( m_isIcon != wasIcon ) + { + wxMSWWinStyleUpdater(GetHwnd()) + .TurnOff(SS_BITMAP | SS_ICON) + .TurnOn(m_isIcon ? SS_ICON : SS_BITMAP); + } MSWReplaceImageHandle((WXLPARAM)handle);