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


Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame

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;

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

    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

    • Very good !

      Posted by Seu_why on 01/16/2006 05:21am


    • linking error?? help

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

      Originally posted by: manson

      Compiling resources...
      C:\Doglist\PrinterJob.cpp(208) : warning C4552: '!=' : operator has no effect; expected operator with side-effect
      Generating Code...
      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
      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 06:40pm

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

    • Print multiline header

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

      Originally posted by: bobo

      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;

      rcPage.top += szFtPrint.cy;

      return CSize(0, szFtPrint.cy);

    • Great Code, just some minor adjustments

      Posted by Legacy on 10/10/2002 07: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

    • How to send to Print Preview

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

      Originally posted by: Kanat


      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.

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

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

      Originally posted by: suduan

      i need it

    • Where is the Print Preview

      Posted by Legacy on 10/17/2000 07: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

      • Print Preview

        Posted by MaxMax14 on 07/21/2012 08: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

    • How to implement two ListControl in one page?

      Posted by Legacy on 04/06/2000 07: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.

    • How to implement Print PreView ??

      Posted by Legacy on 01/19/2000 08: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.

    • ListPrint problems with non-local(network) printers

      Posted by Legacy on 11/23/1999 08:00am

      Originally posted by: Gary Hoffer

      When I have a network printer as my default printer the Print Setup dialog is bypassed. Setting any local printer as the default printer allows the print setup dialog to be brought up and includes the network printers in the selection list. Does anyone have a fix for this behavior?

      I am using Visual C++ v.6.0 SP3 and testing in debug mode.


    • Loading, Please Wait ...

    • You must have javascript enabled in order to post comments.

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

    Most Popular Programming Stories

    More for Developers

    RSS Feeds

    Thanks for your registration, follow us on our social networks to keep up-to-date