From 061e6f9a3ca9e6c14c7f62d32cca18a57c91286a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 9 Dec 2017 19:05:35 +0100 Subject: [PATCH 1/2] Fix flicker when resizing columns of report-mode MSW wxListCtrl Just turn off background erasing to avoid having horrible flicker which can be seen perfectly well simply by drag-resizing a column in a list control with non-default background colour. See https://github.com/wxWidgets/wxWidgets/pull/374 --- docs/changes.txt | 1 + src/msw/listctrl.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index 4b3e200dff..1b7d72f6fb 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -442,6 +442,7 @@ wxMSW: - Fix UTF-32 conversion for non-BMP characters (ARATA Mizuki). - Use correct parent for the native modal dialogs (Andreas Falkenhahn). - Fix layout of wxSlider with wxSL_VALUE_LABEL only (gafatoa). +- Fix flicker when resizing columns of report-mode wxListCtrl. wxOSX/Cocoa: diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index ba30bd6e05..d46e7f000d 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -334,6 +334,10 @@ void wxListCtrl::MSWSetExListStyles() // it seems better to enable it by default than disable LVS_EX_HEADERDRAGDROP ); + + // As we use LVS_EX_DOUBLEBUFFER above, we don't need to erase our + // background and doing it only results in flicker. + SetBackgroundStyle(wxBG_STYLE_PAINT); } WXDWORD wxListCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const From ef91e5ecbe24580daca6e49fbf9412eb88fa2655 Mon Sep 17 00:00:00 2001 From: Steve Browne Date: Tue, 20 Dec 2016 12:44:14 -0500 Subject: [PATCH 2/2] Implement wxTreeCtrl::SetDoubleBuffered() in MSW wxTreeCtrl Also don't erase background when the control is double-buffered because it's not necessary and can cause flicker. See https://github.com/wxWidgets/wxWidgets/pull/374 --- docs/changes.txt | 1 + include/wx/msw/missing.h | 9 +++++++++ include/wx/msw/treectrl.h | 3 +++ src/msw/treectrl.cpp | 40 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index 1b7d72f6fb..0fe16c3658 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -443,6 +443,7 @@ wxMSW: - Use correct parent for the native modal dialogs (Andreas Falkenhahn). - Fix layout of wxSlider with wxSL_VALUE_LABEL only (gafatoa). - Fix flicker when resizing columns of report-mode wxListCtrl. +- Implement wxTreeCtrl::SetDoubleBuffered() (Steve Browne). wxOSX/Cocoa: diff --git a/include/wx/msw/missing.h b/include/wx/msw/missing.h index 1b09f730e9..523df76487 100644 --- a/include/wx/msw/missing.h +++ b/include/wx/msw/missing.h @@ -239,6 +239,10 @@ #define TV_FIRST 0x1100 #endif +#ifndef TVS_EX_DOUBLEBUFFER + #define TVS_EX_DOUBLEBUFFER 0x0004 +#endif + #ifndef TVS_FULLROWSELECT #define TVS_FULLROWSELECT 0x1000 #endif @@ -248,6 +252,11 @@ #define TVM_SETTEXTCOLOR (TV_FIRST + 30) #endif +#ifndef TVM_SETEXTENDEDSTYLE + #define TVM_SETEXTENDEDSTYLE (TV_FIRST + 44) + #define TVM_GETEXTENDEDSTYLE (TV_FIRST + 45) +#endif + // Various defines used by the webview library that are needed by mingw #ifndef DISPID_COMMANDSTATECHANGE diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index 4a5eb1ea57..67b040a5d1 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -202,6 +202,9 @@ public: // returns true if the platform should explicitly apply a theme border virtual bool CanApplyThemeBorder() const wxOVERRIDE { return false; } + virtual bool IsDoubleBuffered() const wxOVERRIDE; + virtual void SetDoubleBuffered(bool on) wxOVERRIDE; + protected: // Implement "update locking" in a custom way for this control. virtual void DoFreeze() wxOVERRIDE; diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 1082912d9b..9bda855c32 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -795,6 +795,46 @@ bool wxTreeCtrl::Create(wxWindow *parent, return true; } +bool wxTreeCtrl::IsDoubleBuffered() const +{ + if ( !GetHwnd() ) + return false; + + // Notice that TVM_GETEXTENDEDSTYLE is supported since XP, so we can always + // send this message, no need for comctl32.dll version check here. + const LRESULT + exTreeStyle = ::SendMessage(GetHwnd(), TVM_GETEXTENDEDSTYLE, 0, 0); + + return (exTreeStyle & TVS_EX_DOUBLEBUFFER) != 0; +} + +void wxTreeCtrl::SetDoubleBuffered(bool on) +{ + if ( !GetHwnd() ) + return; + + // TVS_EX_DOUBLEBUFFER is only supported since Vista, don't try to set it + // under XP, who knows what could this do. + if ( wxApp::GetComCtl32Version() >= 610 ) + { + const HRESULT hr = ::SendMessage(GetHwnd(), + TVM_SETEXTENDEDSTYLE, + TVS_EX_DOUBLEBUFFER, + on ? TVS_EX_DOUBLEBUFFER : 0); + if ( hr == S_OK ) + { + // There is no need to erase background for a double-buffered + // window, so disable it when enabling double buffering and restore + // the default background style value when disabling it. + SetBackgroundStyle(on ? wxBG_STYLE_PAINT : wxBG_STYLE_ERASE); + } + else + { + wxLogApiError("TreeView_SetExtendedStyle(TVS_EX_DOUBLEBUFFER)", hr); + } + } +} + wxTreeCtrl::~wxTreeCtrl() { m_isBeingDeleted = true;