![]() |
Drucken
Liste der Anhänge anzeigen (Anzahl: 1)
Drucken aus Delphi
Aus Delphi zu drucken ist so einfach, dass es schwierig zu verstehen ist. (Um das zu belegen, braucht man sich nur in der einschlägigen Literatur umzusehen.) Das Objekt Printer Nachdem die Unit Printers in die uses-Klausel der Formular-Unit einer Anwendung aufgenommen ist, steht dieser eine Objekt Printer der Klasse TPrinter zur Verfügung, ohne dass eine Variablen Printer deklariert und ihre Instanz erzeugt werden muss. Hier beginnen mit der Assoziation 'Drucker' zu dem unglücklich gewählten Namen 'Printer' ('PrintJob' hätte falsche Assoziationen vermieden) die Schwierigkeiten. Die Instanzen von TPrinter sind jedoch keine Drucker (beziehen sich auch nicht auf einen Drucker), sondern sind als Objekte anzusehen, die Druckjobs (Druckaufträge) bearbeiten. Ohne eine erste Instanz von TPrinter wäre die Unit Printers sinnlos, daher wird diese gleich beim Einbinden der Unit erzeugt. Mit dem gesetzten Namen 'Printer' wird der Code vereinheitlicht. Die Druckaufträge (Jobs) des Objekts Printer werden mit seinen Methoden bearbeitet. Dazu sind folgende Schritte notwendig: • Auswahl des Druckers Printer.Printers gibt eine Liste der verfügbaren Drucker zurück, aus der mit Printer.PrinterIndex ein Drucker ausgewählt werden kann. Printer.PrinterIndex:= -1 wählt den Standarddrucker. • Setzen der Druckereigenschaften: Papierformat, Ausrichtung Hoch-/Quer, Anzahl der Kopien.... Printer.Orientation:= poPortrait setzt Hochformat, Printer.Orientation:= poLandscape setzt Querformat. • Starten des Druckauftrages mit BeginDoc: Stellt eine leere Printer.Canvas für die erste Seite zur Verfügung. • Beschreiben der Printer.Canvas unter Beachtung der Druckerauflösung. • Optional kann mit NewPage zur nächsten Seite gewechselt werden. Über die fertige Canvas der letzen Seite wird auf einen Stack eine neue angelegt, die anschließend beschrieben werden kann. • Beenden des Druckauftrages mit EndDoc: Schickt den Stapel der Printer.Canvas an den Druckerspoiler. Windows übernimmt das Ausdrucken. Zwischen den Jobs kann der Drucker und die Ausrichtung auf Hoch- bzw. Querformat gewechselt werden. Fehlermeldung 'Der Drucker ist am Drucken', wenn zwischen BeginDoc und EndDoc versucht wird PrinterIndex oder Orientation zu ändern. Fehlermeldung 'Der Drucker ist nicht am Drucken', wenn außerhalb von BeginDoc und EndDoc versucht wird auf die Printer.Canvas zu schreiben. Anmerkung: Indem man 'NewPage;'durch 'EndDoc; BeginDoc;'ersetzt, kann man einen mehrseitigen Druckauftrag in einzelne Druckaufträge für seine Seiten aufteilen. Die Seiten werden dann in natürlicher Folge an den Druckspoiler gegeben. Die Druckerauflösung Die Auflösung eines Druckers übersteigt im allgemeinen die Auflösung eines Bildschirmes. Sie ist von Drucker zu Drucker verschieden und kann für den gleichen Drucker (abhängig vom Druckertreiber) verschieden sein. Verwenden Sie keine standardisierte Auflösung für Ihren Drucker, das kann bei einem Wechsel des Druckers oder Druckertreibers die unangenehme Folge haben, dass Sie alle Ihre Routinen zum Drucken überarbeiten müssen! Man kann die Druckerauflösung auf Millimeter des Papierformates und auf Pixel des Bildschirms beziehen. Der Bezug auf Millimeter des Papiers ist für Größen bequem, die keine Entsprechung auf dem Bildschirm haben: z. B. linker und oberer Rand: Den Maßstab m (Pixel/mm) ermittelt man (für DIN A4 im Hochformat) nach Wahl des Druckers mit
Delphi-Quellcode:
oder
m:= Printer.PageHeight/297 // Druckerauflösung Pixel/mm
Delphi-Quellcode:
und setzt z.B. die Position für einen linken Rand von 20mm mit
m:= Printer.PageWidth/205; // Druckerauflösung Pixel/mm
Delphi-Quellcode:
Bezug auf Pixel des Bildschirms ist notwendig für Größen, die in Bildschirmpixeln gegeben sind, wie z.B. die Breite von Spalten eines StringGrid. Den Maßstab ms (Druckerpixel/Bildschirmpixel) ermittelt man nach Wahl des Druckers und kann anschließend z.B. Tabulatoren für die Ausgabe der Zeilen eines StringGrid setzen:
LRand:= Round(m*20);
Delphi-Quellcode:
mit denen man eine Zeile des StringGrid drucken kann
ms:= Printer.PageWidth/Screen.Width; R[0]:= Round(m*lr); // Tabulatoren setzen
for i:= 0 to StrGrid.ColCount-1 do R[i+1]:= R[i] + Round(ms*StrGrid.ColWidths[i]);
Delphi-Quellcode:
Mehrere Druckjobs
for k:= 0 to StrGrid.ColCount-1 do
TextOut(R[k], h, StrGrid.Cells[k, i]); Um mehrere Druckjobs gleichzeitig zu bearbeiten, sind weitere Instanzen von TPrinter notwendig,. Sie werden wie üblich nach Deklaration einer Variablen Printer2: TPrinter; mit dem Construktor von TPrinter angelegt: Printer2:= TPrinter.Create; Mit Printer.BeginDoc; und Printer2.BeginDoc werden zwei verschiedene Canvas erzeugt, die in beliebiger Folge beschrieben werden können und jederzeit mit Printer.EndDoc bzw. Printer2.EndDoc an den entsprechenden Druckerspoiler geschickt werden können. Den Druckjobs können verschiedene aber auch der gleiche Drucker zugeordnet sein. Zwei Druckjobs sind Beispielhaft, wenn in beliebiger Folge Koeffizienten einer Approximations-Funktion (einspaltig) und Wertetabellen (mehrsoaltig) gedruckt werden sollen. Hinweis: Beim Schließen einer Anwendung gibt Delphi eine von Printer nicht geschlossene Druckseite aus, für weitere Instanzen von TPrinter muss das die Anwendung selbst übernehmen, wenn keine Druckseiten verloren gehen sollen. Für die Verwendung von mehreren Druckjobs habe ich ein Demo gepostet. |
Re: Drucken
ich üwrd ja eher mit
GetDeviceCaps(Printer.Handle, LOGPIXELSX) / 2.54 die Pixel in mm unabhängig von der Papiergröße auslesen. Alternaiv mit Printer.font.pixelsperinch / 2.54 (analog die Umrechnung für die Verhältnisse. Und funktioniert das mit Screen.width bei mehreren Monitoren, da muss doch der Desktop genommen werden oder nicht?) |
Re: Drucken
Ja, ich glaube ja, das
Delphi-Quellcode:
nicht sehr universell auf alle Druckerauflösungen passt. Bei einem 300dpi Drucken sollte oben etwa die Breite in Zoll rauskommen (HP hat z.B. oft nur 297dpi), aber nicht mm?
m := Printer.PageHeight/297
Ganz praktisch ist auch
Delphi-Quellcode:
getDeviceCaps(Printer.Handle,HORZSIZE); // (Bedruckbare Breite in mm)
getDeviceCaps(Printer.Handle,VERTSIZE); // (Bedruckbare Höhe in mm) |
Re: Drucken
Hi Satty67
HORZSIZE usw kante ich bisher nicht. Aber bei m := Printer.PageHeight/297 bei DinA4 könnte schon immer in mm rauskommen undabhängig von der DPI. Da bei fester Seitengröße schon PageHeight abhängig von der DPI ist. |
Re: Drucken
Ok, es sind mm, hatte nur schnell den Wert verglichen und eine Abweichung. Deshalb mein falscher Schnellschuss mit Zoll.
Die Abweichung liegt bei mir so vor:
Delphi-Quellcode:
Eine andere Formel gibt bei mir aber 23.62 aus :gruebel:
Printer.PageHeight/297 = 22.55
Ok, gefunden (Exe hatte ich, nur der Source-Code war versteckt)
Delphi-Quellcode:
Welcher Wert bzw. welche Berechnung ist jetzt richtig?
var
i : Integer; e : Extended; begin i := GetDeviceCaps(Printer.Handle,PHYSICALWIDTH); // = 4960 e := i / 210; // = 23,62 |
Re: Drucken
Ich würds generell nicht über feste Werte machen. Von daher ist es eigentlich egal ob
Printer.PageHeight/297 das Richtige Ergebnis liefert oder nicht. -> Es sollte einfach so nicht gemacht werden. (siehe deine Lösung) |
DP-Maintenance
Dieses Thema wurde von "TBx" von "Neuen Beitrag zur Code-Library hinzufügen" nach "Tutorials und Kurse" verschoben.
Hat doch mehr Tutorial-Charakter |
Re: Drucken
"brechi" schreibt:
Zitat:
Bei der Umstellung meines Laserdruckerrs vom HP LP IIIplus auf den HP LaserJet P1005 hatte ich die Druckroutienen in allen meinen Delphi-Projekten umzustellen (Scheißarbeit). Das geschah mit m:= Pagewidth/205. Nach der Umstellung waren die Ausdrucke des HP LaserJet P1005 und des DescJet 710C sichtig skaliert. |
Re: Drucken
Das Problem ist doch eher, dass die Funktion dannnicht bei anderen größen (und z.B: Queryformat) funktioniert.
Da kann man dann auch Printer.Font.PixelPerInch nehmen (/2.54) ist auch kein WinAPI sollte aber dennoch bei jeder größe funktionieren. (Obwohl die WinAPI wohl das beste wäre, alles andere ist nur bisl durmrumgebaut) |
Re: Drucken
Warum setzt ihr den Mapmode nicht auf LOMETRIC? Dann habt ihr 10/Millimeter.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz