Fix wrong appearance of selected unfocused items in wxListCtrl

Items using wxSYS_COLOUR_BTNFACE (light grey in the default theme) for
their background are, for some reason, drawn using the colour of active
selection (blue) even when the control doesn't have focus.

This is wrong, but there just doesn't seem to be any way to prevent this
from happening when using the native drawing logic other than not using
wxSYS_COLOUR_BTNFACE for the background (modifying any colour channel by
1 is enough to work around the issue). So to draw the item ourselves in
this case and hope that it remains indistinguishable from the native
appearance when not using the system theme.

Closes #17988.
This commit is contained in:
Vadim Zeitlin
2019-05-26 22:41:57 +02:00
parent d9684e1ceb
commit 551dfea59a

View File

@@ -2835,8 +2835,9 @@ bool HandleSubItemPrepaint(LPNMLVCUSTOMDRAW pLVCD, HFONT hfont, int colCount)
const int col = pLVCD->iSubItem;
const DWORD item = nmcd.dwItemSpec;
// the font must be valid, otherwise we wouldn't be painting the item at all
SelectInHDC selFont(hdc, hfont);
SelectInHDC selFont;
if ( hfont )
selFont.Init(hdc, hfont);
// get the rectangle to paint
RECT rc;
@@ -3053,6 +3054,22 @@ static WXLPARAM HandleItemPrepaint(wxListCtrl *listctrl,
return CDRF_NEWFONT;
}
// For some unknown reason, native control incorrectly uses the active
// selection colour for the background of the items using COLOR_BTNFACE as
// their custom background even when the control doesn't have focus (see
// #17988). To work around this, draw the item ourselves in this case.
//
// Note that the problem doesn't arise when using system theme, which is
// lucky as HandleItemPaint() doesn't result in the same appearance as with
// the system theme, so we should avoid using it in this case to ensure
// that all items appear consistently.
if ( listctrl->IsSystemThemeDisabled() &&
pLVCD->clrTextBk == ::GetSysColor(COLOR_BTNFACE) )
{
HandleItemPaint(pLVCD, NULL);
return CDRF_SKIPDEFAULT;
}
return CDRF_DODEFAULT;
}