Printing Class Library

.

This update fixes most bugs reported by users and adds the following enhancements to the library

  • Tables can now have more than 1 visible print line. I.E. Multiline tables both static and virtual
  • There is a rotated text function to print text oriented thru 360 degrees of rotation
  • There is a static function to set page orientation on a page by page basis
  • There is a function to retrieve the device driver name currently in use
  • There is a function to place a user defined function into the printing logic to provide the ability to write form type programs where the actual data is not available until runtime. ( see Demo)
  • The reference is now available in both html and rtf ( see referenece.rtf or reference.html )

What's in the works

  • A parser and the ability to save and retrieve forms from disk.
  • The ability to use and print data from various controls in a formatted style. List, tree, and rich text controls are being evaluated and some other people have sent me some code but I have not had time to incorporate them yet.
  • Database connectivity to make report writing easier. If I do it it will be thru a virtual function that can be overridden to handle different databases. I use Codebase++ almost exclusively due to speed, reliability, and size issues. If anyone has any thoughts along this line let me know.

Before jumping into the description of the classes I would like to say a few things here and not repeat them later over and over. These classes use either MM_TEXT or MM_ANISOTROPIC mapping modes. If you know about mapping modes great, if not, don't worry. I'm not going to use the terms again. If interested see the constructor for CPage for the dirty details. All routines used to output text need at least two parameters to form a point of location. All location references in these classes use 0,0 to represent the upper left-hand corner of the output. As the first number grows larger the output goes down the page. As the second grows larger the text goes to the right. If you pass a double as a location reference the classes ASSUME you are using inches as a unit of measurement. This is the easiest and safest route to go because then you really can forget all about the mapping modes. If you wish to use the low-level route and specify the location to the nearest pixel use the MM_TEXT mode and have fun. However, be aware that some printer drivers will lie to you and the output will look considerably different than anticipated. If this is the case and you still need to have exact placement use MM_ANISOTROPIC mode ( the default mode ) and change the 1000 by 1000 logical units in the constructor to suit your needs.

This class library is designed to provide printing and print preview capabilities to applications developed using the Microsoft) Foundation Class Library. In our business we have need to emulate many pre-printed business and insurance forms. In some cases the client wishes us to print the entire document and in others just fill in the fields with information gathered or generated by the application. There was no commercial solution that we could find to do this so we started from scratch. It was an interesting journey.

There is probably no portion of MFC programming that is as mis-understood and poorly documented as printing. Most books and training films give it very short thrift and then it's on to the flashy GUI stuff we all love. Lot of programs resort to using a commercial report writing tool to handle simple printing chores and others simply direct screen drawing to the printer DC in a crude kind of screen print. We found this unacceptable.

The classes are divided into two logical sections. The file Cprinter.cpp holds the low-level printer primitives. Suprisingly there are only three of them


virtual int PrintText(PRTTYPE *ps,double LineSpacing);

virtual void DrawLine(PRTTYPE *ps,int LineSize);

virtual void DrawRect(PRTTYPE *ps,int LineSize);

These are all that we needed to provide a large amount of printing options. If you wish to add more low-level capabilities this is the place to put them.

The higher level constructs are in the file Cpage.cpp. The classes here are

  • CPage represents a page of printed output. MFC printing architecture provides for printing on a page by page method. CPage holds and manipulates data concerning that page. There are member functions to output text, draw boxes and lines, create and use moveable print regions, and create and use tables of data. Fonts and text attributes can be changed freely and newspaper type columns are supported. Much of this functionality is provided by helper classes that are created by CPage as needed and used. These classes are
  • CTable represents a table of data. A table is much like a grid. It has rows and columns. It can have vertical and/or horizontal separations, a border, and a title. Each column in the table is composed of a class that holds a description of the column. This is the header for that column and the width of the column. Please see the documentation and the sample code for the use of tables. In essence the use is really simple. You create a variable of type CTABLEHEADER either on the stack or the heap and set its member variables to describe the table you wish to use. You the pass a pointer to the filled in structure to CPage via the CPageTable(CTABLEHEADER*) function. The table is constructed and displayed at this time. Data may be added to the table using overloaded functions in CPage that are the same as used to print to the page. Look at the documentation and the sample source code for details
  • CPrintRegion represents a sub region of the printed page that is to be treated as a single object. This region may contain textual data, columnar output, check boxes, and graphics but is to be treated as a single unit. The region can have a border and a title id desired. Move the region and all its contents move with it. This allows story boarding of the page. Since most forms have areas that are logical units these can be considered as a print region. Then when the client asks if you can move this here and that there it is a simple task of placing the new co-ordinates in and recompiling. Everything moves with the region. CPageCreateRegion() will return a pointer to a newly created CPrintRegion class. Since CPage actually creates this pointer it keeps an internal list of pointers and deletes the when the CPage~CPage() destructor runs. DO NOT DELETE A CPrintRegion * passed to you from CPage as a page fault may occur when the destructor runs.

All of these classes (CPage CTable CPrintRegion ) are defined in Cpage.h and implemented in CPage.cpp. In order to implement the class functionality in your application include these files in your project and include the line #include "cpage.h" in any file using the classes. There is a RTF file titled REFERENCE.rtf included in the source code that contains more detailed information on the class members and their use.There is also a html file by the same name. Also a demo project is included. It contains sample code exercising most of the class members. This is a bare bones version of the library with most of the esoteric stuff taken out and the code simplified and cleaned up to make it as clear as possible. Everybody has to have their own little special thing and as time goes by the class starts getting bigger and bigger and interdependencies crop up. I think I have removed most of the interdependent code and all the obvious bugs that crop up during a re-write.

One thing that we learned from this is that it is possible to be to object oriented. At one time we had a CParagraph and a CSentence and a CTitle etc. It really just got to be more trouble than it was worth. We think we have hit a happy medium here. This code is being used as the basis for ad hoc report writers, data base output, forms generation, and several other tasks and has proven to be pretty stable. It has not been tested on Win3.1 but the original code was and was developed there so barring any MFC 32 bit stuff it should compile and run fine in 3.1.

I have added the ability to print disk based bit maps to the library. The function is PrintBitMap() and is documented in REFERENCE.rtf. Most of the code was taken from a sample program included with the compiler and modified to fit into this library. The print functions have the ability to print over the bitmap(s). This allows one to scan a form and later print it and place data on it or to place boilerplate printing in a bit map and print only those portions of the form you wish. It is also handy for printing company logos, letter head, etc.

This code snippet shows how the classes are used in the view class


void CMainViewOnPrint(CDC* pDC, CPrintInfo* pInfo)
{
        CPage* ps = new CPage(pInfo-m_rectDraw,pDC,MM_TEXT);
        if(PRINTWHAT==0) PrintForm1(ps);
        if(PRINTWHAT==1) PrintForm2(ps); // subform demo
        if(PRINTWHAT==2) PrintForm3(ps); // table demo
        if(PRINTWHAT==3) PrintForm3(ps); // bitmap demo
        delete ps;
        return;
}

Below are some small examples of how the classes are used.


void PrintForm1(CPage* pPage)
{
        double Row;
        //Print a bitmap
        ps->PrintBitMap(1.0,1.0,4.0,5.0,"MyBitmap.bmp"); 
        //Print a title
        Row=pPage-Print(0.0,0.0,TEXT_NORMAL|TEXT_CENTER,24,"Form Title");
        //create and use a print region
        CPrintRegion *Region1=pPage->CreateRegion(.5,0.0,1.5,3.9);
        Region1->DrawBorder();
        Region1->DrawTitle("Customer 
        Information",8,TEXT_BOLD|TEXT_CENTER|TEXT_RECT,FILL_NONE);
        Row=pPage->Print(Region2,0.0,0.01,TEXT_NORMAL|TEXT_SINGLELINE,9,"Name");
        Row=pPage->Print(Region2,Row,0.01,TEXT_NORMAL|TEXT_SINGLELINE,9,"Location");
}


//create and use a table
TABLEHEADER* pTable=new TABLEHEADER; 
pTable->PointSize=10;
pTable->LineSize=1; // default shown only for demo purposes
pTable->UseInches=TRUE;
pTable->AutoSize=FALSE;
pTable->Border=TRUE;
pTable->FillFlag=FILL_NONE;
pTable->NumColumns=5;
pTable->NumRows=12;
Table->StartRow=0.0;
pTable->StartCol=0.0;
pTable->EndCol=8.0;
pTable->ColDesc[0].Init(1.0,"Item #");
pTable->ColDesc[1].Init(3.0,"Desc.");
pTable->ColDesc[2].Init(1.0,"# Items");
pTable->ColDesc[3].Init(1.0,"Cost");
pTable->ColDesc[4].Init(1.0,"Ext Cost");
pPage->Table(pTable);    

//place information in a table
pPage-Print(pTable,0,0,12,TEXT_LEFT|TEXT_BOLD,"123-009");
pPage-Print(pTable,0,1,12,TEXT_CENTER|TEXT_BOLD,"Small Cray Computer");
pPage-Print(pTable,0,2,12,TEXT_CENTER|TEXT_BOLD,"2");
pPage-Print(pTable,0,3,12,TEXT_RIGHT|TEXT_BOLD,"22.10");
pPage-Print(pTable,0,4,12,TEXT_RIGHT|TEXT_BOLD,"44.20");

Download demo project - 105 Kb

Download source - 48 Kb



About the Author

Richard Stringer

C C++ ASM are my currrent languages of choice. Currently writing MFC apps for insurance companies

Comments

  • budget-priced clarisonic can set right your skin

    Posted by iouwanzi on 06/06/2013 10:01pm

    [url=http://www.miaclarisonicaustralia.org/]clarisonic mia online[/url] Effort prolongé de la chanteuse Katy Perry pour ne pas mentionner la fille préférée de faire GHD. Juste pour Noël 2011, tous les verrous de ghd de Globe référence quantité offrent l’idée cadeau réelle qui puisse satisfaire à d’innombrables : tous le ghd Galerie écarlate. Cette approche unique raisonnablement limitée format ghd stylerintemporelle Platinum réinventé en ajoutant pourpre et reconnues et en outre les nombreux glitz avec glamour appartenant à la vingtaine : toutes les plus fascinante de mouvement appartenant à l’année. [url=http://www.miaclarisonicaustralia.org/clarisonic-mia]clarisonic mia[/url] Victoria Secret 2012, la dernière conférence de maillots de bain sur la belle Miranda Kerr trésor et sexy top model Candice Swanepoel lors de la sélection se tailler un style de grands ghd lisseur cheveux de milliers de féminité sexy. Mannequin ange sexy pour Victoria Secret 2012, la dernière Maillots de bain pour la publicité, [url=http://www.australiaclarisonic.com/]clarisonic mia[/url] Notre coiffeur étranger encouragés plus tôt ghd Gold styler à mon avis, ainsi que maintenant nos U. s. salon de coiffure en outre leur préféré dans mon expérience – car il est ce que vos applications amant dans le salon, ainsi qu’à la maison (la dame s’avère en outre faire un copain, donc mon partenaire et j’ai confiance dans la jeune fille!). Votre nom de marque est en fait le meilleur et même fera un cheveux sentiment fantastique.Réveillé par le glamour unique dans les années folles, cutting edge styler généralement la méthode pour obtenir l’attraction en ajoutant une touche de paillettes. Tous l’écarlate s’engage dans seulement deux cas Craft Deco design et le style que vous pourriez choisir.

    Reply
  • Nike Draught Max+instagram, desire you take the color to step on your feet!

    Posted by madytreathy on 04/20/2013 04:41pm

    Recognize in 2008, if not earlier, when Nike launched ahead of the separated shoe color projects, the war cry "Scion Your Colours", "Nike PhotoiD" layout, [url=http://markwarren.org.uk/goodbuy.cfm]nike free run[/url] return has not been as enthusiastic as expected. Have in mind, 2008 Canon IXUS 80 IS Digital file card arcade but only 8 million pixels, Nokia, the plastic phone market is the only regulation, NikeiD was support to color in the photos as a infrastructure quest of sneakers custom color, although exciting, but does provoke some. Instagram which sort this item fun and elemental, Nike PHOTOiD homeopathic upgrade customization services, recently [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache[/url] released a new plan. That such iD can you realize pictures as instagram account shoe color, for a short offer Nike Breeze Max shoes and Nike Style Max 1, Nike Affectedness Max 90 953 options. Interested in children's shoes, you [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache[/url] can every vanish into thin air's valid website photoid.Nike.com, in besides to browse other people's artistic industry, or you can struggle to upload your own instagram photo, base your own Nike Air Max.

    Reply
  • Lightweight stylish – Nike Unshackled TR Attack in spring 2013 3 series

    Posted by Tufffruntee on 04/20/2013 12:34am

    Nike Free TR Trim 3 noteworthy features is to purchase the brand-new forge: Nike Self-ruling 5 soles improved bending Scratch; new tractor layout making training more focused when; lighter weight, the permeability is stronger, and more in fashion shoe designs not lone make shoes [url=http://markwarren.org.uk/property-waet.cfm]nike air max 90[/url] more serene wearing, barefoot training caress, but also more stylish appearance. Nike Manumitted TR Then 3 provides excellent lateral reliability, you can take the legs in the leg during training. Acrid vamp upper breathable mesh, demean soap up's consonant lay out can be [url=http://markwarren.org.uk/goodbuy.cfm]nike free uk[/url] seen by virtue of it. Lightweight, demanding, pinched foam material habituated to through entirely occasional seams, more obedient, help is stronger. Requirement more advance, department of a training utilize, bubbles make inaccessible in more parts of the neediness for conformableness, foam loose. Say double talk moisture wicking synthetic materials, unshiny on your feet, refrain from living feet tiring and comfortable. Phylite [url=http://markwarren.org.uk/goodbuy.cfm]nike free run[/url] midsole offers lightweight stupor sustained, famous durability and even outsole can do to greatly turn the comprehensive dialect heft of the shoe. Qianzhang pods on the outsole and heel-shaped Unripened rubber enhances the shoe multi-directional purchase on odd surfaces.

    Reply
  • SNMP Problem

    Posted by keshu82_sh on 07/13/2005 05:02am

    can any one help me in SNMP using VC++

    Reply
  • Print the bgcolor properties that are set in a table

    Posted by Legacy on 09/15/2003 12:00am

    Originally posted by: Kim Weir

    I cannot get the bgcolor that is set in the table to print. Any advice?

    Thanks,

    Kim

    Reply
  • Setting number of pages before displaying Print Dialog

    Posted by Legacy on 09/03/2003 12:00am

    Originally posted by: Clive Minnican

    Hello,
    
    

    Is there any way of calculating and setting the max number of pages before displaying the print dialog?

    To clarify, I know you can set the max number of pages to a constant value in the OnPreparePrinting function ie.


    BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    pInfo->SetMaxPage(2);

    return DoPreparePrinting(pInfo);
    }

    but I need to be able to calculate the number of pages depending on whether the printer is set to portrait or landscape mode. This is where I have a problem since I cannot find out which mode the printer is in due to GetPrinterMode() needing a valid printer device context. I am therefore resorting to calculating the number of pages in the OnBeginPrinting() function.

    Another question regarding this issue is how can I update the number of pages in the dialog when the user goes into properties and changes printer mode from portrait to landscape or vice-versa?

    Any help with either of the above will be much appreciated.

    Clive.

    • Printer Driver

      Posted by keshu82_sh on 07/13/2005 05:06am

      Are u using DDK for developing printer driver

      Reply
    • I am developing the printer driver.

      Posted by notfineman on 05/08/2004 03:03am

      I think your code is good.

      Reply
    Reply
  • Printing rtf files without showing them

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

    Originally posted by: Leon

    Hi!
    
    im trying to write program that prints rtf files form command line without opening window or with hidden window.
    please help me
    Leon
    10x

    Reply
  • http://www.ucancode.net

    Posted by Legacy on 02/21/2003 12:00am

    Originally posted by: happppp

    It's very useful!

    Reply
  • Crashes in real application

    Posted by Legacy on 02/13/2003 12:00am

    Originally posted by: Thomas R�nshof

    Hi, I've tried the demo and it works OK.

    But implementing the classes and testprints in my existing application, the program crashes. Except for PrintForm3 and PrintForm4. But here the page/paper is blank !!!

    Has anyone seen this before ?

    Reply
  • simple Example for printing from a Dialog?

    Posted by Legacy on 11/19/2002 12:00am

    Originally posted by: TimoL


    Hi,
    i am trying to print from a dialog.
    but i don't know how to get the PrintInfo (my first problem)...
    do someone already wrote a simple usage?!?

    thanks
    Timo

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

Top White Papers and Webcasts

  • Event Date: April 15, 2014 The ability to effectively set sales goals, assign quotas and territories, bring new people on board and quickly make adjustments to the sales force is often crucial to success--and to the field experience! But for sales operations leaders, managing the administrative processes, systems, data and various departments to get it all right can often be difficult, inefficient and manually intensive. Register for this webinar and learn how you can: Align sales goals, quotas and …

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds