开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜