Fix wxChoice/wxComboBox popup border in MSW dark mode (PR #26574)

20 views
Skip to first unread message

Ferréol DUBOIS COLI

unread,
Jun 8, 2026, 3:40:36 PM (5 days ago) Jun 8
to wx-...@googlegroups.com, Subscribed

Summary

  • Keep the Explorer/ScrollBar theme on the combo popup list HWND from #26535/#26538 so selected items stay readable and scrollbars stay dark.
  • Subclass the popup list HWND and draw the missing popup frame border manually, fixing the regression reported in #26573 without broadening SetWindowTheme() to ComboBox/CFD classes (which breaks either selection colours or scrollbar theming).

Test plan

  • Build with MSW dark mode enabled (wx_msw_dark_mode=2) and run the widgets sample.
  • Verify wxChoice popup border matches native file dialog combo appearance.
  • Verify readonly and editable wxComboBox popup borders.
  • Confirm selected popup item text remains readable (#26535 not regressed).
  • Confirm popup scrollbars remain dark (#26538 not regressed).
  • Confirm standalone wxListBox is unchanged.

Fixes #26573.


You can view, comment on, or merge this pull request online at:

  https://github.com/wxWidgets/wxWidgets/pull/26574

Commit Summary

  • 628989d Fix wxChoice/wxComboBox popup border in MSW dark mode

File Changes

(1 file)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574@github.com>

Steve Cornett

unread,
Jun 8, 2026, 5:11:39 PM (5 days ago) Jun 8
to wx-...@googlegroups.com, Subscribed
stevecor left a comment (wxWidgets/wxWidgets#26574)

I find the theme name "DarkMode_DarkTheme" looks pretty decent on Windows 10.0.26300. The border is not blue, but it looks OK.

diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp
index 45f03a483c..6a8941af0a 100644
--- a/src/msw/choice.cpp
+++ b/src/msw/choice.cpp
@@ -225,7 +225,7 @@ void wxChoice::MSWSetDarkOrLightMode(SetMode setmode)
     WinStruct<COMBOBOXINFO> info;
     if ( ::GetComboBoxInfo(GetHwnd(), &info) && info.hwndList )
     {
-        wxMSWDarkMode::AllowForWindow(info.hwndList, L"Explorer", L"ScrollBar");
+        wxMSWDarkMode::AllowForWindow(info.hwndList, L"DarkMode_DarkTheme");
     }
 }


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574/c4653586980@github.com>

Ferréol DUBOIS COLI

unread,
Jun 8, 2026, 5:26:00 PM (5 days ago) Jun 8
to wx-...@googlegroups.com, Subscribed
Fefedu973 left a comment (wxWidgets/wxWidgets#26574)

I agree with you and it works much better like this @vadz what do you think ?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574/c4653689450@github.com>

Steve Cornett

unread,
Jun 8, 2026, 7:27:10 PM (5 days ago) Jun 8
to wx-...@googlegroups.com, Subscribed
stevecor left a comment (wxWidgets/wxWidgets#26574)

The name in wxListBox::MSWGetDarkModeSupport() should probably be changed too. My understanding is the themeId "ScrollBar" means that the control (a list box in this case) should be rendered as if it were a scroll bar. It does not specify a scope to limit changes. It overrides the control's class name for looking up theme/rendering info. The themeId should almost never be specified.

bool wxListBox::MSWGetDarkModeSupport(MSWDarkModeSupport& support) const
{
    support.themeName = L"Explorer";
    support.themeId = L"ScrollBar";


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574/c4654458506@github.com>

Mohmed abdel-fattah

unread,
Jun 10, 2026, 7:00:00 AM (3 days ago) Jun 10
to wx-...@googlegroups.com, Subscribed
memoarfaa left a comment (wxWidgets/wxWidgets#26574)

Hi @Fefedu973 , @stevecor , @vadz

I find the theme name "DarkMode_DarkTheme" looks pretty decent on Windows 10.0.26300. The border is not blue, but it looks OK.

diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp
index 45f03a483c..6a8941af0a 100644
--- a/src/msw/choice.cpp
+++ b/src/msw/choice.cpp
@@ -225,7 +225,7 @@ void wxChoice::MSWSetDarkOrLightMode(SetMode setmode)
     WinStruct<COMBOBOXINFO> info;
     if ( ::GetComboBoxInfo(GetHwnd(), &info) && info.hwndList )
     {
-        wxMSWDarkMode::AllowForWindow(info.hwndList, L"Explorer", L"ScrollBar");
+        wxMSWDarkMode::AllowForWindow(info.hwndList, L"DarkMode_DarkTheme");
     }
 }

my be this look like.

index 45f03a483c..42ca8d49c1 100644
--- a/src/msw/choice.cpp
+++ b/src/msw/choice.cpp
@@ -36,7 +36,7 @@
 
 #include "wx/msw/private.h"
 #include "wx/msw/uxtheme.h"
-
+#include <dwmapi.h>;
 #include "wx/msw/private/darkmode.h"
 
 // ============================================================================
@@ -217,6 +217,37 @@ void wxChoice::MSWGetDarkModeSupport(MSWDarkModeSupport& support) const
     support.themeName = L"CFD";
 }
 
+typedef HRESULT
+(WINAPI* DwmSetWindowAttribute_t)(HWND, DWORD, const void*, DWORD);
+static wxDynamicLibrary ms_dllDWM;
+
+
+static DwmSetWindowAttribute_t ms_pfnDwmSetWindowAttribute = (DwmSetWindowAttribute_t)-1;
+
+static DwmSetWindowAttribute_t GetDwmSetWindowAttribute()
+{
+    if (ms_pfnDwmSetWindowAttribute == (DwmSetWindowAttribute_t)-1)
+    {
+        ms_dllDWM.Load(wxS("dwmapi.dll"), wxDL_VERBATIM | wxDL_QUIET);
+        wxDL_INIT_FUNC(ms_pfn, DwmSetWindowAttribute, ms_dllDWM);
+    }
+
+    return ms_pfnDwmSetWindowAttribute;
+}
+
+bool wxHasRealDarkTheme(const wchar_t* stdClass, const wchar_t* darkClass)
+{
+    const auto darkTheme = wxUxThemeHandle::NewAtStdDPI(darkClass);
+    if (darkTheme)
+    {
+        const auto stdTheme = wxUxThemeHandle::NewAtStdDPI(stdClass);
+        if (stdTheme && stdTheme != darkTheme)
+            return true;
+    }
+
+    return false;
+}
+
 void wxChoice::MSWSetDarkOrLightMode(SetMode setmode)
 {
     wxChoiceBase::MSWSetDarkOrLightMode(setmode);
@@ -225,7 +256,54 @@ void wxChoice::MSWSetDarkOrLightMode(SetMode setmode)
     WinStruct<COMBOBOXINFO> info;
     if ( ::GetComboBoxInfo(GetHwnd(), &info) && info.hwndList )
     {
-        wxMSWDarkMode::AllowForWindow(info.hwndList, L"Explorer", L"ScrollBar");
+        COLORREF borderColor = NULL;
+
+        // try "Darkmode_DarkTheme" windows 11 theme first.
+        if (wxHasRealDarkTheme(L"Scrollbar",
+            L"DarkMode_DarkTheme::Scrollbar"))
+        {
+            wxMSWDarkMode::AllowForWindow(info.hwndList, L"Darkmode_DarkTheme");
+            borderColor = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW));
+        }
+        // try "Darkmode_Explorer" windows 10 theme next.
+        else if (wxHasRealDarkTheme(L"Scrollbar",
+            L"Darkmode_Explorer::Scrollbar"))
+        {
+            wxMSWDarkMode::AllowForWindow(info.hwndList, L"Darkmode_Explorer");
+            borderColor = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
+        }
+
+        else
+        {
+            borderColor = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW));
+
+            // try to set themes that are known to work in the list part of the scrollbar sequentially.
+            wxMSWDarkMode::AllowForWindow(info.hwndList, L"Explorer", L"Darkmode_DarkTheme::Scrollbar;Darkmode_Explorer::Scrollbar;Scrollbar");
+
+        }
+
+        DWM_WINDOW_CORNER_PREFERENCE cornerPreference = DWM_WINDOW_CORNER_PREFERENCE::DWMWCP_ROUNDSMALL;
+        // Apply rounded corners and border color to the dropdown list if round corner type is DWMWCP_DONOTROUND or DWMWCP_DEFAULT we need to handel WM_NCPaint.
+        // If the round corner type is DWMWCP_ROUNDSMALL or DWMWCP_ROUND, we can set the corner preference directly without handling WM_NCPaint.
+        // this round cornor policy work for any ws_popup window, so it will work for the dropdown list of combo box,list box, menu, tooltip, etc.
+        HRESULT hr = GetDwmSetWindowAttribute()
+            (
+                info.hwndList,
+                DWMWA_WINDOW_CORNER_PREFERENCE,
+                &cornerPreference,
+                sizeof(cornerPreference)
+                );
+
+        if (!FAILED(hr))
+        {
+            hr = GetDwmSetWindowAttribute()
+                (
+                    info.hwndList,
+                    DWMWA_BORDER_COLOR,
+                    &borderColor,
+                    sizeof(borderColor)
+                    );
+        }
     }
 }
 

https://github.com/user-attachments/assets/764a9423-e0de-41ba-adb6-70e4ecd8d40f


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574/c4669403965@github.com>

Ferréol DUBOIS COLI

unread,
Jun 10, 2026, 7:13:45 AM (3 days ago) Jun 10
to wx-...@googlegroups.com, Subscribed
Fefedu973 left a comment (wxWidgets/wxWidgets#26574)

I didn't understand your message.
Which version dosen't work ?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574/c4669525729@github.com>

Mohmed abdel-fattah

unread,
Jun 10, 2026, 8:05:34 AM (3 days ago) Jun 10
to wx-...@googlegroups.com, Subscribed
memoarfaa left a comment (wxWidgets/wxWidgets#26574)

I didn't understand your message. Which version dosen't work ?

I think the confusion is that my code snippet wasn’t meant as a full replacement – I was just exploring whether we could also set the popup border color via DwmSetWindowAttribute(DWMWA_BORDER_COLOR) and maybe adjust the corner preference.

The simple change proposed by @stevecor (using L"DarkMode_DarkTheme" instead of "Explorer" + "ScrollBar") already works for the border appearance on Windows 11 insider 26300.8553.

My more complex version was trying to:

Choose Darkmode_DarkTheme or Darkmode_Explorer depending on what the system really supports.

bool wxHasRealDarkTheme(const wchar_t* stdClass, const wchar_t* darkClass)
{
    const auto darkTheme = wxUxThemeHandle::NewAtStdDPI(darkClass);
    if (darkTheme)
    {
        const auto stdTheme = wxUxThemeHandle::NewAtStdDPI(stdClass);
        if (stdTheme && stdTheme != darkTheme)
            return true;
    }

    return false;
}


 if (wxHasRealDarkTheme(L"Scrollbar",
     L"DarkMode_DarkTheme111::Scrollbar"))
 {
     wxMSWDarkMode::AllowForWindow(info.hwndList, L"Darkmode_DarkTheme");
     borderColor = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW));
 }
 // try "Darkmode_Explorer" windows 10 theme next.
 else if (wxHasRealDarkTheme(L"Scrollbar",
     L"Darkmode_Explorer111::Scrollbar"))
 {
     wxMSWDarkMode::AllowForWindow(info.hwndList, L"Darkmode_Explorer");
     borderColor = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
 }

 else
 {
     borderColor = wxColourToRGB(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW));

     // try to set themes that are known to work in the list part of the scrollbar sequentially.
     wxMSWDarkMode::AllowForWindow(info.hwndList, L"Explorer", L"Darkmode_DarkTheme111::Scrollbar;Darkmode_Explorer1111::Scrollbar;Scrollbar");

 }

Also set a border color + small rounding via DWM attributes as the same as Highlight drop down item.

    // Apply rounded corners and border color to the dropdown list if round corner type is DWMWCP_DONOTROUND or DWMWCP_DEFAULT we need to handel WM_NCPaint.
    // If the round corner type is DWMWCP_ROUNDSMALL or DWMWCP_ROUND, we can set the corner preference directly without handling WM_NCPaint.
    // this round cornor policy work for any ws_popup window, so it will work for the dropdown list of combo box,list box, menu, tooltip, etc.
    HRESULT hr = GetDwmSetWindowAttribute()
        (
            info.hwndList,
            DWMWA_WINDOW_CORNER_PREFERENCE,
            &cornerPreference,
            sizeof(cornerPreference)
            );

    if (!FAILED(hr))
    {
        hr = GetDwmSetWindowAttribute()
            (
                info.hwndList,
                DWMWA_BORDER_COLOR,
                &borderColor,
                sizeof(borderColor)
                );
    }
}


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574/c4669973349@github.com>

VZ

unread,
Jun 10, 2026, 12:04:20 PM (3 days ago) Jun 10
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26574)

Thanks, "DarkMode_DarkTheme" seems to work pretty well, so I'll use it. I wonder since how long does this exist because it looks pretty useful but I don't remember running into it back when I was implementing the initial dark mode support.

The function wxListBox::MSWGetDarkModeSupport() should probably be changed too.

Just removing "ScrollBar" from here results in scrollbar becoming white (at least under Windows 10), so I'm not sure how do you propose to change this?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574/c4672047429@github.com>

VZ

unread,
Jun 10, 2026, 12:04:49 PM (3 days ago) Jun 10
to wx-...@googlegroups.com, Subscribed

Closed #26574 via de11441.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26574/issue_event/26583315053@github.com>

Reply all
Reply to author
Forward
0 new messages