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:
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user