Как рисовать итемы и субитемы листвью вручную? Т.е. сделать полный CUSTOM DRAW? Рисование на уровне возврата из callback цвета фона и шрифта не устраивает. Нужно перерисовывать полностью, чтобы выделение (selected item) не распространялось на нулевой субитем. И чтобы можно было произвольно выбрать цвет выделения. Я в этих возвращаемых из callback значениях запутался полностью Може есть пример какой?
В RSDN не смотрел? Там есть 90% ответов на подобные вопросы. Выделение, как и заливку фона, желательно рисовать один раз при отрисовке первого подэлемента, рамку его получать через GetItemRect(LVIR_SELECTBOUNDS). Пример с MFC: Код (Text): afx_msg void CColoredCtrl::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult) { LPNMLVCUSTOMDRAW nmcd = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR); *pResult = CDRF_DODEFAULT; // по умолчанию на любом этапе рисует система const unsigned int CDDS_SUBITEMPREPAINT = CDDS_ITEM|CDDS_SUBITEM|CDDS_PREPAINT; if(nmcd->nmcd.dwDrawStage == CDDS_PREPAINT) // говорим, что будем рисовать элементы *pResult = CDRF_NOTIFYITEMDRAW; else if(nmcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT){ // почему-то по-умолчанию прямоугольник элемента пуст, заполняем его GetItemRect(nmcd->nmcd.dwItemSpec, &nmcd->nmcd.rc, LVIR_BOUNDS); // говорим, что будем рисовать подэлементы тоже *pResult |= CDRF_NOTIFYSUBITEMDRAW; }else if(nmcd->nmcd.dwDrawStage == CDDS_SUBITEMPREPAINT){ int nitem = nmcd->nmcd.dwItemSpec; ColoredItem* item = reinterpret_cast<ColoredItem*>(nmcd->nmcd.lItemlParam); // свои данные CRect rc = nmcd->nmcd.rc; // получаем состояние подэлемента LVITEM lvi = {LVIF_STATE}; lvi.iItem = nitem; lvi.iSubItem = nmcd->iSubItem; lvi.stateMask = LVIS_SELECTED|LVIS_FOCUSED; GetItem(&lvi); // здесь идёт отрисовка в nmcd->nmcd.hdc. // Но заливать фон нужно только, когда идёт отрисовка 1го подэлемента (nmcd->iSubItem == 0) *pResult = CDRF_SKIPDEFAULT; // говорим, что сделали всё сами } }
IceStudent Спасибо, с этим разобрался. Вот ещё одна проблема: как можно определить при перерисовке итема по pNmhdr->code == NM_CUSTOMDRAW какие итемы и с каким state будут отрисовываться следующими? Это нужно чтобы организовать раздельные select'ы: один selected итем среди root'ов, и один среди child'ов. Пока что я отслеживаю LVN_ITEMCHANGING и по этому сообщению запоминаю в глобальных нужную информацию(какой итем активируется и какой деактивируется), но почему-то иногда не снимается выделение старого итема, возможно это связано с опозданием LVN_ITEMCHANGING. И поэтому приходится ещё делать InvalidateRect листа по LVN_ITEMCHANGED, чтобы закрепить изменения. А это приводит к небольшим мерцаниям листа. Уже весь msdn вспахал - ничего не вижу...
Ну, можно просто взять состояние следующего элемента. Я делал примерно так же для упрощения (две переменные, под фокус и выделение) и ускорения работы (не надо опрашивать все элементы, чтобы определить, кто сейчас в фокусе). Не снимается системой? Если ты хранишь состояние отдельно (или хотя бы часть его, относящуюся к выделению), то имеет смысл при отрисовке элемента сбрасывать у всех выделение и выставлять его только у нужных. Но как делать правильно — я не в курсе; вообще, с этим custom draw больше проблем, чем пользы и зачастую приходится выходить из тупика написанием собственного контрола
Да, я тоже пришел к выводу, что надо писать свой контрол, чтобы всё было красиво Может взять treewiev и скрестить его с listview... Такие treelistview существуют, но я видел только для .net.
смотрел. Поиск по сайту выдал только для vb.net/c#. На programmersheaven нашел один без ремарок vb.net/c#, закачал а при установке инсталлятор потребовал framework