Do not specify a dark theme in wxRendererXP::GetExpanderSize() because
it may give incorrect result in high DPI: as we only need the size here,
using light theme (which always works) is good enough.
Fixes#26829.
Closes#26837.
Using "DarkMode_DarkTheme" with wxTextCtrl results in a nicely looking
border with real native appearance, so use it when supported and only
fall back to our implementation otherwise.
Closes#26824.
To detect whether DarkMode_DarkTheme is available, use a dedicated
function rather than wxCheckOsVersion, for improved readability.
No changes in behaviour.
Closes#26817.
Fix wxGauge indeterminate mode when using DarkMode_DarkTheme which appeared light mode. Fix switching from dark to light mode which caused the bar color to change to blue, rather than green.
Adjust colors used in wxTextCtrl::MSWDrawThemeBorder() to match how the
Edit control is rendered with the DarkMode_DarkTheme theme rather than
how the WinUI 3 TextBox appears. This should improve the appearance on
dialog backgrounds.
Closes#26800.
Closes#26805.
Do not check dark mode in wxTextCtrl::CanApplyThemeBorder(). Instead,
improve the checking for themed border drawing in the WM_NCPAINT
handler.
This fixed the border appearance after switching from dark mode to the
light one.
Closes#26794.
Use system colors for generic calendar header instead of blue and gray.
A separator line is drawn below the header. This makes the control look
consistent with the Win32 and WinUI 3 controls. Custom header colors are
not overwritten by system color change event.
See #25552.
Closes#26777.
Assign values for wxSYS_COLOUR_3DLIGHT and wxSYS_COLOUR_BTNHIGHLIGHT
consistent with Linux and macOS.
Also stop using wxSYS_COLOUR_BTNHIGHLIGHT for rendering disabled text in
wxGrid and wxGenericStaticText: it didn't look before and would be even
worse after this change. Instead, just draw the text in "disabled"
colour, without using drop shadow at all.
Closes#26753.
For wxTextCtrl, draw a themed border consistent with how the control
looks in light mode, and consistent with the WinUI 3 TextBox control in
dark mode. A blue line appears at the bottom when the control has the
focus.
Closes#26745.
Fix wxChoice drop-down list scroll bar when switching to light mode by
using "DarkMode_DarkTheme" only for dark mode. Use "Explorer" for light
mode.
Closes#26736.
With these changes, wxApp::SetAppearance() and
wxApp::MSWEnableDarkMode() can change the dark/light mode at any time.
They can be called before or after windows are created, and can be
called more than once.
The widgets sample has new menu commands to demonstrate this.
Closes#26734.
This change essentially reverts ffeeb612cd (Remove not needed code for
dark mode support under Windows 1809, 2026-06-26). The value of
DWMWA_USE_IMMERSIVE_DARK_MODE changed in Windows 10 v2004, but we
support dark mode on v1903 and later and we still need to use the old
attribute value in this version and v1909.
Closes#26732.
Fix wxGrid for system color change for colors that were assigned
defaults in Init(), and therefore did not update. These colors are
now determined as needed during drawing.
The grid sample "Colours" menu gets additional commands so you can set
all these colors.
Closes#26729.
Remove an unnecessary SetBackgroundColour() to allow system color
change events to take effect. The default background color is already
correct.
Closes#26721.
Update the button text colour of this button, used by wxFontPickerCtrl
under Windows, upon system colour change event (which also covers
switching between light and dark appearances), unless the user selected
a colour.
Closes#26667.
Update the background colour of the generic wxSearchCtrl upon
wxSysColourChangedEvent to notably fix its appearance after switching
between light and dark modes in wxMSW.
Closes#26704.
Defer dark mode system colour change event until after switch is
finished, when the new theme is already active.
Also call RefreshImmersiveColorPolicyState() to fix the initial dark
mode state which was always light before (but it was hidden by
processing WM_SETTINGCHANGE twice).
Closes#26692.
Closes#26698.
In dark mode, make the wxNotebook regions affected by
SetbackgroundColour() match light mode. The default background colour is
wxSYS_COLOUR_WINDOW rather than wxSYS_COLOUR_BTNFACE, which looks too
light.
Closes#25678.
Closes#26695.
On Windows in dark mode, draw a border around the wxNotebook body using
the same colour as the border for the tabs. This makes the dark mode
appearance more consistent with light mode.
See #25678.
Closes#26694.
Subclass the spin control from AddPage() as well as OnSize(), so that
the spin control is drawn properly in dark mode when it appears as a
result of adding a new page.
Closes#26685.
Simply use Win32 FindWindowEx() instead of enumerating child windows
with a loop.
Also extract this code into a reusable function.
No real changes yet.
See #26685.
Remove the USE_NOTEBOOK_ANTIFLICKER configuration option macro. It seems
this was only needed for Windows CE and it couldn't be set to 0 any more
as this started resulting in build errors since 16727d1714 (Start
implementing our own wxNotebook drawing in dark mode, 2022-12-21).
Closes#26684.
Add call to MSWSetDarkOrLightMode() upon control creation to get correct
dark mode drawing under Windows 11 22H2 and later and avoid inverting
colours if they are already drawn correctly for dark mode.
Closes#26683.
The paint event handler clears the DC to the background colour before
drawing the bitmap to properly handle alpha transparency.
Use wxBufferedPaintDC to avoid flicker.
Closes#26682.
Update the text and background colours in wxGrid upon wxSysColourChangedEvent. Moved the colour setting code from Create() into a new function UpdateColours(), and call that from Create() and upon colour change event. To avoid overwriting custom colours, added flag members to track whether custom colours have been set.
Deleted the code that was disabled by #if _USE_VISATTR. That code has been inactive since 2004.
On Windows in dark mode, explicitly draw borders rather than relying on
DrawThemeBackground(), which does not work well on older versions of
Windows.
Closes#26646.
Fix dark mode border flicker by using a clipping region when calling
MSWDefWindowProc(). This prevents drawing the light mode border before
the dark border is drawn.
See #26646.
Remove the background colour setting from wxVListBox::Create() so that
the control uses the up-to-date background colour in the paint event
handler. This way the control responds to system colour changes.
The comment about transparent drawing is wrong since 0975a8a (Applied
patch [ 1405821 ] wxVListBox double-buffering + fix to a scrolling issue
By Jaakko Salli, 2006-01-17).
Closes#26636.
Move colour settings from Create() into a new function UpdateColours(),
which gets called from Create() and also upon system colour change.
Closes#26633.
Add dark mode support to wxFontPreviewer:
- Replace manually drawn black-on-white border with window border
wxBORDER_SIMPLE.
- Set text colour to wxSYS_COLOUR_WINDOWTEXT.
Closes#26632.
For dark mode switching, update the background colour for non-rich
read-only multiline wxTextCtrl controls. The foreground colour is
already updated.
The background colour is controlled by assigning m_backgroundColour
rather than calling SetBackgroundColour(). This leaves the m_hasBgCol
member untouched so that it distinguishes custom colours set by the user
which should not be overwritten, from colours set internally which can
be overwritten.
Some checks of hasBgCol are changed to m_backgroundColour.IsOK(). When
m_backgroundColour.IsOK() is true, there is either a custom colour or an
internally set colour that we need to use.
Closes#26629.
When switching to light mode, always use the theme name L"Explorer"
rather than using MSWGetDarkModeSupport().
The theme name and id needed for dark mode does not always work for
light mode. For example, for wxStatusBar combination name=nullptr
id=L"ExplorerStatusBar" results in an un-themed status bar with strange
internal borders and missing gripper.
Closes#26608.
After the changes of f8363719d4 (Preserve wxNotebook custom colours upon
dark mode switch, 2026-06-15), we need to erase background using the
proper brush.
Closes#26605.
Closes#26606.
This function became unreferenced in 2158f4d798 (moved all wxDialog
event handlers to wxDialogBase to avoid code duplication (sixplication?)
among ports[...], 2006-08-19).
Closes#26594.
Avoid overwriting custom colours upon switching into or out of dark
mode.
The text colour is now the same thing as the foreground colour, as with
wxGenericListCtrl.
Closes#26584.
This was broken by 5bd892f7ac (Fix dark mode selection in list controls
in latest Windows 11, 2026-05-31) which styled the entire list as scroll
bar which was wrong.
Use "DarkMode_DarkTheme" instead of "Explorer" to make the list appear
correctly both under Windows 10 and 11.
Closes#26573.
Closes#26574.
For Windows dark mode, draw themed borders instead of translating
wxBORDER_THEME to wxBORDER_SIMPLE. Borders have the same thickness
between light mode and dark mode for consistent alignment and
positioning. See #26529.
In dark mode, the border styles wxBORDER_STATIC, wxBORDER_RAISED and
wxBORDER_SUNKEN are sometimes drawn by the system using light mode
colours. So draw these borders similarly to themed borders, but using
the proper width. There is no attempt to mimic a raised or sunken look.
The WM_NCCALCSIZE and WM_NCPAINT message handling is simplified and
corrected for calculating the border width.
Closes#26571.
This function is more convenient to use in MSW-specific code than
GetWindowBorderSize() as it returns the size of a single border and so
doesn't require the caller to divide the return value by 2.
No real changes.
See #26571.
Replace MSWGetDarkModeSupport() with MSWSetDarkOrLightMode() which can
now be called to initialize dark mode for a window or to switch it from
one mode to the other and call this function when the mode changes.
Closes#26516.
The problem is when the system switches between dark and light mode,
Refresh() is never called. More specifically, when WM_SETTINGCHANGE
occurs with "ImmersiveColorSet", HandleSettingChange() is not called.
But that is where the only Refresh() call is.
Top level windows should get Refresh() upon WM_SYSCOLORCHANGE as well as
WM_SETTINGCHANGE. Adding another Refresh() call into
HandleSysColorChange() solves the problem.
Closes#26514.
It has not been possible to build with this option disabled for 4 years.
It appears there has been little effort to support this option since
then. For 8 years, there has been a duplicate definition of
wxUxThemeIsActive(), causing a linker warning.
Closes#26509.
All currently used compilers/SDKs define them, so there is no need to do
it ourselves any more.
See #26509.
Co-authored-by: Vadim Zeitlin <vadim@wxwidgets.org>
There was an incompatible change in one of the functions we use in
v1903, so even while we could support older versions, we currently don't
and it's simpler to just increase the minimum supported version rather
than fix this.
See #26494.
Prior to this change, the handling for WM_SETTINGCHANGE with the
"ImmersiveColorSet" argument introduced an additional system color
change event in addition to handling the message normally. This doubled
the number of events per window. Since WM_SETTINGCHANGE is applied
recursively to child windows, this resulted in an exponential increase
in the number of events generated, doubling with each level of child
windows. The solution is to handle WM_SETTINGCHANGE with
"ImmersiveColorSet" as a system color change only - as if it were
WM_SYSCOLORCHANGE.
Closes#26454.
This change fixes wxFrame so that it properly responds to switching
between high contrast themes as well as dark mode.
Do it by not setting the frame background colour by default and
implementing GetDefaultAttributes() properly instead, as this ensures
that the correct colour is used by default, in both light and dark
modes, while explicitly set colour still overrides it.
See #25755.
Closes#26427.
This change updates the colors in the top level window title bar, menu
bar, etc, with dark/light theme change.
wxMSWDarkMode::EnableForTLW() is renamed to ConfigureTLW() as this
function can now either enable or disable the use of dark theme.
Closes#26425.
Most notably, change the text colour to be white instead of #e0e0e0.
Also tweak some colours that are slightly different under Windows 11.
Closes#26412.
Co-authored-by: Vadim Zeitlin <vadim@wxwidgets.org>
Disabling it doesn't save much on code size and the build without it is
currently broken anyhow, so just remove the possibility to turn it off.
Closes#26388.
Closes#26402.