Win32 API: Раскраска ListView
Для своей утилиты, чтобы пользователь мог различать казахстанские и российские торрент-трекеры было решено сделать разноцветные строки.
Первоначально появилась мысль применять сабклассинг для ListView. Сделав пару попыток стало понятно, что это очень длинный путь для совершенно простой задачи.
На помощь пришел гугл и форум wasm.ru - за что особое спасибо воинам дзена.
Оказалось, что кроме свойства LVS_OWNERDRAWFIXED, есть чудесная штука - NM_CUSTOMDRAW, которая даже не требует дополнительного свойства, а просто обрабатывается в сообщении WM_NOTIFY. Причем “custom draw” поддерживает смену цвета фона сроки, цвета текста и шрифта и делает это очень просто. У меня получилось вот так:
...
case WM_NOTIFY:
NM_LISTVIEW *nmlv;
nmlv = (NM_LISTVIEW *)lParam;
if ( nmlv -> hdr.code == NM_CUSTOMDRAW )
{
NMLVCUSTOMDRAW *nmlvcd;
nmlvcd = (NMLVCUSTOMDRAW *)lParam;
if ( nmlvcd -> nmcd.dwDrawStage == CDDS_PREPAINT)
{
return CDRF_NOTIFYITEMDRAW;
}
else if ( nmlvcd -> nmcd.dwDrawStage == CDDS_ITEMPREPAINT )
{
if ( nmlvcd -> nmcd.dwItemSpec & 1 )
{
nmlvcd -> clrTextBk = 0x606060;
nmlvcd -> clrText = 0xF0F0F0;
SelectObject ( nmlvcd -> nmcd.hdc, GetStockObject (DEFAULT_GUI_FONT) );
return CDRF_NEWFONT;
}
else
{
nmlvcd -> clrTextBk = 0x909090;
return CDRF_NEWFONT;
}
}
break;
...
- NMLVCUSTOMDRAW clrTextBk задает цвет фона;
- NMLVCUSTOMDRAW clrText задает цвет текста;
- шрифт выбирается с помощью SelectObject для переданного через ту же структуру hDC;
- nmcd.dwItemSpec сообщает о номере текущей строки, в моем примере изменение цвета текста и шрифта производятся с каждой нечетной строкой, а изменения фона для каждой строки, но цвета будут разные (если почитать MSDN, то можно найти и значение SubItem).
Если вам нужно изменить, например, только цвет фона, то просто не трогайте другие параметры: шрифт и цвет текста.
Главное, что у NM_CUSTOMDRAW есть много дополнительных флагов, которые необходимо узнавать через nmcd.dwDrawStage - в данном случае для CDDS_PREPAINT достаточно вернуть значение CDRF_NOTIFYITEMDRAW, чтобы сообщить, что вы будете обрабатывать каждый элемент отдельно, а вот CDDS_ITEMPREPAINT нужно обрабатывать, т.к. это и есть нужный момент, чтобы вклиниться и “подсказать” системе, что от нее нужно.
Вот таким нехитрым способом можно вдарить пользователю по глазам, а иногда улучшить юзабилити, т.к. раскраска списков (ListBox и ListView) частенько повышает удобство для пользователя. Однако не стоит перебарщивать и менять цвет фон и текста слишком сильно, особенно если вы делаете раскраску через строку, все хорошо в меру.
Оставить комментарий
обучение стенографии в Москве | старательная регистрация фирм в короткие сроки |