|
|

Available Now

Search

Contact
Feedback:
Send an e-mail with your
comments about this program (or anything else).

Help support DFF
If you benefit from the website, in terms of
knowledge, entertainment value, or something otherwise useful,
consider making a donation via PayPal to help defray the
costs. (No PayPal account necessary to donate via credit
card.) Transaction is secure.


|
| |
Here's a "Print Preview" unit which will let you
preview and print memo and stringlist data. As usual, the motivation
was the requirement to preview and print these two component types in
another program (the Crossword generator).
The unit is based on one among several found at programmer's heaven.com. It
was simple enough to get a handle on and flexible enough to let me add the
missing StringGrid preview function. The author is nearly anonymous (no name
just an invalid email address, rpetersn@usit.net).
So Ryan, if you ever run across this, drop me a line and I'll be glad to give
you a better credit write-up.
The unit handles multiple pages, scaling of the preview, and the ability to save
preview pages and reload them at a later
date. There is much you can learn about metafiles and how they work by
studying the code, but not too much that you must learn in order to to use
it.
Metafiles
The unit uses metafiles, one per page, as the ideal mechanism for accurate
scaling of the same data to different devices. A little about metafiles from Microsoft:
"Enhanced metafiles provide true device
independence. You can think of the picture stored in an enhanced metafile as a
"snapshot" of the video display taken at a particular moment. This
"snapshot" maintains its dimensions no matter where it appears on a
printer, a plotter, the desktop, or in the client area of any application.
You can use enhanced metafiles to store a picture
created by using the GDI functions (including new path and transformation
functions). Because the enhanced metafile format is standardized, pictures that
are stored in this format can be copied from one application to another; and,
because the pictures are truly device independent, they are guaranteed to
maintain their shape and proportion on any output device."
When a metafile is being built, data is written to a special "device
context", a structure that defines the characteristics of a particular
device. Borland defines a TCanvas object type to represent a device
context and a descendant TMetafileCanvas type to describe the special device
context associated with metafiles. Data is written to either type
using the same TCanvas methods. More significantly, when a
TMetafileCanvas is freed, the data written to it is encoded in the associated metafile.
The metafile can then it can be saved and/or
"played-back" to any specific device type using the "Stretchdraw"
command for that device's canvas.
Print Preview Methods
The main methods from the PrintPreview unit are:
- XInch and YInch convert a passed inch value to pixels using
the current metafile resolution.
- MemoOut copies memo text (or any TStringlist object) to the
metafile. Parameters are
- aRect : the rectangle describing the area available for
the drawing the text.
- memolines: a stringlist containing the text lines to be
displayed.
- memofont: the font to be used for displaying the text.
- LastCharDisplayed: If the data cannot all be displayed in
the rectangle provided, this is the position of the last character that
was displayed.
- Returnremainder: A Boolean value indicating whether the input
stringlist should have the displayed characters removed. If true
and the list is not empty, the text remaining needs to be displayed in
the next column, page, etc.
- StringGridOut write a StringGrid to the MetafileCanvas. The
procedure will check if an OnDrawCell exit is defined for the StringGrid.
If so, a special protocol is used to call the exit. In a normal
DrawCell exit, the passed StringGrid address is used both to provide access
to the data and canvas for drawing. In this case the two required address
are different - the grid for data information and the MetafileCanvas
for the drawing location. I solve this be passing the two addresses in
a TList to the OnDrawCell exit. The exit can recognize this
case and handle it appropriately. You can check the demo
program for details.
Parameters:
- Grid : The Stringgrid to draw
- NewWidth The width of the image on the
MetafileCanvas.
- Origin: The X, Y coordinates of the top left corner of the grid.
- Showgrid a Boolean value indicating that the interior
gridlines of the Stringgrid are to be drawn
- Showdata A Boolean value indicating that the data in
the Stringgrid cells is to be drawn.
- NewHeight An output of StringGridOut
indicating the height of the drawn Stringgrid.
- GetGridHeight This function returns the height of the
passed StringGrid before it is drawn. This allows us to move to a new
page if necessary before actually rendering the
grid.
Parameters are:
- Grid : The Stringgrid to draw
- NewWidth The width of the image on the
MetafileCanvas.
- NewJob: Starts a new job.
- NewPage Start a new page.
- PageCount Number of pages created for this job so
far.
- Currentpage The page currently being built or displayed.
- PageSize The total width and height of a page
- PrintSize : The height and width of the printable area of
the page.
- DisplayPage(Page : Integer);
- Preview: Setup and display page 1.
- PrintPage:
- PageNum : The page number to print.
- PrintAll: Print all pages.
- SaveToFile: Save the metafiles (one per page) to a single
disk file.
- FileName: The file name to save to.
- Note that even though files are EMF format internally, the
disk file created is not in standard EMF file format. There
is one file for each preview page but I write a file stream saving
all of the pages (metafiles) in a single disk file.
- LoadFromFile: Load previously saved metafiles.
- Filename : The file name to load from.
The Demo Program
The string grid in the demo illustrates use of an OnDrawCell exit to display any cell with a valid numeric value in red and
underlined. (The grid is initially filled with random numbers and letters. You can double click on any white cell
to modify the data.)
On page 1 of the output, the demo will preview or print the StringGrid followed by
the introduction memo. Page 2 has the order
reversed and prints the memo in narrow format to force some page breaks.
It will probably result in 4 pages for most devices.
Addendum June 10, 2007: Version 2 posted today adds the ability
to automatically insert a page break when it reaches the end of a page.
Fixed rows (column headers) are replicated at the top of each continues page.
The fixed cells are now colored using the grid's FixedColor property.
I'll leave the download zip file link for the executable file in the links
below because I put it there in 2004. But there's not much reason to
download that I can think of.
Addendum January 23, 2008: A recent question from a viewer about
right aligned text triggered a restudy of the Margin setting code added last
year. A new button in the demo program prints a message in each corner of
the page based on margin values set. New procedures
SetInchMargin and SetPixelMargin make it easy to set margins for each
border. Note for programmers - this change has replaced TSpinEdit
controls with TDFFSpinEdit controls to achieve compatibility with Turbo
Delphi Explorer, a free updated Delphi version which does not include TSpinEdit.
Download and Explore Programs
Click to download source code for Print Preview
and the demo program.
Click to download executable demo
program.
Future Explorations
- The unit calls the Printer.BeginDoc procedure while building
each new page - this is somewhat awkward and would be unnecessary except
that some printer characteristics are used even in scaling the
screen preview. I think that printer characteristics could
be collected at NewJob time and "BeginDoc"s
not issued until actual playback to the printer is taking place.
- I'm suspicious of the methods used to get and set font, pen,
and brush in the metafiles. They are simply
"set" with the equals operator. I think that assigning the
controls would be the proper way to do it.
|