Variable item height in TreeView gives broken lines
Wee.
So I finally figured out how the iIntegral member of TVITEMEX works. The MSDN docs didn't think to mention that setting it while inserting an item has no effect, but setting it after the item is inserted works. Yay!
However, when using the TVS_HASLINES style with items of variable height, the lines are only drawn for t开发者_开发知识库he top part of an item with iIntegral > 1. E.g. if I set TVS_HASLINES and TVS
Here's what it looks like (can't post images WTF?)
Should I manually draw more of the lines in response to NM_CUSTOMDRAW or something?
Yes, Windows doesn't do anything with the blank space obtained from changing the height.
From the MSDN:
The tree-view control does not draw in the extra area, which appears below the item content, but this space can be used by the application for drawing when using custom draw. Applications that are not using custom draw should set this value to 1, as otherwise the behavior is undefined.
Alright, problem solved.
I failed to find an easy answer, but I did work around it the hard way. It's basically just drawing the extra line segments in custom draw:
// _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 );
}
}
The pattern from the PS_ALTERNATE brush sometimes doesn't align perfectly with line drawn by the control, but that's hardly noticeable. What's worse is that even though I have the latest common controls and all the service packs and hotfixes installed, there are still bugs in TreeView documented way back in 2005. Specifically, the TreeView doesn't update its height correctly. The only workaround I've found for that is to force some collapsing/expanding of nodes and do a few calls to InvalidateRect.
If the variable-height nodes are at the root level, though, there doesn't appear to be anything you can do. Luckily I don't need that.
精彩评论