Click here to Skip to main content
12,406,687 members (60,076 online)
Click here to Skip to main content
Add your own
alternative version

Stats

115.9K views
2.6K downloads
26 bookmarked
Posted

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 
// 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

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

for (i = linesPerPage * currentPage ; 
    (i < numTreeItems) && (i < (linesPerPage * (currentPage + 1))) ; i++)
{
    // 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.

    You may also be interested in...

    Comments and Discussions

     
    GeneralGetNextTreeItem Pin
    portej052-Jan-09 3:13
    memberportej052-Jan-09 3:13 
    GeneralQ&D Transparent Printing Fix (for tree images) Pin
    James R. Twine20-Nov-07 3:23
    memberJames R. Twine20-Nov-07 3:23 
    Generalhelp - "AfxGetApp()->CreatePrinterDC(dc)" Pin
    asfur4-Jul-07 10:00
    memberasfur4-Jul-07 10:00 
    GeneralRe: help - &quot;AfxGetApp()-&gt;CreatePrinterDC(dc)&quot; [modified] Pin
    Davide Zaccanti24-Jul-07 19:09
    memberDavide Zaccanti24-Jul-07 19:09 
    GeneralRe: help - &quot;AfxGetApp()-&gt;CreatePrinterDC(dc)&quot; Pin
    asfur18-Aug-07 9:29
    memberasfur18-Aug-07 9:29 
    QuestionMinutes or hours? Pin
    -Dy27-Jul-05 5:54
    member-Dy27-Jul-05 5:54 
    Generalyour project is excelent! Pin
    haodate29-Nov-03 18:41
    memberhaodate29-Nov-03 18:41 
    GeneralBug ( I think....) Pin
    atul arora24-Aug-03 4:59
    memberatul arora24-Aug-03 4:59 
    GeneralA minor fix when looking for rest of tree node. Pin
    Michael.Liu6-May-06 5:02
    memberMichael.Liu6-May-06 5:02 
    GeneralIcons won't be printed!! Pin
    Ambat4-Jun-03 23:10
    memberAmbat4-Jun-03 23:10 
    GeneralAgain good job Roger Pin
    Mike Wild13-Mar-03 21:42
    memberMike Wild13-Mar-03 21:42 
    GeneralI should add some code into InitInstance of your example Pin
    Michael A. Rusakov12-Mar-03 17:51
    memberMichael A. Rusakov12-Mar-03 17:51 
    GeneralRe: I should add some code into InitInstance of your your example Pin
    Roger Allen13-Mar-03 1:04
    memberRoger Allen13-Mar-03 1:04 
    Generalyou should add some codes for GetNextTreeItem Pin
    bhtang12-Mar-03 15:54
    sussbhtang12-Mar-03 15:54 
    GeneralRe: you should add some codes for GetNextTreeItem Pin
    Roger Allen13-Mar-03 1:08
    memberRoger Allen13-Mar-03 1:08 
    GeneralRe: you should add some codes for GetNextTreeItem Pin
    tbh13-Mar-03 3:00
    membertbh13-Mar-03 3:00 
    GeneralRe: you should add some codes for GetNextTreeItem Pin
    Charlie Curry20-Mar-03 7:20
    sussCharlie Curry20-Mar-03 7:20 
    GeneralError: Cannot find file to open Pin
    WREY11-Mar-03 6:43
    memberWREY11-Mar-03 6:43 
    GeneralRe: Error: Cannot find file to open Pin
    Michael A. Rusakov12-Mar-03 17:41
    memberMichael A. Rusakov12-Mar-03 17:41 
    GeneralRe: Error: Cannot find file to open Pin
    WREY12-Mar-03 18:25
    memberWREY12-Mar-03 18:25 
    GeneralRe: Error: Cannot find file to open Pin
    Roger Allen13-Mar-03 1:06
    memberRoger Allen13-Mar-03 1:06 
    GeneralWM_PRINTCLIENT Pin
    Andreas Saurwein5-Mar-03 5:34
    memberAndreas Saurwein5-Mar-03 5:34 
    GeneralRe: WM_PRINTCLIENT Pin
    Roger Allen5-Mar-03 6:21
    memberRoger Allen5-Mar-03 6:21 
    GeneralYou must be Canadian! Pin
    NGS 5496725-Mar-03 4:45
    memberNGS 5496725-Mar-03 4:45 
    GeneralRe: You must be Canadian! Pin
    Roger Allen5-Mar-03 4:50
    memberRoger Allen5-Mar-03 4:50 
    GeneralRe: You must be Canadian! Pin
    Atlantys7-Mar-03 11:35
    memberAtlantys7-Mar-03 11:35 
    GeneralRe: You must be Canadian! Pin
    Roger Allen10-Mar-03 4:31
    memberRoger Allen10-Mar-03 4:31 
    GeneralRe: You must be Canadian! Pin
    Atlantys10-Mar-03 6:35
    memberAtlantys10-Mar-03 6:35 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    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.160730.1 | Last Updated 17 Mar 2003
    Article Copyright 2003 by Roger Allen
    Everything else Copyright © CodeProject, 1999-2016
    Layout: fixed | fluid