Author: Jonas Bilinkevicius
I am using a TRichEdit in my application that shows text in a 10 point character
size. I would like to print it using a size of 13. How can I change the printing
size?
Answer:
If the whole contents of the TRichEdit use the same font size the simplest method
would be to simply assign 13 to richedit.font.size, print the bugger and revert the
size to 10. One could do this with a hidden TRichEdit control that contains a copy
of the text, if the user should not be aware of what is going on.
This method will break as soon as the rich edit control contains formatted text in
several font sizes. In this case one can scale the printer canvas by using a custom
mapping mode. Unfortunately this means one has to do the printing manually, since
the mapping mode can only be set after a BeginDoc and richedit.print will then
fail. Here is an example that will print a TRichEdit 1.3 times the original size.
It assumes all text will fit onto the first page. If several pages need to be
printed the scaling of the printer canvas needs to be redone after each NewPage,
since that resets the printer canvas to the default mapping mode!
1
2 procedure TForm1.Button1Click(Sender: TObject);
3 var
4 r: TRect;
5 richedit_outputarea: TRect;
6 printresX, printresY: Integer;
7 fmtRange: TFormatRange;
8 begin
9 printer.begindoc;
10 try
11 r := Rect(1000 div 13, 1000 div 13, Round((Printer.PageWidth - 100) / 1.3),
12 Round((Printer.Pageheight - 100) / 1.3));
13 SetMapMode(printer.canvas.handle, MM_ANISOTROPIC);
14 SetWindowExtEx(printer.canvas.handle, GetDeviceCaps(printer.canvas.handle,
15 LOGPIXELSX), GetDeviceCaps(printer.canvas.handle, LOGPIXELSY), nil);
16 SetViewportExtEx(printer.canvas.handle,
17 Round(GetDeviceCaps(printer.canvas.handle,
18 LOGPIXELSX) * 1.3), Round(GetDeviceCaps(printer.canvas.handle,
19 LOGPIXELSY) * 1.3), nil);
20 with Printer.Canvas do
21 begin
22 printresX := Round(GetDeviceCaps(handle, LOGPIXELSX) / 1.3);
23 printresY := Round(GetDeviceCaps(handle, LOGPIXELSY) / 1.3);
24 {Define a rectangle for the rich edit text. The height is set to the maximum.
25 But we need to convert from device units to twips, 1 twip = 1/1440 inch or 1/20
26 point.}
27 richedit_outputarea := Rect(r.left * 1440 div printresX, r.top * 1440 div
28 printresY, r.right * 1440 div printresX, r.bottom * 1440 div printresY);
29 {Tell rich edit to format its text to the printer. First set up data record
30 for message:}
31 fmtRange.hDC := Handle; {printer handle}
32 fmtRange.hdcTarget := Handle; {ditto}
33 fmtRange.rc := richedit_outputarea;
34 fmtRange.rcPage := Rect(0, 0, Printer.PageWidth * 14400 div 13 div printresX,
35 Printer.PageHeight * 14400 div 13 div printresY);
36 fmtRange.chrg.cpMin := 0;
37 fmtRange.chrg.cpMax := richedit1.GetTextLen - 1;
38 {Format the text}
39 richedit1.Perform(EM_FORMATRANGE, 1, Longint(@fmtRange));
40 {Free cached information}
41 richedit1.Perform(EM_FORMATRANGE, 0, 0);
42 end;
43 finally
44 printer.enddoc;
45 end;
46 end;
The richedit1.perform( EM_FORMATRANGE call returns the index of the last character that could be fitted into the passed fmtrange.rc, + 1. So if multiple pages are required one repeats with fmtrange.chrg.cpMin set to this value, until all characters have been printed. Note that the rich edit control strips blanks and linebreaks off the end of the text so the number of characters to output may be smaller than richedit.gettextLen .
|