views:

231

answers:

3

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 the 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?

A: 

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.

dauphic
A: 

OK, can't comment on posts apparently. What is up with this site? :/

Anyway, yes, I've pretty much read all that MSDN has to say about TreeView. But I'm still none the wiser as to what I'm supposed to do in my custom draw handler to extend the lines. Is there some RECT I need to expand when reacting to CDDS_ITEMPREPAINT?

ReturningTarzan
Perhaps you should read http://stackoverflow.com/faq so you'll learn how the site works, before you start complaining about it.
Ken White
I already did. And although it doesn't tell you how to post a comment (the "add comment" button is simply not shown for new users as it turns out), eventually it did explain why I can't comment. But perhaps you should ask me if I read the FAQ before complaining that I didn't. Mind you, the complaint was mostly prompted by the frustration of having to go look for a FAQ to find out that I wasn't allowed to comment.
ReturningTarzan
A: 

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.

ReturningTarzan