Click here to Skip to main content
Click here to Skip to main content

Code to allow you to print the content of a CTreeCtrl

, 16 Mar 2003 CPOL
Rate this:
Please Sign up or sign in to vote.
A base class that provides all the functions you need to print a CTreeCtrl

Sample Image - examplePreview.gif

Introduction

Once again, I present a small printing class I recently developed to allow me to print the content of a CTreeCtrl. The code in itself is contained within a small class from which you can inherit your view/dialog that needs to be able to print the content of a CTreeCtrl.

So how do we use it?

To gain all the functionality you will require to print the content of a CTreeCtrl, you need to inherit the class that will be handling the actual printing from the supplied class TreeCtrlPrint.

#include "TreeCtrlPrint.h"

class CExampleView : public CFormView, TreeCtrlPrint
{

Doing this gives you access to the following functions in the class:

HTREEITEM GetNextTreeItem(const CTreeCtrl& treeCtrl, HTREEITEM hItem)

You use this function to iterate through the tree control in the order of all items as they would be drawn if all nodes in the tree control have been expanded. This lets you plot all the items in the correct order.

void DrawTreeItem(const CTreeCtrl& treeCtrl, HTREEITEM hPrintItem, CDC *pDC, CRect rect, CWnd *pWnd)

This function actually does the drawing of the specific tree item, you need to pass in the handle of the tree item to print, the rectangle on the target DC which you want to print the output into. Some assumptions are made about the DC in that it will have the correct font selected into it to render with and the height of the rectangle supplied will be used as the size of an icon/image when plotted.

ExpandAll(CTreeCtrl& treeCtrl)

This function will automatically expand all tree items with children.

Typical printing code

You have to do some work when printing the content of the tree control:

Select the correct font.

If you look in the example application you will see that I make use of the font being used by the tree control for printing, but just scaled correctly for the DPI of the printer:

CFont        font ;
LOGFONT        lf ;

pTreeCtrl->GetFont()->GetLogFont(&lf);
// This aims to get the same size font for the printer as in use by the control <BR>// on the screen printer resolution
lf.lfHeight = -MulDiv(abs(lf.lfHeight), pDC->GetDeviceCaps(LOGPIXELSY), 72);
VERIFY(font.CreateFontIndirect(&lf));
pDC->SelectObject(&font) ;

Get the number of items that can fit on a page

Once you have the correct font selected, you can calculate how many items can fit on a page, and from there calculate the number of pages required to print the tree control content.

CString text("A") ;
CSize cs = dc.GetTextExtent(text) ;
linesPerPage = abs(pInfo->m_rectDraw.Height() / cs.cy) -1;
if ((numTreeItems % linesPerPage) != 0)
{
    // we need to include the partial page
    numberOfPages++;
}
// Add in the whole pages
numberOfPages += (numTreeItems / linesPerPage);

The actual print loop

When printing, your OnPrint() function gets called once per page of output, so we may need to navigate to the correct start position in the tree control before we start to print the tree items.

// navigate to correct start position, if printing the 2nd or later page<BR>
HTREEITEM hPrintItem = pTreeCtrl->GetRootItem();
for (int i = 0 ; i < linesPerPage * currentPage && i < numTreeItems ; i++)
{
    hPrintItem = GetNextTreeItem(*pTreeCtrl, hPrintItem);
}

Once were at the correct start position in the tree, we just keep printing items until either we run out of items or page space:

// continue printing from this point onwards until we run oot of page area<BR><BR>for (i = linesPerPage * currentPage ; <BR>    (i < numTreeItems) && (i < (linesPerPage * (currentPage + 1))) ; i++)<BR>{
    // calculate the rectangle for this tree item
    CRect    rect(pInfo->m_rectDraw.left + (cs.cx * 2), 
                  pInfo->m_rectDraw.top + (cs.cy * line_number), 
                  pInfo->m_rectDraw.left + pInfo->m_rectDraw.Width(), 
                  pInfo->m_rectDraw.top + (cs.cy * (line_number + 1)));
    DrawTreeItem(*pTreeCtrl, hPrintItem, pDC, rect, this);
    line_number++;
    hPrintItem = GetNextTreeItem(*pTreeCtrl, hPrintItem);
}

This code uses one extra variable currentPage which is taken from pInfo->m_nCurPage - 1, as we need a 0 based page numbering scheme to correctly work out the starting print item for following pages.

Well, thats all there is to it really.

Problems encountered

As I said earlier, this is recently developed code for one of my applications. I ported it across for the CP article and setup the example application. It was then that I found out that my code did not work properly for cases where you had more than 1 root item (my app only has 1 root item). My code was indenting the following root items and generally making a mess of things, so in a way, this article improved my application...

History

  • 17th March 2003

    A bug fix for the GetNextTreeItem() function as reported by bhtang - should now work correctly with any type of populated tree. The example application was updated to call UpdatePrinterSelection(TRUE); in InitInstance() so that a default printer will be automatically selected at start-up, as suggested by Michael A. Rusakov

    A new function ExpandAll(CTreeCtrl& treeCtrl) was added to the class to expand all tree items which have children.

  • 5th March 2003 - Initial version.

    Enjoy!

  • License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

    Share

    About the Author

    Roger Allen
    Software Developer (Senior) Sirius Analytical Instruments
    United Kingdom United Kingdom
    A research and development programmer working for a pharmaceutical instrument company for the past 17 years.
     
    I am one of those lucky people who enjoys his work and spends more time than he should either doing work or reseaching new stuff. I can also be found on playing DDO on the Cannith server (Send a tell to "Maetrim" who is my current main)
     
    I am also a keep fit fanatic, doing cross country running and am seriously into [url]http://www.ryushinkan.co.uk/[/url] Karate at this time of my life, training from 4-6 times a week and recently achieved my 1st Dan after 6 years.

    Comments and Discussions

     
    GeneralGetNextTreeItem Pinmemberportej052-Jan-09 4:13 
    GeneralQ&D Transparent Printing Fix (for tree images) PinmemberJames R. Twine20-Nov-07 4:23 
    Generalhelp - "AfxGetApp()->CreatePrinterDC(dc)" Pinmemberasfur4-Jul-07 11:00 
    GeneralRe: help - &quot;AfxGetApp()-&gt;CreatePrinterDC(dc)&quot; [modified] PinmemberDavide Zaccanti24-Jul-07 20:09 
    GeneralRe: help - &quot;AfxGetApp()-&gt;CreatePrinterDC(dc)&quot; Pinmemberasfur18-Aug-07 10:29 
    QuestionMinutes or hours? Pinmember-Dy27-Jul-05 6:54 
    Generalyour project is excelent! Pinmemberhaodate29-Nov-03 19:41 
    GeneralBug ( I think....) Pinmemberatul arora24-Aug-03 5:59 
    GeneralA minor fix when looking for rest of tree node. PinmemberMichael.Liu6-May-06 6:02 
    GeneralIcons won't be printed!! PinmemberAmbat5-Jun-03 0:10 
    GeneralAgain good job Roger PinmemberMike Wild13-Mar-03 22:42 
    GeneralI should add some code into InitInstance of your example PinmemberMichael A. Rusakov12-Mar-03 18:51 
    GeneralRe: I should add some code into InitInstance of your your example PinmemberRoger Allen13-Mar-03 2:04 
    Generalyou should add some codes for GetNextTreeItem Pinsussbhtang12-Mar-03 16:54 
    GeneralRe: you should add some codes for GetNextTreeItem PinmemberRoger Allen13-Mar-03 2:08 
    GeneralRe: you should add some codes for GetNextTreeItem Pinmembertbh13-Mar-03 4:00 
    GeneralRe: you should add some codes for GetNextTreeItem PinsussCharlie Curry20-Mar-03 8:20 
    GeneralError: Cannot find file to open PinmemberWREY11-Mar-03 7:43 
    GeneralRe: Error: Cannot find file to open PinmemberMichael A. Rusakov12-Mar-03 18:41 
    GeneralRe: Error: Cannot find file to open PinmemberWREY12-Mar-03 19:25 
    GeneralRe: Error: Cannot find file to open PinmemberRoger Allen13-Mar-03 2:06 
    GeneralWM_PRINTCLIENT PinmemberAndreas Saurwein5-Mar-03 6:34 
    GeneralRe: WM_PRINTCLIENT PinmemberRoger Allen5-Mar-03 7:21 
    GeneralYou must be Canadian! PinmemberNGS 5496725-Mar-03 5:45 
    GeneralRe: You must be Canadian! PinmemberRoger Allen5-Mar-03 5:50 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

    | Advertise | Privacy | Terms of Use | Mobile
    Web02 | 2.8.141216.1 | Last Updated 17 Mar 2003
    Article Copyright 2003 by Roger Allen
    Everything else Copyright © CodeProject, 1999-2014
    Layout: fixed | fluid