Custom Draw Tree Control | CodeGuru

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 […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 28, 1999
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

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

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.