Home » Tutorials » Object Pascal/RTL » Drucken

Drucken

Koordinaten-Systeme

Um Änderungen am Koordinatensystem vornehmen zu können, müssen wir auf Win32-API-Befehle zurückgreifen, was die Sache ein wenig komplizierter macht. Diese API-Befehle sind nicht unter Linux verfügbar. Wer also mit Kylix programmiert, muss sich etwas anderes einfallen lassen. Lösungen dazu inkl. einer Komponente, die die Funktionalität der nötigen Win32-API-Befehle bietet, sind im Buch „Kylix – Delphi für Linux“ von Elmar Warken zu finden. Im Tutorial hier beschränken wir uns auf die Umsetzung unter Windows.
Die Folgenden Win32-API-Befehle sind in diesem Zusammenhang interessant:

  • SetViewportOrgEx
  • SetViewportExtEx
  • SetWindowOrgEx
  • SetWindowExtEx
  • SetMapMode
  • GetDeviceCaps

Ausführlich sind all diese Befehle in der Win32 Developer’s Reference (englischsprachige Hilfe, die Delphi beiliegt, im Startmenü „Referenz der Win32-Programmierung“ genannt) beschrieben.

Window – Viewport

Um das dahinterstehende Konzept zu verstehen, muss man wissen, was es mit Window und Viewport auf sich hat. Die o.g. Befehle werden generell bei Abbildungsvorgängen verwendet; das Drucken ist schließlich auch nichts anderes als eine Abbildung von unserer virtuellen Leinwand auf die Druckerausgabe.
Der Viewport bezeichnet die Ausgabefläche, beim Drucken also den Bereich des Blattes, der bedruckt werden soll. Das Window dagegen ist der Bereich unserer virtuellen Leinwand (die größer sein kann als das Blatt Papier), der auf den Viewport gedruckt werden soll. Soll der Ausdruck genau in der Größe erfolgen, wie die Zeichnung auf unserer virtuellen Leinwand ist, also eine 1:1-Abbildung auf das Papier, so müssen Viewport und Window die gleiche Größe haben.
So ist es kein großes Problem, den Inhalt einer Leinwand doppelt so groß auszudrucken – nämlich in dem das Window nur halb so groß gemacht wird wie der Viewport.
Wer das jetzt nicht auf Anhieb verstanden hat, muss nicht verzweifeln. Es folgen noch konkrete Beispiele – zumindest vom Drucken in Originalgröße, was ja wohl auch das häufigste sein wird. Wer anschließend noch vergrößern oder verkleinern will, der kann ja mit obigen Befehlen experimentieren.
Um die Abmwessungen des Windows und des Viewports festzulegen, werden die Befehle SetWindowExtEx und SetViewportExtEx verwendet. Um diese Abmessungen auszulesen gibt es die gleichen Befehle noch in der Form GetWindowExtEx und GetViewportExtEx.
Für Normalfälle reicht das aus. Wer nun auch noch die Ursprungskoordinaten des Windows oder des Viewports verschieben will, der sollte auf SetWindowOrgEx und SetViewportOrgEx zurückgreifen. Ein Beispiel dazu folgt später – beim Drucken über mehrere Seiten.

Abbildungsmodi – Die Maßeinheiten

Wie bereits angesprochen, erfolgt der Ausdruck standardmäßig in der Einheit Pixel, was nicht geräteunabhängig ist und deshalb je nach Einstellungen zu anderen Ergebnissen führt. Mit dem Befehl SetMapMode lässt sich das ändern. Allerdings ändert sich je nach gewählter Einheit auch der Ursprung des Koordinatensystems.

SetMapMode(Printer.Canvas.Handle, MM_LOMETRIC);

Dieser Befehl stellt die Einheiten in 1/10 Millimeter um. Wer noch präziser drucken will, kann auch MM_HIMETRIC für 1/100 Millimeter verwenden. Welche weiteren Konstanten zur Verfügung stehen, ist in der Win32-Hilfe unter SetMapMode zu finden.
Die Umstellung auf Millimeter hat generell den Nachteil, dass sich der Koordinatenursprung links oben befindet und nach unten nicht wie gewohnt die positiven, sondern negative Werte abgetragen werden. Soll also 10 mm (=1 cm) vom oberen und 10 mm vom linken Papierrand der Text „Hallo“ stehen, muss das so aussehen:

Printer.Canvas.TextOut(10, -10, 'Hallo');

Druckerinformationen

Wenn man etwas ausdrucken will, sollte man sich erst über die Möglichkeiten des Druckers informieren. Z.B. ist wichtig, wie groß der bedruckbare Bereich ist (Drucker können in der Regel an keiner Seite bis direkt an den Blattrand drucken); interessant kann auch die eingestellte Druckauflösung (dpi – dots per inch – Punkte pro Zoll) sein. Für die Ermittlung all dieser Geräteinformationen ist GetDeviceCaps zuständig. Dieser Befehl benötigt als ersten Parameter einen Handle auf das Gerät, den wir über Printer.Handle erhalten. Beispiele:

//gibt die horizontale Auflösung zurück:
  dpih:=GetDeviceCaps(Printer.Handle, LOGPIXELSX);
//Blattbreite in Pixeln:
  breite:=GetDeviceCaps(Printer.Handle, HORZRES);
//linker Rand (nicht bedruckbar):
  lrand:=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);

Weitere mögliche Konstanten sind in der Win32-Hilfe unter GetDeviceCaps zu finden.