Generic printing class (and how to print a list control content)

A Generic Printer class - and how to print a list control content (or how to print from anywhere without too many troubles).

The CPrinterJob class is a base class for implementing print process aside from the view architecture; it comes along with a CPrintStatus (a CDialog derived) which shows the printing progress process. You will need to derive a class from this and override the virtual functions as you need; the function are exactly the same as the CView ones (OnPreparePrinting, OnBeginPrinting, OnPrint and so on ..) and you can threat them in the same way; then you can call the OnFilePrint function that will start the printing process. If you want to call a "Page Setup" dialog for customizing the printing you can do this in the OnPreparePrinting function and eventually return false to break the process.

As an example, I've written a class to print the content of a CListCtrl (CListCtrlPrint) with a CListPrintSetup class to manage header, footer, fonts types and sizes and margins.

The CListPrintSetup uses three things that can be used for other purposes:

  1. A CCoolButton class, which is an ownerdraw button with a cool look (main code borrowed from another codeguru .. :)
  2. A CFontCombo class, which is a combobox for choosing a font; borrowed from Girish Bharadwaj code with only a small modify to avoid symbols font
  3. Some macros (you will find them in the CListPrintSetup header file) to manage tab pages. I use here this way for tab sheet: I write the main dialog which contains the tab control and the button which are common (ex. Ok, Cancel), and then the tab pages as child dialogs without borders and title; then with the macros you can easily connect them to the tab control.

The CPrinterJob class

This class is designed to be a base class for your evil pourpose; it works exactly as a CView (except for printing preview, sorry!). It has some virtual functions you can override as you would normally do inside a CView class:
virtual bool OnPreparePrinting(CPrintInfo* pInfo, bool bPrintPreview = false);
- the only difference from the CView's one is the bPrintPreview members - I use it for my pourpose, if you aren't using it from inside a CView you can safely ignore it. You should call the base class function from this one (ex. return CPrinterJob::OnPreparePrinting(pInfo, bPrintPreview));
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
- those three functions work exactly as the CView ones and do nothing in the base class is up to your derived one to do something (almost in the OnPrint - or you will print white pages ..)

Supposing you have properly derived your class and do something in the OnPrint()
(ex. CMyPJob::OnPrint(CDC* pDC, CPrintInfo* pInfo) { pDC->TextOut(100,100,"Hello World!"); })
all you need to do the printing process is this:

CMyPJob pJob;
pJob.OnFilePrint();

To include this class in your project you will need to do this:

  • add the CPrinterJob class
  • add the CPrintStatus class (is a dialog, add it with its resoruce)
  • add the avi files you will use in the CPrintStatus class (in this sample, it is borrowed from Windows - it's called IDR_PRINT and it's an "AVI" resource To see a working implementation of the above, look below to the CListCtrlPrint class.

    The CListCtrlPrint class

    This is a class derived from the CPrinterJob. It permits to print the content of a CListCtrl; it also implements a option dialog for setting the header and footer and the fonts type and size.

    The use of this class is very simple, as you can see in the sample application: in the OnOK() function of the sample dialog, we find:

    	CListCtrlPrint cJob;
    	cJob.csPageHead = "This is the header of the file\r\nMultiline!\r\n";
    	cJob.csPageFooter = "Just a test for the footers\r\neventually multiline too ..";
    	cJob.csPage = "Page %d of %d";
    	cJob.pList = &wndList;
    	cJob.OnFilePrint();
    

    If it meets your needs, all you need is to include the following things in your project:

    • the classes for CPrinterJob as stated above;
    • classes CCoolButton and CFontCombo for controls (CCoolbutton needs the cursor resource IDC_HANDCUR)
    • classes CListPrintPage1, CListPrintPage2 and CListPrintSetup for the option dialog (you'll need the dialogs resources and the bitmap resource IDB_PAGE)
    • and finally, the CListCtrlPrint which implements the CPrinterJob derived class and actually do all the work.

    You can peer through the CListCtrlPrint code to see how to implement a CPrinterJob derived.

    Download source 94K.



  • Comments

    • Reasons why everyone is absolute wrong around shoes and consequently the reasons you will have to look at this article.

      Posted by BobHotgloff on 05/23/2013 02:54pm

      Techniques of shoes that you'll cash in on starting up today. [url=http://www.shoesjp.biz/new-balance【ニューバランス】-c-670.html]newbalance[/url] Reasons almost anything you may have find out about sneakers is completely wrong and what you must understand. [url=http://www.shoesjp.biz/nike【ナイキ】-c-634.html]ナイキ スニーカー[/url] Brief guide tells you most of the inner workings of the sneakers as well as what you ought to do today. [url=http://www.kutujp.biz/]ベルーナ[/url] Upcoming shoes Publication Presents Very Best Way To Dominate The shoes Arena [url=http://www.kutujp.biz/アディダス-adidas-c-4.html]adidas originals[/url] Explanation why almost everything you've discovered about shoes is drastically wrong and exactly what you need realize. [url=http://www.kutujp.biz/アシックス-asics-c-3.html]アシックス[/url] The ultimate fix for the sneakers that one can understand about right away. [url=http://www.kutujp.biz/ナイキ-nike-c-13.html]nike[/url] Hot piece of content discloses the low down about shoes in addition to the reason why you need to take action today. [url=http://www.kutujapan.org/]ベルーナ[/url] Upcoming sneakers Book Discloses The Way To Rule The shoes World [url=http://www.kutujapan.org/adidas-アディダス-c-74.html]アディダス シューズ[/url] Creative shoes Guide Clearly shows Simple Tips To Rule The sneakers Marketplace [url=http://www.kutujapan.org/new-balance-ニューバランス-c-13.html]newbalance[/url] What the researchers don't seem to be saying on the subject of shoes and the way this impacts on you actually. [url=http://www.kutujapan.org/nike-ナイキ-c-78.html]ナイキ スニーカー[/url] The actual reason why all people are dead wrong on the subject of shoes and also the reasons why you ought to read this statement.

      Reply
    • Very good !

      Posted by Seu_why on 01/15/2006 09:21pm

      thanks

      Reply
    • linking error?? help

      Posted by Legacy on 08/07/2003 12:00am

      Originally posted by: manson

      Compiling resources...
      Compiling...
      StdAfx.cpp
      Compiling...
      Test.cpp
      TestDlg.cpp
      PrintStatus.cpp
      PrinterJob.cpp
      C:\Doglist\PrinterJob.cpp(208) : warning C4552: '!=' : operator has no effect; expected operator with side-effect
      PrintManagerDlg.cpp
      ListPrintPage1.cpp
      ListCtrlPrint.cpp
      ListPrintSetup.cpp
      ListPrintPage2.cpp
      PrintManager.cpp
      Generating Code...
      Linking...
      Microsoft (R) Incremental Linker Version 6.00.8168
      Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
      /subsystem:windows /incremental:yes "/pdb:Debug/Test.pdb" /debug /machine:I386 "/out:Debug/Test.exe" /pdbtype:sept
      .\Debug\StdAfx.obj
      .\Debug\Test.obj
      .\Debug\TestDlg.obj
      .\Debug\Test.res
      .\Debug\PrintStatus.obj
      .\Debug\PrinterJob.obj
      .\Debug\PrintManagerDlg.obj
      .\Debug\ListPrintPage1.obj
      .\Debug\ListCtrlPrint.obj
      .\Debug\ListPrintSetup.obj
      .\Debug\ListPrintPage2.obj
      .\Debug\PrintManager.obj
      ListPrintPage1.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall CFontCombo::~CFontCombo(void)" (??1CFontCombo@@UAE@XZ)
      ListCtrlPrint.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall CFontCombo::~CFontCombo(void)" (??1CFontCombo@@UAE@XZ)
      ListPrintSetup.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall CFontCombo::~CFontCombo(void)" (??1CFontCombo@@UAE@XZ)
      ListPrintPage1.obj : error LNK2001: unresolved external symbol "public: __thiscall CFontCombo::CFontCombo(void)" (??0CFontCombo@@QAE@XZ)
      ListPrintPage1.obj : error LNK2001: unresolved external symbol "public: void __thiscall CFontCombo::InitFonts(void)" (?InitFonts@CFontCombo@@QAEXXZ)
      ListCtrlPrint.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall CCoolButton::~CCoolButton(void)" (??1CCoolButton@@UAE@XZ)
      ListPrintSetup.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall CCoolButton::~CCoolButton(void)" (??1CCoolButton@@UAE@XZ)
      ListPrintSetup.obj : error LNK2001: unresolved external symbol "public: __thiscall CCoolButton::CCoolButton(void)" (??0CCoolButton@@QAE@XZ)
      Debug/Test.exe : fatal error LNK1120: 5 unresolved externals
      Error executing link.exe.

      • Resolving linker errors

        Posted by Harald Dietewich on 06/02/2004 11:40am

        You must add the following line to your ResourceIncludes: #include "afxprint.rc" Greetz, DX05

        Reply
      Reply
    • Print multiline header

      Posted by Legacy on 12/05/2002 12:00am

      Originally posted by: bobo

      CSize 
      
      CListCtrlPrint::PrintListHead(CDC * pDC, CRect & rcPage, bool bCalc)
      {
      if (!bCalc)
      {
      CFont * oft = pDC->SelectObject(&ftPrint);
      int box = 0;
      CRect rc1;
      int y = rcPage.top;
      int nMaxHeight = szFtPrint.cy;
      //draw header text first
      for (int t = 0; t < iNumCol; t++)
      {
      rc1.SetRect(rcPage.left + pDx[t], y, rcPage.left + pDx[t+1], y + szFtPrint.cy);
      CString cs = pColTitle[t] ? pColTitle[t] : "";

      UINT ftm = DT_CENTER;
      //if (pFormat[t]&HDF_CENTER) ftm = DT_CENTER;
      //else if (pFormat[t]&HDF_RIGHT) ftm = DT_RIGHT;
      CRect tmpRect = rc1;

      pDC->DrawText(cs, tmpRect, ftm | DT_VCENTER | DT_WORDBREAK | DT_CALCRECT);
      nMaxHeight = max(nMaxHeight, tmpRect.Height());
      rc1.bottom = tmpRect.bottom;
      pDC->DrawText(cs, rc1, ftm | DT_VCENTER | DT_WORDBREAK);
      }
      //draw header column lines
      for (int jj = 0; jj < iNumCol; jj++)
      {
      pDC->MoveTo(rcPage.left + pDx[jj], rcPage.top);
      pDC->LineTo(rcPage.left + pDx[jj], rcPage.top + nMaxHeight);
      }
      //draw header rectangle around
      CRect rcc(rcPage.left, rcPage.top, rcPage.right, rcPage.top + nMaxHeight);
      pDC->MoveTo(rcc.left, rcc.top);
      pDC->LineTo(rcc.right, rcc.top);
      pDC->LineTo(rcc.right, rcc.bottom);
      pDC->LineTo(rcc.left, rcc.bottom);
      pDC->LineTo(rcc.left, rcc.top);

      rcPage.top += nMaxHeight;
      pDC->SelectObject(oft);

      }else
      rcPage.top += szFtPrint.cy;

      return CSize(0, szFtPrint.cy);
      }

      Reply
    • Great Code, just some minor adjustments

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

      Originally posted by: Ken

      Current code will print all the items of list box and add several empty lines to complete the page. I added 2 lines of code to CListCtrlPrint::OnPrint

      if (iLast > pList->GetItemCount ())
      iLast = pList->GetItemCount ();

      So there are no empty lines

      Reply
    • How to send to Print Preview

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

      Originally posted by: Kanat

      Sir/madam

      Could you help me:
      I wrote an application which calls database (Access,SQL Server) wich shows at time only information about one person
      How to send to Printer/Print Preview the data shown at the given time. The Document is SDI.
      thank you furthermore.

      Reply
    • where is the preview edition?who can email me ?

      Posted by Legacy on 04/13/2002 12:00am

      Originally posted by: suduan

      i need it

      Reply
    • Where is the Print Preview

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

      Originally posted by: Prad

      Koay Kah Hoe has written that print preview was added and he has also given the site for getting the example.But while i am trying to access that site it says that page is not found.From where can i get the Print preview.Please help me .


      Thanks in advance
      Prad


      • Print Preview

        Posted by MaxMax14 on 07/21/2012 01:40pm

        Print Previewing without the Document/View Framework By Koay Kah Hoe | 26 Nov 1999 : http://web3.codeproject.com/Articles/65/Print-Previewing-without-the-Document-View-Framewo?msg=4316649#xx4316649xx

        Reply
      Reply
    • How to implement two ListControl in one page?

      Posted by Legacy on 04/06/2000 12:00am

      Originally posted by: Jasmin

      I'm sorry to poor at english.
      I want to print two ListControl in one page.
      I have no idea.
      Help..

      Reply
    • How to implement Print PreView ??

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

      Originally posted by: KyungSu Park

      That's a nice class !!
      I have used this class, but could not find how to implement print preview.
      Is there any source code or demo project that explains the way to provide print preview using this class ??
      I need your help...

      Thanks in advance.

      Reply
    • Loading, Please Wait ...

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

    Top White Papers and Webcasts

    • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

    • Live Event Date: December 18, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this upcoming webcast …

    Most Popular Programming Stories

    More for Developers

    RSS Feeds