Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Undocumented Visual C++

, 17 Sep 2000
Spelunking in the Badlands of MSDEV
// ---------------
// You may use, compile or redistribute this source as part of your application 
// for free. You may not redistribute it as a part of a software development 
// library without the agreement of the author. If the sources are 
// distributed along with the application, you should leave the original 
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES on your own risk.
// Nick Hodapp

// ClassView.cpp : implementation file

#include "stdafx.h"
#include "ClassView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;

// CClassView




BEGIN_MESSAGE_MAP(CClassView, CScrollView)

void CClassView::Render(CDC* pDC, CString strRoot, CRect& rclRet, DWORD dwRow)
	// My quick & dirty tree layout algorithm.  
	// If this had been an assignment in college, I'm sure I would have failed.
	// The algorithm tends to draw the tree left-side heavy.  But I don't feel like fixing it.

	typedef std::vector<CPoint> V_Point;
	V_Point	vecPts;

	long		lMin(INT_MAX), 

	// render children:
	for (M_String::iterator it = m_pmapClasses->find(strRoot) ; it != m_pmapClasses->end() && it->first == strRoot ; it++)
		// draw child -- rclRet holds position on return:
		CRect rclChild;
		Render(pDC, it->second, rclChild, dwRow+1);

		// track pos of child

		// track width of child span
		lMin = min(rclChild.left,  lMin);
		lMax = max(rclChild.right, lMax);

	// root element?
	if (strRoot == "")

	// determine our own size / position:
	DrawTextEx(pDC->GetSafeHdc(), (char*)(const char*)strRoot, strRoot.GetLength(), &rclRet, DT_CALCRECT  | DT_SINGLELINE, NULL);

	// determine our position:
	long offsetx = (lMin == INT_MAX ? m_alRowInsert[dwRow] : ((lMin+lMax)/2)),
		  offsety = dwRow * (rclRet.Height() * 4);

	// adjust...
	while (offsetx < m_alRowInsert[dwRow])

	// move into position:
	rclRet.OffsetRect(offsetx, offsety);

	// record that we're here:
	m_alRowInsert[dwRow]    = rclRet.right + 8;
	m_alRowInsert[dwRow+1] += 8;

	// draw
	pDC->Draw3dRect(&rclRet, RGB(255,000,000), RGB(255,000,000));
	DrawTextEx(pDC->GetSafeHdc(), (char*)(const char*)strRoot, strRoot.GetLength(), &rclRet, DT_SINGLELINE | DT_NOCLIP, NULL);

	// draw lines from chidren to us:
	CPoint ptParent(rclRet.CenterPoint().x, rclRet.bottom);
	for (V_Point::iterator itPt = vecPts.begin() ; itPt != vecPts.end() ; itPt++)
		CPoint& ptChild = *itPt;


	// ensure scroll bars work
	// lame, but it works:  (slows us down quite a bit...)
	int mm;
	CSize size, sizePage, sizeLine;
	GetDeviceScrollSizes(mm, size, sizePage, sizeLine);
	SetScrollSizes(MM_TEXT, CSize(max(, rclRet.right), max(, rclRet.bottom)));

// CClassView drawing

void CClassView::OnInitialUpdate()

	CSize sizeTotal; = 100; = 100;
	SetScrollSizes(MM_TEXT, sizeTotal);

	ModifyStyle(0, WS_HSCROLL | WS_VSCROLL);

void CClassView::OnDraw(CDC* pDC)

	M_String map;
	map.insert(M_String::value_type(CString(""),	 CString("a")));
	map.insert(M_String::value_type(CString("a"), CString("b")));
	map.insert(M_String::value_type(CString("a"), CString("c")));			
	map.insert(M_String::value_type(CString("a"), CString("d")));			
	map.insert(M_String::value_type(CString("a"), CString("e")));			
	map.insert(M_String::value_type(CString("a"), CString("f")));			
	map.insert(M_String::value_type(CString("b"), CString("g")));			
	map.insert(M_String::value_type(CString("b"), CString("h")));			
	map.insert(M_String::value_type(CString("c"), CString("i")));			
	map.insert(M_String::value_type(CString("c"), CString("j")));			

	map.insert(M_String::value_type(CString("d"), CString("k")));			
	map.insert(M_String::value_type(CString("d"), CString("l")));			
	map.insert(M_String::value_type(CString("d"), CString("m")));			

	map.insert(M_String::value_type(CString("e"), CString("n")));			
	map.insert(M_String::value_type(CString("e"), CString("o")));			
	map.insert(M_String::value_type(CString("e"), CString("p")));			

   m_pmapClasses = &map;
	// reset our row tracking data:
	memset(m_alRowInsert, 0x00, sizeof(m_alRowInsert));

	// render:
	CFont font; font.CreatePointFont(100, "Courier New");
	CGdiObject* pOldFont = pDC->SelectObject(&font);
	Render(pDC, "", CRect(0,0,0,0), 1);

// CClassView diagnostics

#ifdef _DEBUG
void CClassView::AssertValid() const

void CClassView::Dump(CDumpContext& dc) const
#endif //_DEBUG

// CClassView message handlers

void CClassView::PostNcDestroy() 
	// do not delete off the heap...	
	//	CScrollView::PostNcDestroy();

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Nick Hodapp
Web Developer
United States United States
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 18 Sep 2000
Article Copyright 2000 by Nick Hodapp
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid