Difference between revisions of "Using the printer/de"

From Lazarus wiki
Jump to navigationJump to search
m (translation continued)
m (Fixed syntax highlighting; deleted category included in page template)
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
{{Using the printer}}
 
{{Using the printer}}
 
+
<br>
 +
Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].<br>
 +
<br>
 +
__TOC__
 +
<br>
 
==Einführung==
 
==Einführung==
 
Drucken ist einfach in Lazarus/FreePascal. Dennoch sollten Sie einige erforderliche Schritte beachten. Wir fangen mit den ersten einfachen Schritten an. Anschließend können Sie dem Weg zu gehobenen Drucktechniken folgen. Dieser Artikel beschreibt die dazu erforderlichen Schritte, die von verschiedenen Forumsseiten und Beispielen zusammengetragen wurden. Nach den grundlegenden Schritten werden wir etwas Text ausdrucken. Zuletzt gibt es noch einen Tipp für das etwas fortgeschrittenere Ausdrucken.
 
Drucken ist einfach in Lazarus/FreePascal. Dennoch sollten Sie einige erforderliche Schritte beachten. Wir fangen mit den ersten einfachen Schritten an. Anschließend können Sie dem Weg zu gehobenen Drucktechniken folgen. Dieser Artikel beschreibt die dazu erforderlichen Schritte, die von verschiedenen Forumsseiten und Beispielen zusammengetragen wurden. Nach den grundlegenden Schritten werden wir etwas Text ausdrucken. Zuletzt gibt es noch einen Tipp für das etwas fortgeschrittenere Ausdrucken.
Line 23: Line 27:
 
===Fügen Sie die Printers - Unit zum uses-Abschnitt Ihrer Unit hinzu===
 
===Fügen Sie die Printers - Unit zum uses-Abschnitt Ihrer Unit hinzu===
 
Dieser Schritt ist einfach und das Ergebnis sollte so ähnlich aussehen:
 
Dieser Schritt ist einfach und das Ergebnis sollte so ähnlich aussehen:
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang=pascal>
 
unit MainUnit;
 
unit MainUnit;
 
   
 
   
Line 37: Line 42:
 
Nehmen wir an, Sie wollen zum Ausdrucken eines Textes eine Schaltfläche verwenden. Legen Sie auf Ihr Form eine Schaltfläche namens '''PrintBtn''' und bearbeiten Sie das '''OnClick'''-Ereignis zu Folgendem:
 
Nehmen wir an, Sie wollen zum Ausdrucken eines Textes eine Schaltfläche verwenden. Legen Sie auf Ihr Form eine Schaltfläche namens '''PrintBtn''' und bearbeiten Sie das '''OnClick'''-Ereignis zu Folgendem:
  
<syntaxhighlight>
+
<syntaxhighlight lang=pascal>
 
procedure TForm1.PrintBtnClick(Sender: TObject);
 
procedure TForm1.PrintBtnClick(Sender: TObject);
 
const
 
const
Line 67: Line 72:
  
 
Von ''begin'' bis zum ''end;'' geschieht Folgendes:
 
Von ''begin'' bis zum ''end;'' geschieht Folgendes:
* With ''Printer.BeginDoc'' you start printing - however, nothing is sent to the printer until you finish with ''Printer.EndDoc;''.
+
* Mit ''Printer.BeginDoc'' starten Sie das Drucken - trotzdem wird noch nichts zum Drucker gesendet bis Sie mit ''Printer.EndDoc;'' abschließen.
* The printer uses a Canvas to draw the output on. It is this drawing that ends up on the printed page. ''Canvas.Font'' is the font object used for the output canvas. That is, the ''TextOut'' call we use later will output text using the settings of the font object of that moment.
+
* Das Druckerobjekt benutzt eine Leinwand ''Canvas'' auf die die Ausgabe gezeichnet wird. Diese Zeichnung landet zuletzt auf der gedruckten Seite. ''Canvas.Font'' ist das Fontobjekt der Ausgabeleinwand. Der nachfolgende Aufruf von ''TextOut'' nimmt zur Textausgabe die jetzt getroffenen Einstellungen des Fontobjektes.
* Everything you draw on the canvas must be positioned using coordinates. So, we calculate a ''LineHeight'' to position text vertically. You could do the same for the horizontal position, which I left here to be ''LEFTMARGIN''.
+
* Alles, was Sie auf die Leinwand zeichnen, muss mittels Koordinaten positioniert werden. Also, berechnen wir eine Zeilenhöhe ''LineHeight'' zum vertikalen Positionieren. Sie könnte das auch für die horizontale Position machen, ich hab es hier aber bei der Einstellung ''LEFTMARGIN'' belassen.
* The text is drawn with the ''TextOut'' call.
+
* Jetz wird der Text mit dem Aufruf ''TextOut'' gezeichnet.
* This magnificent result is sent to the printer by ''Printer.EndDoc''.
+
* Das überwältigende Ergebnis wird mittels ''Printer.EndDoc'' an den Drucker geschickt.
  
In some forums it is suggested that the use of ''PrintDialog'' (the printer selection dialog) is required for good functioning, but I did not find this to be true (any more).
+
In einigen Foren wird behauptet, dass ''PrintDialog'' (der Druckerauswahl-Dialog) für ein gutes Funktionien nötig ist. Ich konnte das nicht (mehr) nachvollziehen.
  
 
==Die nächsten Schritte==
 
==Die nächsten Schritte==
After the above basic steps, you can do the next steps. I leave it to the reader to try:
+
Nach diesen grundlegenden Schritten könnten Sie als weitere Schritte Folgendes ausprobieren:
* Make drawings on the paper.
+
* Machen Sie auf dem Papier Zeichnungen.
* Format text nicely.
+
* Formatieren Sie den Text ansprechender.
* Select another printer and compare results.
+
* Wählen Sie einen anderen Drucker und vergleichen Sie die Ergebnisse.
  
In the Lazarus distribution there is an example project that uses Raw printing to the printer. You can find this example with the following location $(lazarusdir)\components\printers\samples\rawmode\rawmodetest.lpi.
+
In der Lazarus-Distribution gibt es ein Beipielsprojekt, das den Drucker im Raw - Modus ansteuert. Sie finden dieses Beispiel im Ordner $(lazarusdir)\components\printers\samples\rawmode\rawmodetest.lpi.
Another sample shows how to select another printer: $(lazarusdir)\components\printers\samples\dialogs\selectprinter.lpi.
+
Ein weiteres Beispiel erläutert die Auswahl eines Druckers: $(lazarusdir)\components\printers\samples\dialogs\selectprinter.lpi.
  
==Advanced steps: printing controls==
+
==Gehobene Schritte: Drucksteuerung==
The printer object primarily allows you to draw on a canvas and send that canvas image to the printer. If we continue on the path shown above, then you would use the printer's canvas methods to draw text, ellipses, diamonds and what not.  
+
Das Druckerobjekt ermöglicht primär das Zeichnen auf eine Leinwand und das Senden dieses Bildes an den Drucker. Wenn wir auf diesem oben gezeigten Weg weiter gingen, würden wir die Methoden der Druckerleinwand zum Zeichnen von Text, Ellipsen, Kästchen u.s.w. einsetzen.  
  
However, this can hardly be interesting to any serious programmer. You are working on a more perfect CAD program or yet another image file sorter and want to print the wonderful result of your program to your printer. Trying to translate the perfect picture into canvas method calls is not the way: you already have the picture.
+
Für einen ernsthaften Programmierer ist dies wenig ansprechend. Sie arbeiten an einem besseren CAD-Programm oder einer weiteren Bilderverwaltung und möchten einen Ausdruck von Ihrem Programm an Ihren Drucker senden? Der Versuch, das perfekte Bild in Methodenaufrufe der Leinwand umzusetzen, ist nicht der Weg: Sie haben das Bild nämlich schon.
  
Each and every control you put on a form, also draws a picture on a TCanvas object just like the printer. We can use that to bring the picture from the screen to the printer.  
+
Jedes einzelne Steuerelement das auf einem Form liegt, liefert auch ein Bild auf einem TCanvas - Objekt genau wie beim Drucken. Dies nutzen wir aus, um das Bild vom Bildschirm zum Drucker zu bringen.  
  
Imagine you are going to make a preview program. You create a form and on this form you put a TPanel. This panel will provide the nice grayish background of the preview. On the panel, you put another TPanel object called ''page''. This ''page'' will be white and represents the paper. You can nicely size the page.  
+
Angenommen Sie erstellen ein Vorschaubild. Sie erzeugen ein Form und darauf legen Sie ein TPanel ab. Dieses Panel hat einen leicht grauen Hintergrund für die Vorschau. Auf das Panel legen Sie ein weiteres TPanel - Objekt namens ''Seite'' (page). Diese ''Seite'' wird weiß und stellt das Papier dar. Sie können leicht die Größe der Seite anpassen.  
  
On this page we put a TShape object, for example a nice red, rounded rectangle. Now try the following in the '''PrintBtnClick''' event method:
+
Auf diese Seite geben wir ein TShape - Objekt, bspw. ein nettes rotes, abgerundetes Rechteck. Versuchen Sie jetzt Folgendes in der Ereignismethode '''PrintBtnClick''':
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang=pascal>
 
MyPrinter.BeginDoc;
 
MyPrinter.BeginDoc;
 
   page.PaintTo(myPrinter.Canvas, 0, 0);
 
   page.PaintTo(myPrinter.Canvas, 0, 0);
Line 100: Line 106:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
What happens:
+
Was passiert:
* ''BeginDoc'' starts the printing (but nothing is sent yet).
+
* ''BeginDoc'' startet die Druckaufbereitung (aber es wird noch nichts gesendet).
* ''page.PaintTo'' sends the output of our TPanel object that represents the page to the canvas of the printer. Note the following:
+
* ''page.PaintTo'' schickt die Ausgaben unseres TPanel - Objekts an die Druckerleinwand. Beachten Sie:
*# You can use the PaintTo method of any control in the control hierarchy. You could also send the output of the whole window to the printer if you want to.
+
*# Sie können die Methode PaintTo jedes beliebigen Steuerelements aus der Hierachie verwenden. Sie könnten ebenso die Ausgabe des ganzen Fensters an den Drucker senden.
*# You can send the output of any control with a PaintTo method to the printer, so you can be creative. To send the output of your image sorter to the printer you may send the output of the TImage to the printer.
+
*# Jedes Steuerelement mit einer PaintTo - Methode bietet sich an, also seien Sie kreativ. Für die Ausgabe Ihrer Bildverwaltung eignet sich ein TImage.
*# TCanvas also has a method to copy rectangles from another canvas. However, you can only do that if an object really draws to a canvas. I think most controls rely on containers to provide a real canvas, so you cannot copy rectangles from just any control. At least, it didn't work for me.
+
*# TCanvas besitzt auch eine Methode zum Kopieren rechteckiger Bereiche zu einer anderen Leinwand. Allerdings klappt das nur, wenn ein Objekt wirklich auf eine Leinwand zeichnet. Viele Steuerelemente greifen aber über Container auf eine Leinwand zu, dann geht das Kopieren nicht. Zumindest hat es bei mir nicht funktioniert.
*# Make sure the control you want to paint to the printer is visible. If the control is not visible, nothing will be painted not even to the printer.
+
*# Versichern Sie sich, dass das SteuerelementMake sichtbar ist. Unsichtbare Elemente werden nicht gezeichnet, nicht einmal zum Drucker.
* ''EndDoc'' sends the drawing to the printer.
+
* ''EndDoc'' sendet die Zeichnung zum Drucker.
  
 
==Und weiter geht's: Änderung der Größe==
 
==Und weiter geht's: Änderung der Größe==
The printer uses a lot more pixels per inch on paper than the monitor uses pixels per inch on the screen. As a result, the output that is redirected from the screen to the printer ends up rather smallish on the paper. Scaling and controlling the layout is important for good looking output. It would be nice if you can have an exact sized copy of what you see on the screen.
+
Der Drucker hat eine wesentlich höhere Auflösung (Pixel pro Zoll) als ein Bildschirm. Deshalb resultiert die vom Bildschirm zum Drucker umgeleitete Ausgabe als ziemlich winziger Ausdruck auf dem Papier. Für eine gut aussehende Ausgabe sind darum Skalierung und Layoutkontrolle wichtig. Es wäre toll, wenn man eine exakt gleich große Kopie des Bildschirms  ach auf Papier haben könnte.
  
For the moment we are not striving for the ideal, just for the idea. As said before, controls do not have their own canvas but rely on the canvas of a container or owner. However, there are components that have their own canvas. I chose TBitMap and then it works as follows.
+
Kümmern wir uns im Augenblick nicht um dieses Ideal, eher um die Idee dahinter. Wie bereits erwähnt, haben Steuerelemente keine eigene Leinwand, sondern verlassen sich auf die Leinwand eines Containers oder ihres Owners. Allerdings haben manche Komponenten auch ihre eigene Leinwand. Ich wähle TBitMap und dort klappt es wie folgt.
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang=pascal>
 
procedure TForm1.PrintBtnClick(Sender: TObject);
 
procedure TForm1.PrintBtnClick(Sender: TObject);
 
var
 
var
Line 137: Line 144:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
For this to work, do not use the ''Windows'' unit. The ''Windows'' unit has other definitions for '''Rect'''. What you see in the example is the following:
+
Damit das funktioniert dürfen Sie nicht die Unit ''Windows'' verwenden. Die ''Windows'' - Unit hat andere Definitionen für '''Rect'''. Was Sie im Beispiel sehen, ist dies:
* A bitmap is created and made the same size as the page control.
+
* Eine Bitmap wird erzeugt mit gleicher Größe wie beim Page-Steuerelement.
* To avoid the border to print, the '''BorderStyle''' of the page is switched off before painting it to the bitmap and set back to its old value afterwards.
+
* Sie vermeiden den Ausdruck des Randes, indem Sie die Eigenschaft '''BorderStyle''' der Seite vor dem Drucken zur Bitmap abschalten und hinterher auf die alten Werte zurücksetzen.
* Then printing is started and the ''BitMap'' canvas content is copied to the printer canvas.
+
* Das Drucken wird gestartet und der Leinwandinhalt der ''BitMap'' wir auf die Druckerleinwand kopiert.
 +
 
 +
Aber beachten Sie, dass die Seite ''page'' in diesem Vorgang vergrößert wird. Die Papiergröße '''Printer.papersize''' ist erheblich größer als die Bitmap, aber der Kopiervorgang füllt das Zielrechteck gut aus. Um das zu erreichen, müssen wir sicherstellen, dass die Dimensionen von ''page'' und die des Papiers das selbe Verhältnis aufweisen. Sie sehen sicher, wie das geschieht.
  
But notice one thing, in the process ''page'' is magnified. The '''Printer.papersize''' is considerably bigger than the the size of the bitmap, but the copy process fills the destination rectangle nicely. So, when we want to do this, we must make sure that the ''page'' dimensions have the same ratio as the paper dimension. You can figure out how to do it.
+
Ein Problem dabei ist, dass der Ausdruck auf dem Papier "pixelig" wirkt. Wie gesagt, es ist nicht ideal, aber es zeigt das Prinzip. Steuerelemente haben keine eigene Leinwand; um sie auszudrucken zeichnen wir sie zuerst auf ein Objekt mit eigener Leinwand: eine TBitMap.
 +
Da Sie jetzt also wissen, wie das geht, können Sie einen Weg herausfinden, um richtige Kunstwerke oder Dokumente herzustellen. Dazu brauchen Sie Objekte, die sich selbst in ein TPanel mit niederer Auflösung, aber auch in ein TBitMap mit hoher Auflösung zeichnen können. Aber das ist schon Stoff für einen weiteren Artikel.
  
A problem with this way of working is of course that the pixels of the screen will show on the printed paper. As said, it is not ideal but it shows a principle. Controls do not have their own canvas; to print controls we first paint them on an object that does have its own canvas: the TBitMap.
 
Now you know how it works, you can figure out a way to create fine artwork or documents. This will need objects that draw themselves properly in a TPanel with low resolution, but also on a TBitMap with high resolution. But, that is food for another article.
 
  
[[Category:Tutorials]]
+
Übersetzt von: --[[User:Billyraybones|billyraybones]] 20:10, 21 September 2013 (CEST)
[[Category:Printing]]
 
[[Category:Lazarus]]
 
[[Category:Hardware]]
 

Latest revision as of 08:21, 4 March 2020

Deutsch (de) English (en) español (es) 日本語 (ja) polski (pl) 中文(中国大陆)‎ (zh_CN)

Zurück zu den Zusätzlichen Informationen.


Einführung

Drucken ist einfach in Lazarus/FreePascal. Dennoch sollten Sie einige erforderliche Schritte beachten. Wir fangen mit den ersten einfachen Schritten an. Anschließend können Sie dem Weg zu gehobenen Drucktechniken folgen. Dieser Artikel beschreibt die dazu erforderlichen Schritte, die von verschiedenen Forumsseiten und Beispielen zusammengetragen wurden. Nach den grundlegenden Schritten werden wir etwas Text ausdrucken. Zuletzt gibt es noch einen Tipp für das etwas fortgeschrittenere Ausdrucken.

Die grundlegenden Schritte

Um Drucker zu benutzen, müssen Sie Folgendes beachten:

  1. Fügen Sie das Printer4Lazarus - Package zu Ihren Projektanforderungen hinzu.
  2. Fügen Sie die Printers - Unit zum uses-Abschnitt Ihrer Unit hinzu.
  3. Verwenden Sie das existierende Printer - Objekt.

Fügen Sie das Printer4Lazarus - Package zu Ihren Projektanforderungen hinzu

Das Printer4Lazarus - Package legt einen Drucker als Grundlage fest und bietet somit plattformunabhängiges Ausdrucken. Deshalb kann folgendes Verfahren auf verschiedenen Plattformen eingesetzt werden.

Führen Sie in der Lazarus IDE folgende Schritte durch:

  1. Klicken Sie im Menü Projekt auf Projektinspektor .... Es wird ein Fenster mit einer Baumstruktur angezeigt. Einer der Zweige lautet Benötigte Packages. Als Standard wird von Benötigte Packages das LCL - Package angezeigt.
  2. Klicken Sie die Schaltfläche Hinzufügen, den Knopf mit dem Pluszeichen am oberen Fensterrand.
  3. Öffnen Sie die Seite Neue Anforderung.
  4. Aus dem Listenfeld Package-Name wählen Sie Printer4Lazarus aus.
  5. Klicken Sie auf Neue Abhängigkeit erzeugen.
  6. Printer4Lazarus wird jetzt im Zweig Benötigte Packages angezeigt.

Fügen Sie die Printers - Unit zum uses-Abschnitt Ihrer Unit hinzu

Dieser Schritt ist einfach und das Ergebnis sollte so ähnlich aussehen:

unit MainUnit;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, Forms, Printers;

Verwenden Sie das existierende Printer - Objekt

Nehmen wir an, Sie wollen zum Ausdrucken eines Textes eine Schaltfläche verwenden. Legen Sie auf Ihr Form eine Schaltfläche namens PrintBtn und bearbeiten Sie das OnClick-Ereignis zu Folgendem:

procedure TForm1.PrintBtnClick(Sender: TObject);
const
  LEFTMARGIN = 100;
  HEADLINE = 'I Printed My Very First Text On ';
var
  YPos, LineHeight, VerticalMargin: Integer;
  SuccessString: String;
begin
  with Printer do
  try
    BeginDoc;
    Canvas.Font.Name := 'Courier New';
    Canvas.Font.Size := 10;
    Canvas.Font.Color := clBlack;
    LineHeight := Round(1.2 * Abs(Canvas.TextHeight('I')));
    VerticalMargin := 4 * LineHeight;
    // There we go
    YPos := VerticalMargin;
    SuccessString := HEADLINE + DateTimeToStr(Now);   
    Canvas.TextOut(LEFTMARGIN, YPos, SuccessString);
  finally
    EndDoc;
  end;
end;

Habe ich grundlegend und einfach geschrieben? Das obige Beispiel ist schon irgendwie komplex. Neben der reinen Textausgabe stellt es auch ein Beispiel dar, wie Sie den Text formatieren können.

Von begin bis zum end; geschieht Folgendes:

  • Mit Printer.BeginDoc starten Sie das Drucken - trotzdem wird noch nichts zum Drucker gesendet bis Sie mit Printer.EndDoc; abschließen.
  • Das Druckerobjekt benutzt eine Leinwand Canvas auf die die Ausgabe gezeichnet wird. Diese Zeichnung landet zuletzt auf der gedruckten Seite. Canvas.Font ist das Fontobjekt der Ausgabeleinwand. Der nachfolgende Aufruf von TextOut nimmt zur Textausgabe die jetzt getroffenen Einstellungen des Fontobjektes.
  • Alles, was Sie auf die Leinwand zeichnen, muss mittels Koordinaten positioniert werden. Also, berechnen wir eine Zeilenhöhe LineHeight zum vertikalen Positionieren. Sie könnte das auch für die horizontale Position machen, ich hab es hier aber bei der Einstellung LEFTMARGIN belassen.
  • Jetz wird der Text mit dem Aufruf TextOut gezeichnet.
  • Das überwältigende Ergebnis wird mittels Printer.EndDoc an den Drucker geschickt.

In einigen Foren wird behauptet, dass PrintDialog (der Druckerauswahl-Dialog) für ein gutes Funktionien nötig ist. Ich konnte das nicht (mehr) nachvollziehen.

Die nächsten Schritte

Nach diesen grundlegenden Schritten könnten Sie als weitere Schritte Folgendes ausprobieren:

  • Machen Sie auf dem Papier Zeichnungen.
  • Formatieren Sie den Text ansprechender.
  • Wählen Sie einen anderen Drucker und vergleichen Sie die Ergebnisse.

In der Lazarus-Distribution gibt es ein Beipielsprojekt, das den Drucker im Raw - Modus ansteuert. Sie finden dieses Beispiel im Ordner $(lazarusdir)\components\printers\samples\rawmode\rawmodetest.lpi. Ein weiteres Beispiel erläutert die Auswahl eines Druckers: $(lazarusdir)\components\printers\samples\dialogs\selectprinter.lpi.

Gehobene Schritte: Drucksteuerung

Das Druckerobjekt ermöglicht primär das Zeichnen auf eine Leinwand und das Senden dieses Bildes an den Drucker. Wenn wir auf diesem oben gezeigten Weg weiter gingen, würden wir die Methoden der Druckerleinwand zum Zeichnen von Text, Ellipsen, Kästchen u.s.w. einsetzen.

Für einen ernsthaften Programmierer ist dies wenig ansprechend. Sie arbeiten an einem besseren CAD-Programm oder einer weiteren Bilderverwaltung und möchten einen Ausdruck von Ihrem Programm an Ihren Drucker senden? Der Versuch, das perfekte Bild in Methodenaufrufe der Leinwand umzusetzen, ist nicht der Weg: Sie haben das Bild nämlich schon.

Jedes einzelne Steuerelement das auf einem Form liegt, liefert auch ein Bild auf einem TCanvas - Objekt genau wie beim Drucken. Dies nutzen wir aus, um das Bild vom Bildschirm zum Drucker zu bringen.

Angenommen Sie erstellen ein Vorschaubild. Sie erzeugen ein Form und darauf legen Sie ein TPanel ab. Dieses Panel hat einen leicht grauen Hintergrund für die Vorschau. Auf das Panel legen Sie ein weiteres TPanel - Objekt namens Seite (page). Diese Seite wird weiß und stellt das Papier dar. Sie können leicht die Größe der Seite anpassen.

Auf diese Seite geben wir ein TShape - Objekt, bspw. ein nettes rotes, abgerundetes Rechteck. Versuchen Sie jetzt Folgendes in der Ereignismethode PrintBtnClick:

MyPrinter.BeginDoc;
  page.PaintTo(myPrinter.Canvas, 0, 0);
MyPrinter.EndDoc;

Was passiert:

  • BeginDoc startet die Druckaufbereitung (aber es wird noch nichts gesendet).
  • page.PaintTo schickt die Ausgaben unseres TPanel - Objekts an die Druckerleinwand. Beachten Sie:
    1. Sie können die Methode PaintTo jedes beliebigen Steuerelements aus der Hierachie verwenden. Sie könnten ebenso die Ausgabe des ganzen Fensters an den Drucker senden.
    2. Jedes Steuerelement mit einer PaintTo - Methode bietet sich an, also seien Sie kreativ. Für die Ausgabe Ihrer Bildverwaltung eignet sich ein TImage.
    3. TCanvas besitzt auch eine Methode zum Kopieren rechteckiger Bereiche zu einer anderen Leinwand. Allerdings klappt das nur, wenn ein Objekt wirklich auf eine Leinwand zeichnet. Viele Steuerelemente greifen aber über Container auf eine Leinwand zu, dann geht das Kopieren nicht. Zumindest hat es bei mir nicht funktioniert.
    4. Versichern Sie sich, dass das SteuerelementMake sichtbar ist. Unsichtbare Elemente werden nicht gezeichnet, nicht einmal zum Drucker.
  • EndDoc sendet die Zeichnung zum Drucker.

Und weiter geht's: Änderung der Größe

Der Drucker hat eine wesentlich höhere Auflösung (Pixel pro Zoll) als ein Bildschirm. Deshalb resultiert die vom Bildschirm zum Drucker umgeleitete Ausgabe als ziemlich winziger Ausdruck auf dem Papier. Für eine gut aussehende Ausgabe sind darum Skalierung und Layoutkontrolle wichtig. Es wäre toll, wenn man eine exakt gleich große Kopie des Bildschirms ach auf Papier haben könnte.

Kümmern wir uns im Augenblick nicht um dieses Ideal, eher um die Idee dahinter. Wie bereits erwähnt, haben Steuerelemente keine eigene Leinwand, sondern verlassen sich auf die Leinwand eines Containers oder ihres Owners. Allerdings haben manche Komponenten auch ihre eigene Leinwand. Ich wähle TBitMap und dort klappt es wie folgt.

procedure TForm1.PrintBtnClick(Sender: TObject);
var
  MyPrinter : TPrinter;
  myBitMap : TBitMap;
begin
  myBitMap := TBitMap.Create;
  myBitMap.Width := page.Width;
  myBitMap.Height := page.Height;
  page.BorderStyle:=bsNone;
  page.PaintTo(myBitMap.Canvas, 0, 0);
  page.BorderStyle:=bsSingle;
  //
  MyPrinter := Printer;
  MyPrinter.BeginDoc;
    //page.PaintTo(myPrinter.Canvas, 0, 0);
    //myPrinter.Canvas.Draw(0,0, myBitMap);
    myPrinter.Canvas.CopyRect(Classes.Rect(0, 0, myPrinter.PaperSize.Width, myPrinter.PaperSize.Height),
       myBitMap.Canvas, Classes.Rect(0, 0, myBitMap.Width, myBitMap.Height));
  MyPrinter.EndDoc;
  myBitMap.Free;
end;

Damit das funktioniert dürfen Sie nicht die Unit Windows verwenden. Die Windows - Unit hat andere Definitionen für Rect. Was Sie im Beispiel sehen, ist dies:

  • Eine Bitmap wird erzeugt mit gleicher Größe wie beim Page-Steuerelement.
  • Sie vermeiden den Ausdruck des Randes, indem Sie die Eigenschaft BorderStyle der Seite vor dem Drucken zur Bitmap abschalten und hinterher auf die alten Werte zurücksetzen.
  • Das Drucken wird gestartet und der Leinwandinhalt der BitMap wir auf die Druckerleinwand kopiert.

Aber beachten Sie, dass die Seite page in diesem Vorgang vergrößert wird. Die Papiergröße Printer.papersize ist erheblich größer als die Bitmap, aber der Kopiervorgang füllt das Zielrechteck gut aus. Um das zu erreichen, müssen wir sicherstellen, dass die Dimensionen von page und die des Papiers das selbe Verhältnis aufweisen. Sie sehen sicher, wie das geschieht.

Ein Problem dabei ist, dass der Ausdruck auf dem Papier "pixelig" wirkt. Wie gesagt, es ist nicht ideal, aber es zeigt das Prinzip. Steuerelemente haben keine eigene Leinwand; um sie auszudrucken zeichnen wir sie zuerst auf ein Objekt mit eigener Leinwand: eine TBitMap. Da Sie jetzt also wissen, wie das geht, können Sie einen Weg herausfinden, um richtige Kunstwerke oder Dokumente herzustellen. Dazu brauchen Sie Objekte, die sich selbst in ein TPanel mit niederer Auflösung, aber auch in ein TBitMap mit hoher Auflösung zeichnen können. Aber das ist schon Stoff für einen weiteren Artikel.


Übersetzt von: --billyraybones 20:10, 21 September 2013 (CEST)