Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
How to controlling Margins when printing RichEdit contents Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Reporting /Printing
Delphi 2.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			Author: Lou Adler

How can I control margins when printing text that I have loaded into a TRichEdit?


Printing from a RichEdit is really rather easy - all you need to do is to call the 
Print method:

RichEdit1.Print(const Caption: string);

The Caption parameter shown here specifies the title that appears in the Print 
queue.  Therefore you would, for example, call something like:
2   RichEdit1.Print(MyAppName + ': ' + DocumentTitle);

From this call the system will carefully format and print the contents of the 
RichEdit automatically over the required number of pages.  That is all well and 
good, but it does have an unwanted side effect - there is no control over the 
margins whatsoever. It will simply use the default margins as reported by the 
Printer when it returns its printable page size.

In order to be able to define the margins you need to know a number of things... 
The available space on the page, the unprintable area of the page, whether to 
calculate the margins as Inches or Centimetres, and so on. Much of this can be 
retrieved from the Printer object, and the rest we will need to provide in our code.

The first thing to decide is how to determine the measurements. You could pass this 
as a String (e.g. 'inches' or 'centimetres'), you could pass it as a number (e.g. 1 
for inches, 2 for centimetres) but perhaps the easiest way is to declare your own 
data type that will make the code easier to read. For this example I have defined 
TRichTextMeasurements in the Interface section of the unit:

3   type
4     TRichTextMeasurements = (rtmNone, rtmInches, rtmCentimetres);

Now we can determine whether to use the default margins (rtmNone) or to create our 
own margins in the selected measurement.

Now all we need is the code to implement the margins if needed. This example 
function accepts parameters to describe the margins required, the type of 
measurements to be used for creating margins and the number of copies to be printed.
6   function PrintRichText(RTLeftMargin, RTRightMargin, RTTopMargin, RTBottomMargin:
7     Extended;
8     RichTextMeasurement: TRichTextMeasurements; Copies: Integer): Boolean;
9   var
10      PixelsX, PixelsY, LeftSpace, TopSpace: Integer;
11      LeftMargin, RightMargin, TopMargin, BottomMargin: Extended;
12  begin
13    Result := False; // default return value
14      if RichTextMeasurement <> rtmNone then
15          begin
16             // get pixels per inch
17          PixelsX := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
18          PixelsY := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
20           // get non-printable margins
21          LeftSpace := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
22          TopSpace := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
24          LeftMargin := RTLeftMargin;
25          RightMargin := RTRightMargin;
26          TopMargin := RTTopMargin;
27          BottomMargin := RTBottomMargin;
29           // If the measurement is set in Centimetres, recalculate
30          if RichTextMeasurement = rtmCentimetres then
31              begin
32                LeftMargin := LeftMargin / 2.54;
33              RightMargin := RightMargin / 2.54;
34              TopMargin := TopMargin / 2.54;
35              BottomMargin := BottomMargin / 2.54;
36            end;
38             // Set the Margins
39            R.Left := Round(PixelsX * LeftMargin) - LeftSpace;
40            R.Right := Printer.PageWidth - Round(PixelsX * RightMargin) - LeftSpace;
41            R.Top := Round(PixelsY * TopMargin) - TopSpace;
42            R.Bottom := Printer.PageHeight - Round(PixelsY * BottomMargin) - TopSpace;
43            RichEdit1.PageRect := R;
44            Application.ProcessMessages;
45        end;
47    // Print the required number of copies
48      while Copies > 0 do
49          begin
50            RichEdit1.Print('MyApp: Copy ' + IntToStr(Copies));
51          Dec(Copies);
52          Application.ProcessMessages;
53        end;
54    Result := True;
55  end;

To call the example code to print one copy with a 1 inch margin all round, you 
could do something like this:

56  procedure TForm1.PrintButtonClick(Sender: TObject);
57  begin
58      if PrintRichText(1, 1, 1, 1, rtmInches, 1) then
59          ShowMessage('Printing was successful')
60        else
61          ShowMessage('Printing failed');
62  end;

Note that if you want to use the default margins you still have to pass a number 
for each margin in the function call. What that number is does not matter as they 
are all ignored, but perhaps for clarity using a zero would be best:

63  procedure TForm1.PrintButtonClick(Sender: TObject);
64  begin
65    if PrintRichText(0, 0, 0, 0, rtmNone, 1) then
66      ShowMessage('Printing was successful')
67    else
68      ShowMessage('Printing failed');
69  end;

This example can easily be extended to provide visual print progress feedback, or to add margin measurements in millimetres.  However, it will not replace a full implementation as provided by commercial Word Processing products. On the other hand, for many purposes it will more than suffice.

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC