Add dark mode support to wxHeaderCtrl

Extract the code setting up the header control colours for the dark mode
from src/msw/listctrl.cpp into wxMSWHeaderCtrlCustomDraw and reuse it in
wxHeaderCtrl too.
This commit is contained in:
Vadim Zeitlin 2022-12-09 02:50:18 +00:00
parent ca5f244f15
commit a37f28bcb6
3 changed files with 35 additions and 8 deletions

View file

@ -12,6 +12,7 @@
#include "wx/itemattr.h"
#include "wx/msw/uxtheme.h"
#include "wx/msw/wrapcctl.h"
namespace wxMSWImpl
@ -67,6 +68,25 @@ public:
{
}
// Set the colours to the ones used by "Header" theme.
//
// This is required, for unknown reasons, when using dark mode, because
// enabling it for the header control changes the background, but not the
// foreground, making the text completely unreadable.
//
// If this is ever fixed in later Windows versions, this function wouldn't
// need to be called any more.
void UseHeaderThemeColors(HWND hwndHdr)
{
wxUxThemeHandle theme{hwndHdr, L"Header"};
m_attr.SetTextColour(theme.GetColour(HP_HEADERITEM, TMT_TEXTCOLOR));
// Note that TMT_FILLCOLOR doesn't seem to exist in this theme but the
// correct background colour is already used in "ItemsView" theme by
// default anyhow.
}
// Make this field public to let the control update it directly when its
// attributes change.
wxItemAttr m_attr;

View file

@ -35,6 +35,7 @@
#include "wx/msw/wrapcctl.h"
#include "wx/msw/private.h"
#include "wx/msw/private/customdraw.h"
#include "wx/msw/private/darkmode.h"
#include "wx/msw/private/winstyle.h"
#ifndef HDM_SETBITMAPMARGIN
@ -93,6 +94,8 @@ protected:
int sizeFlags = wxSIZE_AUTO) override;
virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) override;
virtual const wchar_t* MSWGetDarkThemeName() const override;
// This function can be used as event handle for wxEVT_DPI_CHANGED event.
void WXHandleDPIChanged(wxDPIChangedEvent& event);
@ -216,6 +219,12 @@ bool wxMSWHeaderCtrl::Create(wxWindow *parent,
if ( !MSWCreateControl(WC_HEADER, wxT(""), pos, size) )
return false;
if ( wxMSWDarkMode::IsActive() )
{
m_customDraw = new wxMSWHeaderCtrlCustomDraw();
m_customDraw->UseHeaderThemeColors(GetHwnd());
}
// special hack for margins when using comctl32.dll v6 or later: the
// default margin is too big and results in label truncation when the
// column width is just about right to show it together with the sort
@ -246,6 +255,11 @@ WXDWORD wxMSWHeaderCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
return msStyle;
}
const wchar_t* wxMSWHeaderCtrl::MSWGetDarkThemeName() const
{
return L"ItemsView";
}
wxMSWHeaderCtrl::~wxMSWHeaderCtrl()
{
delete m_imageList;

View file

@ -368,14 +368,7 @@ void wxListCtrl::MSWInitHeader()
if ( !m_headerCustomDraw )
m_headerCustomDraw = new wxMSWHeaderCtrlCustomDraw();
wxUxThemeHandle theme{hwndHdr, L"Header"};
m_headerCustomDraw->m_attr.SetTextColour(
theme.GetColour(HP_HEADERITEM, TMT_TEXTCOLOR)
);
m_headerCustomDraw->m_attr.SetBackgroundColour(
theme.GetColour(HP_HEADERITEM, TMT_FILLCOLOR)
);
m_headerCustomDraw->UseHeaderThemeColors(hwndHdr);
}
void wxListCtrl::MSWAfterReparent()