Sign in Join
Wiki copytemporary

Using the printer/de: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Using the printer/de

OldNewLine
1+Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].\
2+
3+==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.
4+
5+## Die grundlegenden Schritte
6+
7+Um Drucker zu benutzen, müssen Sie Folgendes beachten:
8+
9+1. Fügen Sie das Printer4Lazarus - Package zu Ihren Projektanforderungen hinzu.
10+2. Fügen Sie die Printers - Unit zum uses-Abschnitt Ihrer Unit hinzu.
11+3. Verwenden Sie das existierende Printer - Objekt.
12+
13+### Fügen Sie das Printer4Lazarus - Package zu Ihren Projektanforderungen hinzu
14+
15+Das Printer4Lazarus - Package legt einen Drucker als Grundlage fest und bietet somit plattformunabhängiges Ausdrucken. Deshalb kann folgendes Verfahren auf verschiedenen Plattformen eingesetzt werden.
16+
17+Führen Sie in der Lazarus IDE folgende Schritte durch:
18+
19+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.
20+2. Klicken Sie die Schaltfläche **Hinzufügen**, den Knopf mit dem Pluszeichen am oberen Fensterrand.
21+3. Öffnen Sie die Seite **Neue Anforderung**.
22+4. Aus dem Listenfeld **Package-Name** wählen Sie *Printer4Lazarus* aus.
23+5. Klicken Sie auf **Neue Abhängigkeit erzeugen**.
24+6. *Printer4Lazarus* wird jetzt im Zweig *Benötigte Packages* angezeigt.
25+
26+### Fügen Sie die Printers - Unit zum uses-Abschnitt Ihrer Unit hinzu
27+
28+Dieser Schritt ist einfach und das Ergebnis sollte so ähnlich aussehen:
29+
30+``` pascal
31+unit MainUnit;
32+
33+{$mode objfpc}{$H+}
34+
35+interface
36+
37+uses
38+ Classes, SysUtils, Forms, Printers;
39+```
40+
41+### Verwenden Sie das existierende Printer - Objekt
42+
43+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:
44+
45+``` pascal
46+procedure TForm1.PrintBtnClick(Sender: TObject);
47+const
48+ LEFTMARGIN = 100;
49+ HEADLINE = 'I Printed My Very First Text On ';
50+var
51+ YPos, LineHeight, VerticalMargin: Integer;
52+ SuccessString: String;
53+begin
54+ with Printer do
55+ try
56+ BeginDoc;
57+ Canvas.Font.Name := 'Courier New';
58+ Canvas.Font.Size := 10;
59+ Canvas.Font.Color := clBlack;
60+ LineHeight := Round(1.2 * Abs(Canvas.TextHeight('I')));
61+ VerticalMargin := 4 * LineHeight;
62+ // There we go
63+ YPos := VerticalMargin;
64+ SuccessString := HEADLINE + DateTimeToStr(Now);
65+ Canvas.TextOut(LEFTMARGIN, YPos, SuccessString);
66+ finally
67+ EndDoc;
68+ end;
69+end;
70+```
71+
72+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.
73+
74+Von *begin* bis zum *end;* geschieht Folgendes:
75+
76+- Mit *Printer.BeginDoc* starten Sie das Drucken - trotzdem wird noch nichts zum Drucker gesendet bis Sie mit *Printer.EndDoc;* abschließen.
77+- 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.
78+- 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.
79+- Jetz wird der Text mit dem Aufruf *TextOut* gezeichnet.
80+- Das überwältigende Ergebnis wird mittels *Printer.EndDoc* an den Drucker geschickt.
81+
82+In einigen Foren wird behauptet, dass *PrintDialog* (der Druckerauswahl-Dialog) für ein gutes Funktionien nötig ist. Ich konnte das nicht (mehr) nachvollziehen.
83+
84+## Die nächsten Schritte
85+
86+Nach diesen grundlegenden Schritten könnten Sie als weitere Schritte Folgendes ausprobieren:
87+
88+- Machen Sie auf dem Papier Zeichnungen.
89+- Formatieren Sie den Text ansprechender.
90+- Wählen Sie einen anderen Drucker und vergleichen Sie die Ergebnisse.
91+
92+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.
93+
94+## Gehobene Schritte: Drucksteuerung
95+
96+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.
97+
98+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.
99+
100+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.
101+
102+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.
103+
104+Auf diese Seite geben wir ein TShape - Objekt, bspw. ein nettes rotes, abgerundetes Rechteck. Versuchen Sie jetzt Folgendes in der Ereignismethode **PrintBtnClick**:
105+
106+``` pascal
107+MyPrinter.BeginDoc;
108+ page.PaintTo(myPrinter.Canvas, 0, 0);
109+MyPrinter.EndDoc;
110+```
111+
112+Was passiert:
113+
114+- *BeginDoc* startet die Druckaufbereitung (aber es wird noch nichts gesendet).
115+- *page.PaintTo* schickt die Ausgaben unseres TPanel - Objekts an die Druckerleinwand. Beachten Sie:
116+ 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.
117+ 2. Jedes Steuerelement mit einer PaintTo - Methode bietet sich an, also seien Sie kreativ. Für die Ausgabe Ihrer Bildverwaltung eignet sich ein TImage.
118+ 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.
119+ 4. Versichern Sie sich, dass das SteuerelementMake sichtbar ist. Unsichtbare Elemente werden nicht gezeichnet, nicht einmal zum Drucker.
120+- *EndDoc* sendet die Zeichnung zum Drucker.
121+
122+## Und weiter geht's: Änderung der Größe
123+
124+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.
125+
126+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.
127+
128+``` pascal
129+procedure TForm1.PrintBtnClick(Sender: TObject);
130+var
131+ MyPrinter : TPrinter;
132+ myBitMap : TBitMap;
133+begin
134+ myBitMap := TBitMap.Create;
135+ myBitMap.Width := page.Width;
136+ myBitMap.Height := page.Height;
137+ page.BorderStyle:=bsNone;
138+ page.PaintTo(myBitMap.Canvas, 0, 0);
139+ page.BorderStyle:=bsSingle;
140+ //
141+ MyPrinter := Printer;
142+ MyPrinter.BeginDoc;
143+ //page.PaintTo(myPrinter.Canvas, 0, 0);
144+ //myPrinter.Canvas.Draw(0,0, myBitMap);
145+ myPrinter.Canvas.CopyRect(Classes.Rect(0, 0, myPrinter.PaperSize.Width, myPrinter.PaperSize.Height),
146+ myBitMap.Canvas, Classes.Rect(0, 0, myBitMap.Width, myBitMap.Height));
147+ MyPrinter.EndDoc;
148+ myBitMap.Free;
149+end;
150+```
151+
152+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:
153+
154+- Eine Bitmap wird erzeugt mit gleicher Größe wie beim Page-Steuerelement.
155+- 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.
156+- Das Drucken wird gestartet und der Leinwandinhalt der *BitMap* wir auf die Druckerleinwand kopiert.
157+
158+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.
159+
160+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.
161+
162+Übersetzt von: --billyraybones 20:10, 21 September 2013 (CEST)
163+
164+---
165+*From the Free Pascal wiki, page "Using the printer/de", as it stood on 2020-03-04 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history