Download demo project - 104 Kb
Download source files - 49 Kb
Full class documentation available here.
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. This class eliminates the need to use and ship
report generators with your application.
Below is some output from the library functions. These
images were taken directly from the print preview window running the demo
program. Much more detailed printing is possible with the functions as written.
They are also easily modified for special needs.
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 CPage::Table(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. CPage::CreateRegion() 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.The bit map printing is in dib.cpp and dib.h.
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. I suggest that you download
the demo project as it shows how to use the more esoteric features of the
classes. It contains sample code exercising most of the class members.
One thing that we learned from this project 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 CMainView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
CPage* ps = new CPage(pInfo-m_rectDraw,pDC,MM_TEXT);
if(PRINTWHAT==0) PrintForm1(ps);
if(PRINTWHAT==1) PrintForm2(ps);
if(PRINTWHAT==2) PrintForm3(ps);
if(PRINTWHAT==3) PrintForm3(ps);
delete ps;
return;
}
Below are some small examples of how the classes are used.
void PrintForm1(CPage* pPage)
{
double Row;
ps->PrintBitMap(1.0,1.0,4.0,5.0,"MyBitmap.bmp");
Row = pPage-Print(0.0,0.0,TEXT_NORMAL|TEXT_CENTER,24,"Form Title");
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");
}
TABLEHEADER* pTable = new TABLEHEADER;
pTable->PointSize = 10;
pTable->LineSize = 1;
pTable->UseInches = TRUE;
pTable->AutoSize = FALSE;
pTable->Border = TRUE;
pTable->FillFlag = FILL_NONE;
pTable->NumColumns = 5;
pTable->NumRows = 12;
pTable->StartRow = 0.0;
pTable->StartCol = 0.0;
pTable->EndCol = 8.0;
pTable->ColDesc[0].Init(1.0,"Item #",FILL_NONE);
pTable->ColDesc[1].Init(3.0,"Desc.",FILL_LTGRAY);
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);
pPage->Print(pTable,0,0,12,TEXT_LEFT|TEXT_BOLD,"123-009");
pPage->Print(pTable,0,1,12,TEXT_CENTER|TEXT_BOLD,"SmallCray 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");
In order to use the printing functions in your project you
need to include the files:
CPage.cpp
CPage.h
CPrinter.cpp
CPrinter.h
Dib.cpp
Dib.h
In any file where reference to the printing functions is needed include
the header file:
CPage.h
That�s all that is needed to incorporate the printing functions.
If you find this library useful let me know.
(kdtexas@onramp.net)
Table of Contents
Functions
Not all functions are located here. Consult the demo program or CPage.h for a complete list
SetUserFunction
SetPrinterMode
GetPrinterName
CPage Constructor
Print
PrintColumn
SetLineSpacing
SetFont
SetFontSize
SetColor
SetRightMargin
SetBottomMargin
GetDisplayContext
PrintBitmap
GetNextLogicalColumn
Line
Box
CheckBox
Tables
Rotated
Text
Print(TABLEHEADER* )
Regions
Create
SubRegions
Printer Class Documentation
Class definitions located in CPrinter.h
Functions in CPrinter.cpp: This is a low-level printer
function class. All calls from the higher-level functions will eventually
get here to one of the printer primitives. To add functionality to the
high level class(s) it is best to let the high level classes handle all
formatting etc and call simple primitive output functions. This will make
porting to a different output device or operating system a little easier.
Below is the class definition of the low-level class CPrinter.
class CPrinter{
public:
CPrinter();
virtual ~CPrinter();
virtual int GetPrintInfo(PRTTYPE *ps,double LineSpacing);
virtual int PrintText(PRTTYPE *ps,double LineSpacing);
virtual void DrawLine(PRTTYPE *ps,int LineSize);
virtual void DrawRect(PRTTYPE *ps,int LineSize);
};
int GetPrintInfo: This function will set internal variables
without actually printing the output string. It is mainly used internally.
int PrintText: The workhorse. Just about every call gets
routed here eventually. This function creates a font each time it is called
and calculates print parameters and changes internal variables. If the
class is to slow this is where it can be sped up considerably. The return
value is the next logical print line. It is calculated using the current
map mode, font size, and spacing factor.
void DrawLine: Line drawing primitive. Very basic.
void DrawRect: Rectangle drawing function. Very basic.
The class user should call none of these functions. Use
the higher level calls. However, if minimal print functionality is all
that is needed this can be a standalone library and does have quite a bit
of functionality
Back
PRTTYPE structure definition
The PRTTYPE structure is used to hold information about
the current print page and the current output string. It also retains information
across printer calls that can be used in determining future output selections.
It is defined below:
typedef struct tagPrinter{
CDC *pDC;
RECT rc;
int PointSize;
CString Text;
UINT uTextFlags;
UINT uFillFlags;
UINT uPenFlags;
CString FontName;
UINT n_maxWidth;
UINT n_maxLength;
UINT n_minNextLine;
int m_NextCharPos;
int m_MinDisplacement;
RECT LastPrintArea;
TEXTMETRIC* tm;
}PRTTYPE;
This structure is a member of the Cpage class and is
maintained internally. It is initialized in the Cpage constructor using
information passed. The TEXTMETRIC field ,LastPrintArea, and m_NextCharPos are
calculated and changed by each call to PrintText(). The print behavior is
modified by changing the uTextFlags and uPenFlags variable ( see definitions in
CPrinter.h ) .The current output string is contained in the variable Text (
isn�t that remarkable ). The parameters are set using information passed to the
various output routines.
Back
CPage Class Definitions
CPage contains most of the class functionality. CPage.H
and CPage.Cpp contain the class headers and class definition.
All of the print routines have a new override added that
takes a user supplied integer indentifier and passes it to a user suppled
function that will return the text to be printed. This function must be
in the form of: LPCSTR (*PF_REMOTE)(int) which is defined in CPage.h.
This function is set by a call to CPage::SetUserFunction(UserFunctionAddress).
If this function is not called all the output routines called form the
functions calling the user defined function will do no output and those
that return a value will return 0. All of the Print and PrintColumn functions,
including those that print to regions, have this over ride. The demo program
has been updated to show these functions in a working example. These functions
are included to make it easier to design a data independant form and to
facilitate using the library as a portion of a report generator, form generator,
etc. See PrintForm5(CPage* ps) located in PrintForm1.cpp. A sample
user defined function is shown below:
LPCSTR MyFunction(int ID)
{
static CString S;
switch(ID)
{
case ID_1:
return "Called From User Function ID 1";
case ID_2:
return "Called From User Function ID 2";
case ID_3:
return "Called From User Function ID 3";
case ID_4:
return "Called From User Function ID 4";
case ID_5:
return "Called From User Function ID 5";
case ID_6:
S.Format("%.2f",120.90);
return S;
}
return "*****unknown ID Passed*****";
}
This is a very simple version of a user function but demonstrates
how it is used. In real life it would be more complex and probably call
other functions, do calculations, and other data manipulation tasks. Just
as long as it returns a pointer to a output string all is well. The string
is used immediatly and need not be persistant. Static buffers can be re-used
between calls. However if CStrings or other variables are used as buffers
be certain that they are either static or created on the heap and not destroyed
until after use. Variables set on the stack frame will not be accessable
to the output routines because they will go out of scope on he user function
return. In order to set the call up you will call:
Back
CPage::SetUserFunction(MyFunction);
This can be called more than once thereby replacing the
active function making it possible to have several output functions for
the same page. The effect of this technique is a lot like subclassing the
CPage object but without the overhead. The user defined function should
be prototyped as typedef LPCSTR (*PF_REMOTE)(int). An example
is :
LPCSTR MyFunction(int ID)
{
switch(ID)
{
case ID_1:
S="Called From User Function ID 1";
return S;
case ID_2:
return "Called From User Function ID 2";
}
return "";
}
There is a special over ride of the Print function:
virtual double Print(double row,double col,UINT TextFlags,int
PointSize,int ID);
This function works in conjunction with the
SeUserFunction in that the user defined function is called to supply the prit
text. See the demo program for details.
Example:
void PrintStuff(CPage* ps)
{
ps->SetUserFunction(MyFunction);
double row = ps->Print(0.0,0.0,TEXT_NORMAL|TEXT_CENTER,24,"User Demo");
row = ps->Print(row,0.0,TEXT_BOLD|TEXT_ITALIC|TEXT_CENTER,24,ID_1);
}
static void SetPrinterMode(CDC*
pDC,int Mode=DMORIENT_PORTRAIT);
This function will change the printer orientation of the printer. IT
CANNOT BE CALLED AFTER THE CONSTRUCTOR
for Cpage is called and
as such is a static member function. It must be called by a function in
the function chain somewhere before the OnPrint() or OnDraw() function
is called and after access to the CDC for the print job is available. The
recommended place to call the static member function is your CView::OnPrepareDC()
override. The CDC passed to this function will be changed by this function
call. The mode parameter must be either DMORIENT_PORTRAIT ( default ) or
DMORIENT_LANDSCAPE.
Example
void CMainView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
CView::OnPrepareDC(pDC, pInfo);
switch(pInfo->m_nCurPage)
{
case 1:CPage::SetPrinterMode(pDC);break;
case 2:CPage::SetPrinterMode(pDC,DMORIENT_LANDSCAPE);break;
}
}
DO NOT CALL THIS FUNCTION ONCE THE CONSTRUCTOR FOR CPAGE HAS EXECUTED.
For users not familiar with static
member functions. The above code creates a CPage object on the stack and
executes the member function. The function does not depend on or alter
any data in the class so it needs no virtual table entry or a this pointer.
( as a matter of fact in CANNOT read or write and class data at all) There
will be one and only one copy of the function created no matter how many
CPage objects that there are. This is a poor explanation of static member
functions; please consult the MS documentation for details. HA!
Back
static LPCSTR GetPrinterName(CDC*
pDC);
This function will return the name of the selected printer
driver in use for this CDC. The driver cannot be changed but can be used
to switch between options. This function and the above function also demonstrates
the method of get data from and changing data in a DEVMODE structure. This
method can be used to change paper size DPI etc for all supported printers,
Back
CPage(RECT rectDraw,
CDC* p_Dc, int MapMode=MM_ANISOTROPIC)
This is the class constructor. There is no private
constructor override. This class is designed to be used in conjunction with MFC
and makes use of the Cview class printing architecture. The parameters
are:
RECT rectDraw The drawing rectangle to be used by this
output device. ( see example )
CDC* The display context object passed by MFC to the
print function
Int mapMode The supported mapping modes are MM_TEXT and
MM_ANISOTROPIC
Example of use:
void CMainView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
double Row,Col;
CPage* ps = new CPage(pInfo->m_rectDraw, pDC,MM_TEXT);
Row=ps->Print(6.5,4.0,TEXT_NORMAL,10,"This is a test");
delete ps;
}
Back
int Print(int row,int col,char* fmt,...);
// use cpage default parameteres for flags pt size etc...
int Print(int row,int col,UINT TextFlags,int PointSize,char* fmt,...);
The workhorse. This function has many different overloads*. All
class functions are designed to use several different units of measurement. In
MM_TEXT map mode the native unit is pixels, which can vary from output device to
output device. In MM_ANISOTROPIC the units are user defined in both axis. The
default for this class is 1000 by 1000. The library can also function in terms
of inches. The passed parameters are converted to native units before being
passed to lower level functions. Inches present the problem of being fractional
in value and not integral. To facilitate the ease of use the library makes the
following assumptions to all calls to the Print functions (With one exception
noted below). If the value is a double it is treated as a inch measurement. If
one of the location variables (Row and Col) is a double the other must be a
double also. The parameters are:
Int row the vertical displacement for the print line.
Displacement is relative to the top of the page.
Int col the horizontal displacement for the print line.
Displacement is relative to the left side
( both
of these parameters can be doubles and if so are treated as inches )
UINT Textflags Modify the appearance of the output string.
See CPrinter.h
Int PointSize The number of points
to use for the font.
Char* fmt a printf type
format string.
Example of use:
Void PrintStuff (CPage* ps)
{
Row = ps->Print(6.5,4.0,TEXT_NORMAL,10,"This is a test");
Row = ps->Print(Row,4.0,TEXT_NORMAL,10,"This is a test Also");
Row = ps->Print(Row,4.0,TEXT_NORMAL,10,"This is a test Also as is this");
Col = 1.0;
ps->Print(Row,&Col,TEXT_NORMAL,10,"This is a test Also as is this");
ps->Print(Row,&Col,TEXT_BOLD|TEXT_ITALIC,10,"This");
ps->Print(Row,&Col,TEXT_BOLD,10,"is Italic");
}
*note
Consult CPage.h for details on all the various
overloads. There are many.
int Print(int row,int *col,UINT
TextFlags,int PointSize,char* fmt,...) is a special override that takes
a pointer to the column variable. (See example above). On execution the
column variable is updated to the next column position. Subsequent calls
to Print using the variable will result in the output being a continuos
line allowing different attributes to be assigned within a line of text.
It is useful when printing a series of question/answer type forms also
as the variable will point to the next logical horizontal print area at
all times. There are also two overrides of this function that take only
Row,Column, Text parameters and get the rest of the information from the
defaults set into the CPage object.
Back
void PrintColumn(int Top,int
Left,int Bottom,int Right,UINT flags,int PointSize,LPCSTR Text);
Print function to allow for newspaper style print
columns. The location variables function in the same manner as in Print() above
but have two extra dimensions to describe a bounding rectangle. All text will be
printed in the rectangle. If the flags variable includes TEXT_RECT the bounding
rectangle will be drawn on the output device. See Print() for variable
usage.
``
Example of use:
Void PrintStuff (CPage* ps)
{
ps->PrintColumn(1.0,1.0,3.0,4.0,TEXT_BOLD|TEXT_RECT,8,
"This is a test of the column wrap feature");
ps->PrintColumn(1.00,4.1,3.0,7.0,TEXT_BOLD,8,
"This is a test of the column wrap feature ");
}
Back
double SetLineSpacing(double Spacing);
Set the constant used in calculating the next logical
print line.. The amount needed to get the affect you want will vary so
experiment. Should be no smaller than 1.0
Back
LPCSTR SetFont(LPCSTR FontName);
Set the default font name. The constructor sets it to
"Times New Roman". Spelling does count. The old font name is returned from this
function. If all you want is the font name use SetFont(NULL) to return the
current font name.
Back
int SetFontSize(int sz);
Set
default font pointsize.
Back
COLORREF SetColor(COLORREF Color);
If the output device supports color set the current color
here. Returns the old color.
Back
virtual int SetRightMargin(int width)
Change the size of the default printing rectangle right
margin. A value of -1 will reset it to MaxWidth. A value of 0 will just return
the current value.Returns the previous width.
Back
int SetBottomMargin(int length);
Same as above except the margin affected is the
bottom
Back
double SetRightMargin(double
width);
See above
Back
double SetBottomMargin(double
length);
See Above
Back
CDC* GetDisplayContext();
Return the display context used for this page. Can be used
for direct manipulation of the context
Example of use:
void PrintStuff (CPage* ps)
{
CDC* pDcpDc=ps->GetDisplayContext();
}
Back
void PrintBitMap(int top,int left,int bottom,int
right,LPCSTR name);
void PrintBitMap(double top,double left,double bottom,double right,LPCSTR name);
Prints a bitmap from a disk file into a region of the
page. The numeric parameteres are location vectors for the bounding rectangle
and the LPCSTR param is the name of the file to print. Disk based bitmaps are
directly supported as there are many ways to print a resource bitmap.
Example of use:
Void PrintStuff (CPage* ps)
{
ps->PrintBitMap(1.0,1.0,4.0,5.0,"MyBitMap.bmp");
}
Back
double GetNextLogicalColumn(BOOL Convert=TRUE,BOOL
AddOffset=FALSE);
Returns the next logical print column based on the last
call to Print(). This must not be used prior to a call to Print() as garbage
will be returned. Parameters are:
BOOL Convert if true will return result in inches
BOOL AddOffset if true will add extra space to column to
give separation.
Example of use:
Void PrintStuff (CPage* ps)
{
double Col;
ps->Print(6.5,4.0,TEXT_NORMAL,10,"This is a test");
Col = ps->GetNextLogicalColumn(TRUE);
ps->Print(6.5,Col,TEXT_NORMAL|TEXT_ITALIC,10,"This is a test Also");
}
Output will be "This is a test.
This is a test also" starting
4 inches over and 6.5 inches down. The common usage is to apply special
formatting to indivivual words in a sentence.
Back
void Line(int top,int left,int bottom,int right,int
LineSize=1,UINT flag=PEN_SOLID);
void Box(int top,int left,int bottom,int right,int
LineSize=1,UINT Fillflags=FILL_NONE,UINT PenFlags=PEN_SOLID);
Drawing primitives exposed to user. Parameters can also
be doubles. If so they represent inches.Parameters are:
Int top,left,bottom,right: top/left define the position of
the left starting point
Bottom/right the
right.
In the case of a rectangle the points describe the
bounding area to draw the rectangle around
Int
Linesize Determines thickness of the line used to draw the shape 1 is
smallest
Int Fillflags determines if area is
filled with color see CPrinter.h for definitions
Int Penflags Pen type used to draw See CPrinter.h for
definitions
Example of use:
Void PrintStuff(CPage*ps)
{
ps->Line(5.0,0.0,5.0,8.0);
ps->Line(0.0,4.0,10.0,4.0);ps->Box(4.0,3.0,6.0,5.0);
}
Back
void CheckBox(LPSTR Caption,BOOL Data,int top,int left,int
FontSize,int Direction=LABEL_RIGHT,int LineSize=2,UINT Fillflags=FILL_NONE,UINT
TextFlags=TEXT_NORMAL|TEXT_NOCLIP|TEXT_SINGLELINE);
Draws a Checkbox on the output device. Parameters are
:
LPSTR Caption The text accompanying the
checkbox
BOOL Data The true/false expression to
be shown
Int top,left The starting position to
print the Checkbox. Can be doubles.If so units are inches.
Int Direction either LABLE_RIGHT or LABEL_LEFT
Int Linesize Thickness of pen used to draw the boxUINT
Fillflags If set to any value other than FILL_NONE the checkbox will use the
fill color to fill the box rather than Xing the box
UINT TextFlags Define text attributes (See
CPrinter.h)
Example of use:
void PrintStuff (CPage* ps)
{
ps->CheckBox("A Test",TRUE,1000,1000,12,LABEL_LEFT,2,FILL_BLACK,TEXT_BOLD);
ps->CheckBox("A Test again",TRUE,1100,1000,6,LABEL_RIGHT,2,FILL_NONE,TEXT_BOLD);
ps->CheckBox("A Test",TRUE,8.0,1.0,12,LABEL_LEFT,2,FILL_BLACK,TEXT_BOLD);
ps->CheckBox("A Test again",TRUE,9.0,1.0,6,LABEL_RIGHT,2,FILL_NONE,TEXT_BOLD);
}
Back
Tables
Tables are a method of showing tabular data. They are
similar to a grid control, only printed. Many business forms are simply a series
of tables. The table metaphor has been implemented by use of three helper
classes:
class CPrintTable;
class COLUMNDATA;
class TABLEHEADER;
TABLEHEADER is a very simple class that describes a table of
data. It is described below.
class TABLEHEADER {
public:
~TABLEHEADER();
TABLEHEADER();
BOOL UseInches;
BOOL AutoSize;
UINT FillFlag;
int PointSize;
int LineSize;
int NumColumns;
int NumRows;
BOOL Border;
BOOL Vlines;
BOOL HLines;
BOOL HeaderOnly;
BOOL NoHeader;
int HeaderLines;
int NumPrintLines;
double StartRow;
double StartCol;
Double EndCol;
Double EndRow;
COLUMNDATA ColDesc[20];
CprintTable* pClsTable;
};
Example of use:
TABLEHEADER* pTable=new TABLEHEADER;
pTable->PointSize=10;
pTable->UseInches=TRUE;
pTable->AutoSize=FALSE;
pTable->Border=TRUE;
pTable->FillFlag=FILL_NONE;
pTable->NumColumns=3;
pTable->NumRows=6;
pTable->StartRow=3.5;
pTable->StartCol=.1;
pTable->EndCol= 8.0;
pTable->ColDesc[0].Init(4.0,"Coverages");
pTable->ColDesc[1].Init(3.0,"Limits ofLiability");
pTable->ColDesc[2].Init(1.0,"Premium");
ps->Table(pTable);
ps->Print(pTable,0,0,8,TEXT_LEFT,"Section I - Coverage A: Dwelling");
ps->Print(pTable,1,0,8,TEXT_LEFT,"Section I - Coverage A: Other Structures");
delete pTable;
Class COLUMNDATA is also a very simple class. Its total
functionality is demonstrated above. It is a member of class TABLEHEADER and is
created when it is and destroyed with it. Just use it to describe the columns
width and caption. The width unit of measurement is determined by the
TABLEHEADER UseInches variable.
class COLUMNDATA
{
public:
double Width;
CString Text;
COLUMNDATA() { Width = 0; Text.Empty(); };
Void Init(double nWidth,LPCSTR lpzText) { Width = nWidth; Text = lpzText; };
};
Class CPrintTable is used internally and should not be
exposed. It actually draws and fills the table with data. It is called and used
by CPage . See the source code for details.
Tables are attached to the page by using the function
CPage::Table(pValidTableHeader). Once the TABLEHEADER has been created and
filled in pass it to the CPage class using this function. The Table is drawn on
the output device at this point. The variable LastRow is filled in at this time
and is available for use.If you are stacking tables this variable will tell you
where to start the next table. See example below.
There is an overloaded Print() function in CPage that
allows data to be inserted into the table:
Back
virtual void Print(TABLEHEADER* TheTable,int row,int col,int
PointSize,UINT TextFlags,char* fmt,...);
In creating a table if the data element NumPrintLines is
greater than 1 each cell will be made large enough to contain multiple print
lines. The size will be determined from the font size used to create the table.
If you use a smaller font in printing there may be more visible print lines than
you specified. The standard Print(TABLEHEADER,...) overide of the Print function
will operate in a different manner if the value is set to more than 1. See
CTable::InsertItem for details. Word wrap and text clipping is in affect unless
overridden.
The Row and Col parameters that usually show position
indicate the table row and column in this overload. Other than that it operates
just like the CPage::Print() statement
Example of use:
ps->Table(pTable);
double lastRow=pTable->EndRow;
ps->Print(pTable,0,0,8,TEXT_LEFT,"Section I - Coverage A: Dwelling");
ps->Print(pTable,1,0,8,TEXT_LEFT,"Section I - Coverage A: Other Structures");
That�s all there is to using tables. They are used a lot
in business forms and insurance applications.
REMEMBER IF YOU CREATE A
TABLEHEADER USING NEW THAT YOU HAVE TO DELETE IT.THE CLASS WILL NOT
AUTOMATICALLY DELETE THESE POINTERS.
Back
Regions
Regions are a lot harder to describe than to use. A Region
is a area of the page that you wish to treat as a single item. It may contain
Text or checkboxes or columns. It may have a title and a border. If the
location of the region moves then all of the data contained in the region
moves with it. Many forms have areas that contain data on specific topics.
Many times you�ll get everything finished and someone will say "Boy it
would be neat if that section was here and that one here". Regions are
the cure for that. The class CPrintRegion implements regions. It is really
a very simple class. Data is put into Regions using, of course, overloaded
versions of the CPage::Print() CPage::PrintColumn()
and CPage::CheckBox() functions
already described. The functions all take one extra parameter. A pointer to a
CPrintRegion. You obtain a pointer to a CPrintRegion by calling one of these two
functions defines in CPage:
Back
virtual CPrintRegion* CPage::CreateRegion(double ptop,double
pleft,double pbottom, double pright);
virtual CPrintRegion* CPage::CreateRegion(int ptop,int
pleft,int pbottom, int pright);
CPrintRegion*
CreateSubRegion(CPrintRegion* pParent,int ptop,int pleft,int pbottom, int
pright);
CPrintRegion*
CreateSubRegion(CPrintRegion* pParent,double ptop,double pleft,double pbottom,
double pright);
As usual if the position is passed as a double we assume
that all measurements are in inches.
The only
callable functions from CPrintRegion are DrawBorder() and DrawTitle(). See the
header file in CPage.H for details. Subregions are simply regions that are
referenced to another region. A Subregion is completly contained in the parent
region and all offsets are based on the parent region at creation. If the parent
region is moved the subregion moves with it.Usage of these functions are shown
below.
Example of use:
Void PrintStuff (CPage* ps)
{
double Row;
PrintRegion *Region1=ps->CreateRegion(1.0,1.0,2.0,4.0);
CPrintRegion *SubRegion1=ps->CreateSubRegion(Region1,0.0,1.0,2.0,2.0);
Region1->DrawBorder();
SubRegion1->DrawBorder();
Region1->DrawTitle("The Title",8,TEXT_BOLD|TEXT_CENTER|TEXT_RECT,FILL_NONE);
ps->CheckBox(Region1,"A Test",TRUE,.2,0.0,12,LABEL_LEFT,1,FILL_NONE,TEXT_BOLD);
Row=ps->Print(Region1,1.0,0.0,TEXT_NORMAL,14,"This is a test");
ps->Print(SubRegion1,0.0,0.0,TEXT_BOLD,"In subregion");
}
DO NOT DELETE THE CPrintRegion
POINTER RETURNED TO YOU. THE CPage CLASS MAINTAINS A LIST OF THESE AND FREES
THEM WHEN THE DESTRUCTOR RUNS. DELETEING A CPrintRegion POINTER WILL RESULT IN A
PAGE FAULT WHEN THE CLASS TRIES TO ACCESS THE ITEM.
There are overrides for all the line and box drawing
routines. They work just like CPage::Line() and CPage::Box() with he exception
of the first parameter which is a pointer to a CPrintRegion. They are not
documented here but see the source code for details. They do provide some
checking for parameter validity and assure that drawing only takes place within
the region passed.. As usual all offsets are relative to the region not the
page. A offset of 0,0 refers to the first printable spot in the region,
whereever it is located. If offsets are outside the region they are adjusted
back to fit within the region.
Back
void
PrintRotatedText(double Top,double Left,double Bottom,double Right,UINT
flags,int PointSize,LPCSTR Text,int angle);
This function allows one to print text rotated thru 360
degrees. The angle of orientation is expressed in 1/10 of a degree and
represented as an integer for 0 to 3600. Parameters are
double Top,Left,Bottom,Right. Boundries of text clipping
area. TEXT_NOCLIP should be used to rotate text thru non region areas.
UINT Flags are the standard text flags
int Point size is the font size
LPCSTR Text is , of course, the text
int angle is the rotation angle expressed in 1/10 of a
degree. Valid range is 0-3600.
Example of
use:
void PrintForm6(CPage* ps)
{
CString s;
double row=0.0;
for(int y=0; y < 3600;y+= 300)
{
s.Format("Rotated Text Demo:Factor %d",y);
ps->PrintRotatedText(5.5,4.0,9.0,8.0,TEXT_BOLD|TEXT_NOCLIP,16,s,y);
}
}
Back