Comments (4)
I will submit a PR dealing with checkboxes and item selection rectangle soon.
from wxwidgets.
Since I did not see anything related to drawing checkboxes in the wxListCtrl
code, I tested if it is not a limitation of the native listview. I used https://github.com/ysc3839/win32-darkmode/tree/delayload, where I made a single change:
diff --git a/win32-darkmode/win32-darkmode.cpp b/win32-darkmode/win32-darkmode.cpp
index efe249c..28536b1 100644
--- a/win32-darkmode/win32-darkmode.cpp
+++ b/win32-darkmode/win32-darkmode.cpp
@@ -115,6 +115,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (wmId)
{
case IDM_ABOUT:
+ ListView_SetExtendedListViewStyle(g_hWndListView, ListView_GetExtendedListViewStyle(g_hWndListView) | LVS_EX_CHECKBOXES);
DialogBoxW(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
I.e., use checkboxes for the listview after selecting About from the Help menu.
The checkboxes are displayed properly:
Since the listctrl sample is rather complex and uses custom drawing, I tested also with the minimal sample:
diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index 5f32257c6b..923eb27f4a 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
@@ -26,6 +26,8 @@
#include "wx/wx.h"
#endif
+#include <wx/listctrl.h>
+
// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------
@@ -175,6 +177,16 @@ MyFrame::MyFrame(const wxString& title)
CreateStatusBar(2);
SetStatusText("Welcome to wxWidgets!");
#endif // wxUSE_STATUSBAR
+ wxListCtrl* listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
+
+ listCtrl->AppendColumn("Item");
+ listCtrl->AppendColumn("SubItem");
+ for ( long i = 0; i < 10; ++i )
+ {
+ listCtrl->InsertItem(i, wxString::Format("Item %ld", i));
+ listCtrl->SetItem(i, 1, wxString::Format("SubItem %ld", i));
+ }
+ listCtrl->EnableCheckBoxes();
}
But still no checkboxes. So it seems the issue is on wxWidgets side here.
BTW, the issue label "windows-11" should be probably changed to "dark mode".
from wxwidgets.
Because I added the checkboxes to wxListCtrl
this caught my attention and had a look at it.
I can indeed reproduce it on Windows 10. It seems in dark mode, everything is drawn manually. So the checkboxes also need to be drawn. I tried some guestimated sizes and this seems to work all right:
diff --git "a/src/msw/listctrl.cpp" "b/src/msw/listctrl.cpp"
index 9aad796b90..9754c9fd61 100644
--- "a/src/msw/listctrl.cpp"
+++ "b/src/msw/listctrl.cpp"
@@ -36,8 +36,10 @@
#endif
#include "wx/imaglist.h"
+#include "wx/renderer.h"
#include "wx/vector.h"
+#include "wx/msw/dc.h"
#include "wx/msw/private.h"
#include "wx/msw/uxtheme.h"
#include "wx/msw/private/customdraw.h"
@@ -3047,7 +3049,7 @@ RECT GetCustomDrawnItemRect(const NMCUSTOMDRAW& nmcd)
return rc;
}
-bool HandleSubItemPrepaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont, int colCount)
+bool HandleSubItemPrepaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont, int colCount)
{
NMCUSTOMDRAW& nmcd = pLVCD->nmcd;
@@ -3072,6 +3074,23 @@ bool HandleSubItemPrepaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont, int colCount)
rc.right = rc2.left;
}
+ if ( listctrl->HasCheckBoxes() )
+ {
+ wxDCTemp dc((WXHDC)hdc);
+
+ int cbSize = listctrl->FromDIP(13);
+ int cbX = listctrl->FromDIP(2);
+ int cbY = rc.top + ((rc.bottom - rc.top) / 2 - cbSize / 2);
+
+ int flags = 0;
+ if ( listctrl->IsItemChecked(item) )
+ flags |= wxCONTROL_CHECKED;
+
+ wxRendererNative::Get().DrawCheckBox(listctrl, dc, wxRect(cbX, cbY, cbSize, cbSize), flags);
+
+ rc.left += listctrl->FromDIP(16);
+ }
+
// This mysterious offset is necessary for the owner drawn items to align
// with the non-owner-drawn ones. Note that it's intentionally *not* scaled
// by DPI factor because it doesn't seem to depend on the resolution.
@@ -3167,7 +3186,7 @@ void HandleItemPostpaint(NMCUSTOMDRAW nmcd)
// for consistency.
//
// pLVCD->clrText and clrTextBk should contain the colours to use
-void HandleItemPaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
+void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
{
NMCUSTOMDRAW& nmcd = pLVCD->nmcd; // just a shortcut
@@ -3240,7 +3259,7 @@ void HandleItemPaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
for ( int col = 0; col < colCount; col++ )
{
pLVCD->iSubItem = col;
- HandleSubItemPrepaint(pLVCD, hfont, colCount);
+ HandleSubItemPrepaint(listctrl, pLVCD, hfont, colCount);
}
::SetTextColor(hdc, colTextOld);
@@ -3264,7 +3283,7 @@ WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
? wxColourToRGB(attr->GetBackgroundColour())
: wxColourToRGB(listctrl->GetBackgroundColour());
- HandleItemPaint(pLVCD, nullptr);
+ HandleItemPaint(listctrl, pLVCD, nullptr);
return CDRF_SKIPDEFAULT;
}
@@ -3294,7 +3313,7 @@ WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
// with recent comctl32.dll versions (5 and 6, it uses to work with
// 4.something) so we have to draw the item entirely ourselves in
// this case
- HandleItemPaint(pLVCD, GetHfontOf(font));
+ HandleItemPaint(listctrl, pLVCD, GetHfontOf(font));
return CDRF_SKIPDEFAULT;
}
@@ -3315,7 +3334,7 @@ WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
if ( listctrl->IsSystemThemeDisabled() &&
pLVCD->clrTextBk == ::GetSysColor(COLOR_BTNFACE) )
{
- HandleItemPaint(pLVCD, nullptr);
+ HandleItemPaint(listctrl, pLVCD, nullptr);
return CDRF_SKIPDEFAULT;
}
from wxwidgets.
It seems in dark mode, everything is drawn manually. So the checkboxes also need to be drawn.
Thanks I did not know that and thanks for the code as well. I tried an alternate approach, at 225% DPI my checkboxes are a bit smaller than yours but mine look a bit better (not jagged).
diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp
index 2b5ed314a4..cec64a26ee 100644
--- a/src/msw/listctrl.cpp
+++ b/src/msw/listctrl.cpp
@@ -3047,7 +3047,7 @@ RECT GetCustomDrawnItemRect(const NMCUSTOMDRAW& nmcd)
return rc;
}
-bool HandleSubItemPrepaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont, int colCount)
+bool HandleSubItemPrepaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont, int colCount)
{
NMCUSTOMDRAW& nmcd = pLVCD->nmcd;
@@ -3072,6 +3072,25 @@ bool HandleSubItemPrepaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont, int colCount)
rc.right = rc2.left;
}
+ if ( listctrl->HasCheckBoxes() )
+ {
+ const HIMAGELIST himl = ListView_GetImageList(hwndList, LVSIL_STATE);
+
+ if ( himl && ImageList_GetImageCount(himl) >= 2 )
+ {
+ int x, y, width, height;
+
+ ImageList_GetIconSize(himl, &width, &height);
+ x = listctrl->FromDIP(2);
+ y = rc.top + ((rc.bottom - rc.top) / 2 - height/ 2);
+ // when using any style flag (ILD_TRANSPARENT, ILD_SELECTED, ILD_FOCUS), the checkboxes
+ // for selected items are drawn with a blue background, which we want to avoid
+ ImageList_Draw(himl, listctrl->IsItemChecked(item) ? 1 : 0, hdc, x, y, 0);
+
+ rc.left += x + width + listctrl->FromDIP(1);
+ }
+ }
+
// This mysterious offset is necessary for the owner drawn items to align
// with the non-owner-drawn ones. Note that it's intentionally *not* scaled
// by DPI factor because it doesn't seem to depend on the resolution.
@@ -3167,7 +3186,7 @@ void HandleItemPostpaint(NMCUSTOMDRAW nmcd)
// for consistency.
//
// pLVCD->clrText and clrTextBk should contain the colours to use
-void HandleItemPaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
+void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
{
NMCUSTOMDRAW& nmcd = pLVCD->nmcd; // just a shortcut
@@ -3240,7 +3259,7 @@ void HandleItemPaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
for ( int col = 0; col < colCount; col++ )
{
pLVCD->iSubItem = col;
- HandleSubItemPrepaint(pLVCD, hfont, colCount);
+ HandleSubItemPrepaint(listctrl, pLVCD, hfont, colCount);
}
::SetTextColor(hdc, colTextOld);
@@ -3264,7 +3283,7 @@ WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
? wxColourToRGB(attr->GetBackgroundColour())
: wxColourToRGB(listctrl->GetBackgroundColour());
- HandleItemPaint(pLVCD, nullptr);
+ HandleItemPaint(listctrl, pLVCD, nullptr);
return CDRF_SKIPDEFAULT;
}
@@ -3294,7 +3313,7 @@ WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
// with recent comctl32.dll versions (5 and 6, it uses to work with
// 4.something) so we have to draw the item entirely ourselves in
// this case
- HandleItemPaint(pLVCD, GetHfontOf(font));
+ HandleItemPaint(listctrl, pLVCD, GetHfontOf(font));
return CDRF_SKIPDEFAULT;
}
@@ -3315,7 +3334,7 @@ WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
if ( listctrl->IsSystemThemeDisabled() &&
pLVCD->clrTextBk == ::GetSysColor(COLOR_BTNFACE) )
{
- HandleItemPaint(pLVCD, nullptr);
+ HandleItemPaint(listctrl, pLVCD, nullptr);
return CDRF_SKIPDEFAULT;
}
Regardless of the approach, there is still a problem with the item selection rect. The checkbox is not covered by it, when the control has images in the first column, the selection rect does not even cover the whole image, it's offset to the right.
But there are quite a few visual glitches in wxListCtrl
in MSW dark mode, Besides #23772 and #23846; I found few more today when comparing the appearance in light and dark modes when in report view. But I guess that is for another Issue.
from wxwidgets.
Related Issues (20)
- most samples build failed in universal build: mnemonics.cpp and notifmsg had not been compiled HOT 4
- Creating a non-modal window from wxHtmlHelpController HOT 3
- [macOS] widgets sample crashes immediately HOT 2
- [macOS?] Sizers are not setting the size of windows correctly HOT 2
- [macOS] Alignment of a slider's current value looks strange HOT 1
- [macOS] Ugly drawing of slider's ticks HOT 4
- Calendar reports invalid date format when using ca_ES locale HOT 4
- [macOS] Wrong calculation of slider's vertical label positions (in case of a horizontal slider)
- [macOS] Slider value and value label do not match
- [regex] wxRegex::Compile will always popup a message box if the pattern was not valid HOT 1
- Documentation typo - wxListColumnFormat HOT 8
- wxGridBagSizer item clipping when vgap/hgap are different and some items span multiple rows/cols HOT 3
- regression: 3.2.5 kicad/gtk plot window is not shown correct. HOT 16
- `wxDialog` ignores the specified position with GTK3 HOT 4
- Memory leak in wxSearchCtrl with autocomplete HOT 8
- [macOS] wxRichTextCtrl doesn't position and show candidate of IME correctly on macOS HOT 2
- wxBitmapComboBox flickers on Windows. HOT 2
- wxGrid should disable ime input on read-only cells HOT 8
- Unpredictable crash when assigning a toolbar to a frame on macOS 14 (Sonoma) HOT 8
- wxBitmapComboBox bitmaps are rendered at x4 size at x2 window scaling on wxGTK HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wxwidgets.