Creating a Printing Class


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

Printing line-by-line without a Document/View framework


Environment: tested on VC6 SP4 and VC7


Do you still remember the times of the LINE printer (a dot-matrix printer)? Printing was still simple in these times. You simply sent print lines to the printer and lines in exactly this order were printed out. Searching for a way to use this technique, I created the class "CPrivatePrint". This class gives you the possibility to do exactly this and more.

This class works much like a old line printer. There is a "print-cursor" that moves downward with each printed line. It is as though you are printing on an endless strip of paper. The class ensures that the text is divided correctly on single sheets.

For example: You have to print a couple of lines of text in a desired font. With the CPrivatePrint class, you send lineprints. That's all. If you need to arrange the text on two or more pages, the class does it for you. You only have to set the desired margins. Therefore, the main function of the class is "print()", which sends the text line.

Although with this class line for line is printed, it is also possible to position the print cursor at any time and let it continue the printing at this position (use the SetHPos() function to do this).

You don't have to think about font handling. To use different fonts, you add the desired fonts with AddFontToEnvironment(). With SetActiveFont(), you switch between the fonts during the printing.

Some Features

  • Printer selection is optional. (You can use the Windows printer selection dialog to select a printer or set a printer manually.)
  • Supports header and footer lines.
  • Supports bitmap printing.
  • Supports up to 10 different fonts in one document.
  • Supports font escapement.
  • Used fonts can be printed in bold and/or big versions.
  • For printer selection, you can use your own created dialog.

Using the Class

Here is the typical way to use the class:

  1. Include PrivatePrint.cpp and PrivatePrint.h into your project.
  2. Declare an object of CPrivatePrint.
  3. Call the member function Dialog() to let the user choose a printer and to initialize the object.
  4. Call the member function StartPrint(). This function MUST be called immediately after Dialog(), before other class functions are called. It creates the print document in the printer spooler. At the end of all printing, EndPrint() must be called to release it.
  5. Add the fonts that are needed with the member function AddFontToEnvironment(). Principally, it is enough to generate one font. The function returns a handle of the type HPRIVATEFONT, which then is needed for various other member functions. For each necessary font, the function must be called once. There are only 10 different fonts possible.
  6. Adjust the margins and the line spacing (dots between the print lines) with the member functions SetMargins() and SetDistance().
  7. If a header and/or a footer line is needed, the member function ActivateHF() must be called. See a description about this further down in this text.
  8. Call member function StartPage() to begin a new page. If the page ends, call EndPage(). Between these two functions, you place the line printings. Should it be necessary to print more lines than fit on one page (between the call of these two functions), the class ensures that EndPage() is called followed by a StartPage() automatically. A possibly necessary header and/or footer line is created automatically (if wanted). Normally, you use this function only once, at the start and the end. But if it is neccessary for your printing, you can create a new page every time by using EndPage() and StartPage().
  9. Lines are printed with the function Print(). With lf(), blank lines are produced. Further functions are:
    Function Description
    SetFace() Adjusts the appearance of a font
    SetActiveFont() Changes the font
    SetEscapment() Changes the writing direction
    Line() Creates a line
    InsertBitmap() Inserts a bitmap
    ... and so forth  
    All functions are explained in the remarks in the cpp file.
  10. Call the member function EndPrint() to release the document in the spooler.

Some Words About Header/Footer Lines

If you need a header or a footer, or both, you have to create a callback function, such as this:

void HeaderFooter(CPrivatePrint*prt,int page,bool hf)

With CPrivatePrint::ActivateHF(), you say the class that has to call this callback function each time a header or footer line is neccessary. In the hf parameter, you get "true" if the header has to be written, and "false" if the footer has. The *prt pointer gives you a pointer to your CPrivatePrint-Object, which is calling the callback function.

If you are using a footer line, think that the bottom margin includes the height of the footer line. For example, if your footer needs 100 points of height, then your bottom margin should equal or be greater than 100.

Here is an example. It uses the class to print a selected text file. In the header of the printing, the name of the file is printed. In the footer, there is a page counter. Also, there is a bitmap logo in the footer. The example also shows the use of a header/footer line function:

void PrintText()
  CPrivatePrint  prt;
  FILE           *f1;
  CFileDialog    dlg(TRUE,_T("txt"),NULL,OFN_HIDEREADONLY |
                     OFN_OVERWRITEPROMPT,"Text Files (*.txt)|
  char           cBuffer[1024];

  // get the file
  if (dlg.DoModal() != IDOK) return;

  g_strFileName = dlg.GetFileName();

  // open the file
  if ((f1 = fopen (g_strFileName,"r")) == NULL) {
    AfxMessageBox (_T("can't open the file"));

  // initializing the class and printer selection

  // create the print document in the spooler

  // Adding the arial font to the class
  hFont = prt.AddFontToEnvironment("Arial");

  // set margins and line spacing

  // activate a header and footer line

  // now start a page

  // start printing the lines
  while (fgets(cBuffer,1024,f1)) {

  // now end the page

  // close the print document and release it in the spooler

  fclose (f1);

void HeaderFooter(CPrivatePrint*prt,int page,bool hf)

  if (hf)    // header line is wanted
    CSize  dim;
    CRect  margins;
    CString strBuffer;
    strBuffer.Format ("Seite %d",page);


Download demo project - 68 Kb
Download source - 10 Kb


  • Centering bug fix

    Posted by mschifter on 01/31/2007 06:04pm

    This is a timesaving class, but text was not centering for me on the page. I traced this down to line 367 in PrivatePrint.cpp. Change:
        lx += m_DimDraw.cx/2 - Size.cx/2;
        lx = m_DimDraw.cx/2 - Size.cx/2;
    and this should fix the problem.

  • Solution to one line per page problem....

    Posted by aschon on 05/09/2006 11:28pm

    Let me start by saying this class worked wonderfully and has performed 
    well so far in the app I am using it for. It has likely saved me hours over 
    using other alternatives. On with the problem/fix....
    m_Abstand is not being initialized.
    Reason for one line per page:
    When the calculation for end of page occurs, such as in Print() right before 
    the text is written, the page would break or not break after every line based 
    on the value left in m_Abstand at initialization. After initialization of the 
    PrivatePrint object every line written with that object either would or would 
    not be written on its own page based on the (random) initialization value. 
    Call SetDistance() to provide the number of points between lines after object creation.
    Update code base to provide a reasonable default in the constructor, such as:
    m_Abstand = 5;

  • How to control Font Size using this class

    Posted by wuwei on 01/06/2005 08:37am

    Hi, I want to print a text file using this class, but I want to print using different Font Size different rows. How to Realize it? Thanks.

  • How to get the printer status

    Posted by Namal on 10/21/2004 03:24pm

    Hi Guys,
    I wish to know how to get the printer status from an MFC application.
    I have tryed with querying the jobs for the printer and then get the status as follows
    	if (!EnumJobs(hPrinter,
    	   pJobStorage = NULL;
    	   pPrinterInfo = NULL;
    	   return FALSE;
    But even when the printer is offline the status returned is always READY. 
    If you have some idea of this please help me.
    Thank you.

  • PrivatePrint is working in my developements

    Posted by rgimilio on 03/09/2004 09:13pm

    I have incorporated PrivatePrint class in my MFC dialog based applications. It works. I have derived some private utilities for : - printing the content of a multiline edit control, - printing the content of a ListBox control Thanks for all.

  • HELP! works differently in debug than in release !!!

    Posted by Legacy on 06/26/2003 07:00am

    Originally posted by: sfraden

    Odd problem, I have used this class all over my program, with great success, however in this one module, it prints each line on a seperate piece of paper, all well before endpage is ever called.  Now if I put it in debug mode and trace it out, it will work perfectly every time, I am really stumped!  Here is a snippet of the code...

    CPrivatePrint prn;
    HPRIVATEFONT hfont,bfont;

    prn.Dialog(); //chjoose printer to print to
    hfont=prn.AddFontToEnvironment("MS Sans Serif");
    bfont=prn.AddFontToEnvironment("Comic Sans MS Bold",12,20);
    m_bar.SetStep(1); //sets the bar for 100 steps

    int month=sp.m_month;
    int tripcount=1,plines=0;
    CString casinoname=sp.m_casinoname; //bring over the vars
    CString buff,idbuff,dbuff,pbuff,sbuff;
    CStdioFile fp;

    prn.StartPage();//begin job spooler for printing


    for(int c=0;c<indexarray.GetSize();c++) {
    buff=indexarray.GetAt(c); //load buff with player
    idbuff=buff.Mid(buff.ReverseFind(',')+1,buff.GetLength());//idbuff now = folder number
    buff.Format("%s%s\\trip%d.rec",recordpath,idbuff,tripcount);// got player pid in idbuff, open that players file up


  • Please help me for online printing

    Posted by Legacy on 04/21/2003 07:00am

    Originally posted by: azeem shaik


    1.online printing: when ever user enter one Item information it should print imediately, the user complete the sales invoice then i have to call EndPage() function,so that i can cut the paper.

    i want to print line by line,i have done this through ms-dos.

    i want to do through MFC.
    i want to print without calling EndPage() function.because EndPage() function is cutting paper(printer had autocutter). it is ending my task


  • Useing this code in Visual Basic 6.0

    Posted by Legacy on 04/05/2003 08:00am

    Originally posted by: Ritesh


    Could u tell me how could i use this code in vb6 and print a full length text file using this

  • How to add watermark option ot this

    Posted by Legacy on 03/21/2003 08:00am

    Originally posted by: satya

    Hi i would liekt add the water mark option to the print dialog and also the optional caption for Watermarking hwo do i do that

  • printing list ctrl which variable column width with dialogbox

    Posted by Legacy on 01/29/2003 08:00am

    Originally posted by: praveen

    hello sir
    i need to print listctrl which has variable number of columns and width of each column is variable.please help me

  • 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