Custom Draw Tree Control

MFC 6 supports Custom Draw Tree Control, which makes setting different colors for individual tree items much simpler (see Zafir Anjum's article "Setting color and font attribute for individual items" to find out how to do it without Custom Draw support). Custom draw tree control sends an NM_CUSTOMDRAW notification to its owner. The trick is that the control sends first NM_CUSTOMDRAW notification with dwDrawStage set to CDDS_PREPAINT, and no further notifications will be sent, unless this notification is processed correctly. Setting pResult to CDRF_NOTIFYITEMDRAW causes the control to send NM_CUSTOMDRAW notifications for individual items with dwDrawStage set to CDDS_ITEMPREPAINT, which allows changing item's attributes before it is drawn.



BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
{
	LPNMHDR pNmhdr = (LPNMHDR)lParam;

	switch (pNmhdr->code)
	{
		case NM_CUSTOMDRAW:
		{
			LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)lParam;
			switch (pCustomDraw->nmcd.dwDrawStage)
			{
				case CDDS_PREPAINT:
					// Need to process this case and set pResult to CDRF_NOTIFYITEMDRAW, 
					// otherwise parent will never receive CDDS_ITEMPREPAINT notification. (GGH) 
					*pResult = CDRF_NOTIFYITEMDRAW;
					return true;

				case CDDS_ITEMPREPAINT:
					switch (pCustomDraw->iLevel)
					{
						// painting all 0-level items blue,
						// and all 1-level items red (GGH)
						case 0:
							if (pCustomDraw->nmcd.uItemState == (CDIS_FOCUS | CDIS_SELECTED)) // selected
								pCustomDraw->clrText = RGB(255, 255, 255);
							else	
								pCustomDraw->clrText = RGB(0, 0, 255);
							break;
						case 1:
							if (pCustomDraw->nmcd.uItemState == (CDIS_FOCUS | CDIS_SELECTED)) // selected
								pCustomDraw->clrText = RGB(255, 255, 255);
							else	
								pCustomDraw->clrText = RGB(255, 0, 0);
							break;
					}
					
					*pResult = CDRF_SKIPDEFAULT;
					return false;

			}
		}
		break;
	}
	
		
	return CFrameWnd::OnNotify(wParam, lParam, pResult);
}


Download demo project - 22 KB

Download source - 1.4 KB



Comments

  • how can i add list view for the same

    Posted by vishal_pansari on 08/20/2004 01:12am

    This is really a very good code. but tell me, how can i add list view for the same to the right side of the window. ??

    • vishal sir plz contact me, paras from indore

      Posted by thematrix4u on 12/17/2008 01:51am

      hello vishal sir,
      i donot know that this mail will reach to u or not,
      but sir kindly contact me this is an emergancy,,,
      i m paras patidar from indore..
      Dr. Rama's family friend..
      i tried ur no. but it is not in service..
      
      contact me at +91-9009784488
      plz sir i need to talk somthing important to u for both of us.
      
      
      regards:
      
      paras patidar

      Reply
    Reply
  • Can i apply the same logic to a scrollbar?

    Posted by Legacy on 01/27/2004 12:00am

    Originally posted by: prashanth prabhu p

    I would like to know wether the windows scrollbar control supports customdraw and wether the same logic could be applied for drawing a custom scrollbar.

    Reply
  • changing item RECT workaround

    Posted by Legacy on 10/28/2002 12:00am

    Originally posted by: David Woods

    I've seen several posts here about changing the item rect when doing a custom draw, and in fact it was searching for that information that led me to this page in the first place.  I've had luck with one ... not a solution, more like a work-around.
    
    

    It's pretty simple to implement -- just increase the TreeCtrl Indent by the size of your icon, then in the custom draw function, offset your item rectangle by the same amount in the other direction:

    // when initializing CTreeCtrl, assuming icon width of 16
    MyTree.SetIndent(MyTree.GetIndent() + 16);

    // inside CustomDraw function
    HTREEITEM hti = (HTREEITEM)nmcd.dwItemSpec;
    CRect itemRect;
    GetItemRect(hti, &itemRect, TRUE);
    // only reverse the indent offset if this is a child item
    if (GetParentItem(hti) != TVI_ROOT && GetParentItem(hti) != NULL)
    ::OffsetRect(&itemRect, -16, 0);


    cheers!
    -david

    Reply
  • how to make a transparent CTreeCtrl

    Posted by Legacy on 10/06/2002 12:00am

    Originally posted by: Nitin Dbey

    i am trying to make transparent tree control, i have tryed to make it by selecting the options given in the properties window of CTreeCtrl. but its not working

    thankz

    Reply
  • treeview customdraw and why horizontal scrolling does not work

    Posted by Legacy on 11/28/2001 12:00am

    Originally posted by: lammerville

    I draw my personnal image and text like this
    but horizontal scrolling does not work, why ?

    void CViewArbre::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
    {
    NMTVCUSTOMDRAW* pTVCD = (NMTVCUSTOMDRAW*)pNMHDR;
    // TODO: Add your control notification handler code here

    *pResult = 0;

    switch (pTVCD->nmcd.dwDrawStage)
    {
    case CDDS_PREPAINT:
    *pResult = CDRF_NOTIFYITEMDRAW ;
    break;
    case CDDS_ITEMPREPAINT:
    {
    CDC* pDC = CDC::FromHandle(pTVCD->nmcd.hdc);
    CRect rc(pTVCD->nmcd.rc);
    CRect rcImg(pTVCD->nmcd.rc);
    POINT p;
    rcImg.OffsetRect(pTVCD->iLevel*16,0) ;
    p=rcImg.TopLeft();
    rc.OffsetRect(rcImg.left+16,0);
    p=rcImg.TopLeft();
    m_il.Draw(pDC,0,p,ILD_NORMAL);
    CString strTexte = GetTreeCtrl().GetItemText((HTREEITEM)pTVCD->nmcd.dwItemSpec);
    pDC->TextOut(rc.left,rc.top,strTexte) ;
    TRACE("%d %d,%d sur %d x %d\n",rand(),rc.left,rc.top,rc.Width(),rc.Height());
    }
    *pResult = CDRF_SKIPDEFAULT ;
    break;
    }

    }

    Reply
  • ExTree

    Posted by Legacy on 10/18/2001 12:00am

    Originally posted by: Mike Philis

    Are you looking for a cool tree control?
    
    

    Check this out: http://www.exontrol.com/sg.jsp?content=products/extree

    Features include:
    ActiveX hosting, events from contained components are fired through to your program using the exact same model used in VB6 for components added at run time, data bounding, multiple columns, and more

    Mike
    www.exontrol.com

    Reply
  • how to get a CDDS_ITEMPOSTPAINT?

    Posted by Legacy on 10/20/2000 12:00am

    Originally posted by: Don Metzler

    How can I ensure that I will get a CDDS_ITEMPOSTPAINT notification?

    Thanks,

    Don

    Reply
  • Solution : I don't get a CDDS_ITEMPREPAINT message

    Posted by Legacy on 01/07/2000 12:00am

    Originally posted by: Nikolai Sander

    In case you don't get a CDDS_ITEMPREPAINT message after returning CDRF_NOTIFYITEMDRAW to the CDDS_PREPAINT, you can try to set SetWindowLong(hDlg,DWL_MSGRESULT,CDRF_NOTIFYITEMDRAW); in case you have a dialog box.

    Nikolai

    Reply
  • How to change item-size ?

    Posted by Legacy on 10/27/1999 12:00am

    Originally posted by: Martin Thoma

    Hi !

    The Custom-Draw-TreeCtrl works fine. But now I want to set the width of each item, so I can draw something instead of text. The main problem is, that the scroll-bar will only notice the width of the text, but I want to set a user-defined width. Is this possible ?

    Regards

    Martin

    Reply
  • Changing the color of a selected item in a MFC CTreeView

    Posted by Legacy on 07/15/1999 12:00am

    Originally posted by: Carl Bomgardner

    I made the following changes to the code so that I could
    
    change the color of the selected item to the Tree Control
    embedded in the MFC's CTreeView.

    The CTreeView routine is notified when the tree item is to
    be painted (via the NM_CUSTOMDRAW notification) through the
    OnChildNotify rather than the OnNotify member function.


    BOOL CLeftView::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    {
    LPNMHDR pNmhdr = (LPNMHDR)lParam;
    int select=0;
    if (message==WM_NOTIFY) {
    if (pNmhdr->code == NM_CUSTOMDRAW) {
    LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)lParam;
    switch (pCustomDraw->nmcd.dwDrawStage)
    {
    case CDDS_PREPAINT:
    // Need to process this case and set pResult to CDRF_NOTIFYITEMDRAW,
    // otherwise parent will never receive CDDS_ITEMPREPAINT notification. (GGH)
    *pResult = CDRF_NOTIFYITEMDRAW;
    return true;

    case CDDS_ITEMPREPAINT:
    CTreeCtrl& refCtrl = GetTreeCtrl();
    if (pCustomDraw->nmcd.dwItemSpec == (ULONG) refCtrl.GetSelectedItem()) select=1;
    if (select) pCustomDraw->clrText = RGB(0,0,255);
    else pCustomDraw->clrText = RGB(0,0,0);
    pCustomDraw->clrTextBk = RGB(255,255,255);
    *pResult = CDRF_NEWFONT;
    return false;

    }
    }
    }

    return CTreeView::OnChildNotify(message, wParam, lParam, pResult);
    }

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

RSS Feeds