diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index 042e8348e6..4bad3f375f 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -481,6 +481,9 @@ private: // another WM_SIZE to be generated. int m_inResize = 0; + // Non-zero while the native control is auto-sizing a column, which it does + // by sending NM_CUSTOMDRAW notifications for all of its items. + int m_inAutoSize = 0; wxDECLARE_DYNAMIC_CLASS(wxListCtrl); wxDECLARE_EVENT_TABLE(); diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index 5a5422db45..233d35f8c1 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -843,7 +843,18 @@ bool wxListCtrl::SetColumnWidth(int col, int width) return true; } - if ( !ListView_SetColumnWidth(GetHwnd(), col, width) ) + // See the comment in OnCustomDraw() for why we need to know about this. + const bool autoSize = width == LVSCW_AUTOSIZE || + width == LVSCW_AUTOSIZE_USEHEADER; + if ( autoSize ) + m_inAutoSize++; + + const bool ok = ListView_SetColumnWidth(GetHwnd(), col, width) != FALSE; + + if ( autoSize ) + m_inAutoSize--; + + if ( !ok ) return false; // Failure to explicitly refresh the control with horizontal rules results @@ -3540,7 +3551,11 @@ WXLPARAM wxListCtrl::OnCustomDraw(WXLPARAM lParam) // // for virtual controls, always suppose that we have attributes as // there is no way to check for this - if ( IsVirtual() || m_hasAnyAttr || wxMSWDarkMode::IsActive() ) + // + // in dark mode we also need to draw all items ourselves, but not + // when auto-sizing the columns, see CDDS_ITEMPREPAINT case below + if ( IsVirtual() || m_hasAnyAttr || + (wxMSWDarkMode::IsActive() && !m_inAutoSize) ) return CDRF_NOTIFYITEMDRAW; break; @@ -3552,7 +3567,15 @@ WXLPARAM wxListCtrl::OnCustomDraw(WXLPARAM lParam) // repeat the same drawing once per column, which is not only // wasteful but also results in visible delays when scrolling // lists with many columns. - if ( wxMSWDarkMode::IsActive() && InReportView() ) + // + // Don't do it while auto-sizing a column however: in this case the + // native control sends us this notification for every item, but + // only to allow us to select a different font for measuring it, so + // painting the entire row here would be useless and would make + // setting the column width very slow for big controls (see + // #24011). Just fall through to the default handling below, which + // takes care of the custom fonts, if any, instead. + if ( wxMSWDarkMode::IsActive() && InReportView() && !m_inAutoSize ) { const int item = nmcd.dwItemSpec;