Ви.
Итак, я наконец понял, как работает iIntegral, член TVITEMEX. В документах MSDN не упоминается, что его установка при вставке элемента не имеет никакого эффекта, но установка после вставки элемента работает. Ура!
Однако при использовании стиля TVS_HASLINES с элементами переменной высоты линии рисуются только для верхней части элемента с iIntegral > 1. Например. если я установлю TVS_HASLINES и TVS
Вот как это выглядит (не могу публиковать изображения, WTF?)
Должен ли я вручную рисовать больше линий в ответ на NM_CUSTOMDRAW или что-то в этом роде?
2 ответа
Да, Windows ничего не делает с пустым пространством, полученным при изменении высоты.
Из MSDN:
Элемент управления древовидным представлением не рисует в дополнительной области, которая появляется под содержимым элемента, но это пространство может использоваться приложением для рисования при использовании пользовательского рисования. Приложения, которые не используют пользовательскую отрисовку, должны установить это значение равным 1, так как в противном случае поведение не определено.
Хорошо, проблема решена.
Мне не удалось найти простой ответ, но я обошёл его трудным путём. В основном это просто рисование дополнительных сегментов линии в пользовательском рисовании:
// _cd is the NMTVCUSTOMDRAW structure
// ITEMHEIGHT is the fixed height set in TreeView_SetItemHeight
// linePen is HPEN of a suitable pen to draw the lines (PS_ALTERNATE etc.)
// indent is the indentation size returned from TreeView_GetIndent
case CDDS_ITEMPREPAINT : {
// Expand line because TreeView is buggy
RECT r = _cd->nmcd.rc;
HDC hdc = _cd->nmcd.hdc;
HTREEITEM hItem = (HTREEITEM) _cd->nmcd.dwItemSpec;
if( r.bottom - r.top > ITEMHEIGHT ) {
HGDIOBJ oldPen = SelectObject( hdc, linePen );
// Draw any lines left of current item
HTREEITEM hItemScan = hItem;
for( int i = _cd->iLevel; i >= 0; --i ) {
// Line should be drawn only if node has a next sibling to connect to
if( TreeView_GetNextSibling( getHWnd(), hItemScan ) ) {
// Lines seem to start 17 pixels from left edge of control. But no idea
// where that constant comes from or if it is really constant.
int x = 17 + indent * i;
MoveToEx( hdc, x, r.top + ITEMHEIGHT, 0 );
LineTo( hdc, x, r.bottom );
}
// Do the same for the parent
hItemScan = TreeView_GetParent( getHWnd(), hItemScan );
}
SelectObject( hdc, oldPen );
}
}
Узор кисти PS_ALTERNATE иногда не совсем совпадает с линией, нарисованной элементом управления, но это едва заметно. Что еще хуже, несмотря на то, что у меня установлены последние общие элементы управления и все пакеты обновления и исправления, в TreeView все еще есть ошибки, задокументированные еще в 2005 году. В частности, TreeView неправильно обновляет свою высоту. Единственный обходной путь, который я нашел для этого, — принудительное свертывание/расширение узлов и выполнение нескольких вызовов InvalidateRect.
Однако, если узлы переменной высоты находятся на корневом уровне, вы ничего не можете сделать. К счастью, мне это не нужно.
Похожие вопросы
Новые вопросы
winapi
Windows API (ранее назывался Win32 API) - это основной набор интерфейсов прикладного программирования, доступных для операционных систем Microsoft Windows. Этот тег предназначен для вопросов о разработке собственных приложений Windows с использованием Windows API.