How do you change the color of individual items in a Tree Control?
Posted on 1997-03-26
This seems to be the question of the hour on both comp.os.ms-windows.mfc and Microsoft's microsoft.public.vc.mfc newsgroups. How do you change the color of individual items in a Tree Control?
I've been trying for about a week to set the colors of Text items in a CTreeCtrl object. From a previous post, I found the ActiveX SDK documentation for NM_CUSTOMDRAW. Also, MSJ Oct '96 goes over this stuff.
I'm not in love with this method -- I'd be thankful for anything that works. Specifically, I'm trying to monitor several machines with a CTreeCtrl and provide a graphical system status by color-coding the items in the tree. I've heard rumors that other people have managed to change colors with =WM_CTRCOLOR and WM_ERASEBKGRND. I haven't had any success with that approach, either.
With the NM_CUSTOMDRAW approach, I believe the problem I'm having is that I'm not getting the CDDS_ITEMPREPAINT message. I pasted the code illustrated in the ActiveX docs into my CView::OnNotify() and NM_CUSTOMDRAW with CCDS_PREPAINT are being received just fine. After that, however, only 'default' is being hit in my switch().
Here's my OnNotify() in case someone spots something stupid I've done:
BOOL CFooView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
LPNMTREEVIEW pnm = (LPNMTREEVIEW)lParam;
fonti.CreateFont(-200, 0, 0, 0, FW_NORMAL, TRUE, FALSE, FALSE,ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, "Times New Roman");
LPNMTVCUSTOMDRAW lptvcd = (LPNMTVCUSTOMDRAW)lParam;
CDDS_PREPAINT is at the beginning of the paint cycle. You
implement custom draw by returning the proper value. In this
case, we're requesting item-specific notifications.
if (lptvcd->nmcd.dwDrawStage == CDDS_PREPAINT)
PTREEITEMINFO ptreeitem = (PTREEITEMINFO)lParam;
TRACE("Item = %Xh\n", ptreeitem->pItem);
// Request pre-paint notifications for each item.
CDDS_ITEMPREPAINT is sent when the control is about to paint an
item. We're getting this because we returned CDRF_NOTIFYITEMDRAW
in response to CDDS_PREPAINT before.
if (lptvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
/* To change the font, select the desired font into the
provided HDC. We're changing the font for every third item
in the control, starting with item zero.
if (!(lptvcd->nmcd.dwItemSpec % 3))
/* To change the text and background colors in a list view
control, set the clrText and clrTextBk members of the
NMLVCUSTOMDRAW structure to the desired color.
This differs from most other controls that support
CustomDraw. To change the text and background colors for
the others, call SetTextColor and SetBkColor on the provided HDC.
lptvcd->clrText = RGB(150, 75, 150);
lptvcd->clrTextBk = RGB(255,255,255);
// SetTextColor(lptvcd->nmcd.hdc, lptvcd->clrText);
// SetBkColor(lptvcd->nmcd.hdc, lptvcd->clrTextBk);
/* We changed the font, so we're returning CDRF_NEWFONT. This
tells the control to recalculate the extent of the text.
// return 0;
return CView::OnNotify(wParam, lParam, pResult);