Mit der folgende Prozedur kann man den Inhalt eines RichEdit-Steuerelements
ganz oder teilweise an beliebige Stellen auf einer Seite ausdrucken.
Der Parameter RichEditHandle ist das Handle des RichEdit-Steuerelements, also z.B RichEdit1.Handle.
Der Parameter PageRect gibt das Rechteck auf der aktuellen Druckseite an,
in das gedruckt werden soll. Die Maßeinheit der Elemente dieses Rechtecks wird über den
folgenden Parameter angegeben.
Der Parameter RectScaling gibt die Maßeinheit von PageRect an,
in Einheiten je 100 Zoll. Einige Konstanten für Twips, Punkte, Millimeter und Druckerpixel
sind im Quelltext definiert. Ist dieser Wert positiv, dann beschreibt das Rechteck absolute
Koordinaten, sonst die Seitenränder.
Beispiele:
PrintRichEditIntoRect(h, Rect(10, 20, 110, 60), PageRect_MM)
Druckt den Text in ein Rechteck, das 1 cm von linken und 2 cm vom oberen Rand entfernt ist
und das 10 cm breit und 4 cm hoch ist.
PrintRichEditIntoRect(h, Rect(25, 20, 25, 20), -PageRect_MM)
Druckt den Text in ein Rechteck mit den Seitenrändern 2,5 cm links und rechts
sowie 2 cm oben und unten.
Der Parameter StartPos ist der Index des ersten zu druckenden
Zeichens, also z.B. RichEdit1.SelStart. Der Wert 0 druck ab dem ersten Zeichen.
Der Parameter EndPos ist der Index des letzten zu druckenden Zeichens,
also z.B. RichEdit1.SelStart + RichEdit1.SelLength.
Der Wert -1 druck alle Zeichen bis zum Ende des Textes.
Der Rückgabewert ist der Index des ersten Zeichens, dass nicht mehr in das
Ausgaberechteck passte und somit nicht mehr gedruckt wurde. So kann man konsekutiv
den Rückgabewert als nächsten Wert für StartPos benutzen, um den
gesamten Text auszudrucken. Über einen Vergleich mit RichEdit1.GetTextLen
kann man erfahren, ob der gesamte Inhalt ausgedruckt werden konnte.
Man sollte die Funktion nicht direkt für den Ausdruck eines einzigen Textes
über viele Seiten benutzen, da durch den Aufruf von
SendMessage(RichEditHandle, EM_FORMATRANGE, 0, 0) die Formatierungsinformationen
jeweils wieder verworfen werden, und das geht auf die Performance. Allerdings kann man den
Text für solche Fälle dennoch sehr gut als Vorlage für eigene Entwicklungen benutzen.
Die Druckerfunktionen Printer.BeginDoc , Printer.EndDoc sowie
ggf. Printer.NewPage muss man selbst aufrufen - aber dadurch kann man z.B. auch den
Inhalt von 7 RichEdit-Steuerelementen zusammen mit einer Grafik auf eine Seite drucken.
Das Beispiel am Ende dieser Seite zeigt dies.
uses
Windows, RichEdit;
const
PageRect_Twips = 144000; // 100 * twips/inch
PageRect_Points = 7200; // 100 * pt/inch
PageRect_MM = 2540; // 100 * mm/inch
PageRect_Printer = 0;
function PrintRichEditIntoRect(RichEditHandle: HWND; const PageRect: TRect;
RectScaling: Integer = PageRect_Printer; StartPos: Integer = 0;
EndPos: Integer = -1): Integer;
var
Range: TFormatRange;
mm, lpx, lpy, pox, poy: Integer;
begin
Range.hdc := Printer.Handle;
Range.hdcTarget := Range.hdc;
// Get printer resolution
lpx := 100 * GetDeviceCaps(Range.hdc, LOGPIXELSX);
lpy := 100 * GetDeviceCaps(Range.hdc, LOGPIXELSY);
// Convert to device coordinates
if RectScaling <> PageRect_Printer then
begin
// Get physical printing offset
pox := GetDeviceCaps(Range.hdc, PHYSICALOFFSETX);
poy := GetDeviceCaps(Range.hdc, PHYSICALOFFSETY);
if RectScaling < 0 then
begin
Range.rc.Left := MulDiv(PageRect.Left, lpx, -RectScaling) - pox;
Range.rc.Top := MulDiv(PageRect.Top, lpy, -RectScaling) - poy;
Range.rc.Right := GetDeviceCaps(Range.hdc, PHYSICALWIDTH) -
MulDiv(PageRect.Right, lpx, -RectScaling);
Range.rc.Bottom := GetDeviceCaps(Range.hdc, PHYSICALHEIGHT) -
MulDiv(PageRect.Bottom, lpy, -RectScaling);
end
else
begin
Range.rc.Left := MulDiv(PageRect.Left, lpx, RectScaling) - pox;
Range.rc.Top := MulDiv(PageRect.Top, lpy, RectScaling) - poy;
Range.rc.Right := MulDiv(PageRect.Right, lpx, RectScaling) - pox;
Range.rc.Bottom := MulDiv(PageRect.Bottom, lpy, RectScaling) - poy;
end;
end
else
Range.rc := PageRect;
// Convert to twips
Range.rc.Left := MulDiv(Range.rc.Left, 144000, lpx);
Range.rc.Top := MulDiv(Range.rc.Top, 144000, lpy);
Range.rc.Right := MulDiv(Range.rc.Right, 144000, lpx);
Range.rc.Bottom := MulDiv(Range.rc.Bottom, 144000, lpy);
Range.rcPage := Range.rc;
Range.chrg.cpMin := StartPos;
Range.chrg.cpMax := EndPos;
mm := SetMapMode(Printer.Handle, MM_TEXT);
try
SendMessage(RichEditHandle, EM_FORMATRANGE, 0, 0);
Result := SendMessage(RichEditHandle, EM_FORMATRANGE, 1, Integer(@Range));
if Result < 0 then
Result := SendMessage(RichEditHandle, WM_GETTEXTLENGTH, 0, 0);
finally
SendMessage(RichEditHandle, EM_FORMATRANGE, 0, 0);
SetMapMode(Printer.Handle, mm);
end;
end;
|
Beispiel
Das folgende Beispiel druckt den Inhalt von RichEdit1 in vier 10 cm große Quadrate in der Reihenfolge links oben, rechts unten, links unten, rechts oben.
procedure TForm1.Print1Click(Sender: TObject);
var
h: THandle;
pp: Integer;
begin
h := RichEdit1.Handle;
Printer.BeginDoc;
try
pp := 0;
pp := PrintRichEditIntoRect(h, Rect( 10, 10, 100, 100), PageRect_MM, pp);
pp := PrintRichEditIntoRect(h, Rect(110, 110, 200, 200), PageRect_MM, pp);
pp := PrintRichEditIntoRect(h, Rect( 10, 110, 100, 200), PageRect_MM, pp);
pp := PrintRichEditIntoRect(h, Rect(110, 10, 200, 100), PageRect_MM, pp);
Printer.EndDoc;
except
Printer.Abort;
raise;
end;
MessageDlg('Ausdruck erfolgte bis Zeichen ' + IntToStr(pp),
mtInformation, [mbOk], 0);
end; |
|