Thema: Delphi Drucken mit Delphi

Einzelnen Beitrag anzeigen

Larsi

Registriert seit: 10. Feb 2007
2.262 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Drucken mit Delphi

  Alt 3. Apr 2008, 18:11
Ich glaube, er hat nicht Probleme beim generellen Drucken, sondern damit wie er die Grafik ausrichten soll, richtig? Ist bestimmt nicht das ellganteste aber ordne doch alles auf einem Form an mach davon einen Screenshot und drucke diesen!

Ich habe mir das Tutorial bei delphi treff jetzt mal angeguckt und weiß echt nicht was dein Problem ist? Dort steht doch wie man zb Logo und so anordnet!


Mal ein Ausschnitt für alle dies nicht kennen:
Zitat:
Die Leinwand

Zunächst einmal muss man sich vom zeilenorientierten Denken verabschieden. Es ist nicht so wie in einem Textprogramm, dass nach einem Zeilenende automatisch eine neue Zeile angefangen wird, die direkt unter die vorige platziert wird. Sondern Text (und natürlich auch Grafik) wird gezeichnet.

Und das Zeichnen kann man sich wirklich wörtlich vorstellen. Immerhin haben wir auch eine Leinwand (englisch Canvas). Leinwände (TCanvas) kommen bei mehreren Steuerelementen vor, z.B. auch bei der Komponente TPaintbox. Hierbei handelt es sich um den gleichen Typ wie bei der "Druckerleinwand". Es stehen also die gleichen Methoden zum Zeichnen zur Verfügung, die wir uns gleich ansehen werden.

Wir stellen uns also eine Leinwand in Papiergröße vor (wie groß das Papier überhaupt ist, werden wir in einem späteren Schritt ermitteln) und beginnen zu zeichnen.
TPen und TBrush

Bevor wir etwas zeichnen, müssen wir uns einen Stift und einen Pinsel aussuchen. Soll heißen für alle folgenden Zeichenoperationen gelten die aktuellen Pen- und Brush-Einstellungen. Solange, bis diese geändert werden. Der Stift (Pen) wird für Umrisse und Texte verwendet, der Pinsel (Brush) ist für das Ausfüllen zuständig.

Folgende Eigenschaften können dabei verändert werden:
Color

Das wichtigste ist wohl die Farbe. Als Zuweisung sind hier alle Delphi-Farbkonstanten (z.B. clBlack für schwarz) möglich sowie generell alles vom Typ TColor (s. VCL-Hilfe).
Um die Füllfarbe (also Brush) auf blau zu setzen, wäre folgender Code nötig:

Canvas.Brush.Color:=clBlue;
Style

Die Eigenschaft Style gibt es zwar sowohl für Pen als auch für Brush; jedoch ist die eine vom Typ TPenStyle, die andere vom Typ TBrushStyle.

Bei Brush sind folgende Werte möglich: bsSolid, bsClear, bsHorizontal, bsVertical, bsFDiagonal, bsBDiagonal, bsCross, bsDiagCross - sie beschreiben einfach die Art des Füllens. bsSolid füllt Elemente durchgehend mit der in Color angegebenen Farbe. Bei bsClear passiert nichts (durchsichtige Farbe), bei den restlichen Werten erhält man gestreifte Muster.

Bei Pen sind folgende Werte möglich: psSolid, psDash, psDot, psDashDot, psDashDotDot, psClear, psInsideFrame - hier wird also die Art der Linie festgelegt, ob durchgehend oder gestrichelt.
Width

Bei Linien kann natürlich noch eine Dicke angegeben werden. Das geschieht über die Eigenschaft Width. Bei Brush ist diese Eigenschaft (logischerweise) nicht zu finden.
Was ist nun mit TCanvas alles möglich?

Folgende Methoden sollen nur exemplarisch für die Möglichkeiten von TCanvas, der Leinwand, stehen. Weitere sind in der VCL-Hilfe unter TCanvas zu finden.

Alle Zeichenelemente werden mit den gerade aktuellen Einstellungen von Brush und Pen gezeichnet.
MoveTo

Eine wichtige Methode ist MoveTo. Sie bewegt den Zeichenstift (ohne zu zeichnen) zu einer bestimmten Position, die durch x und y angegeben wird. An dieser Stelle wird dann die folgende Grafioperation durchgeführt. Z.B. die Methode LineTo, der beim Aufruf nur die Zielkoordinaten übergeben werden.
Ellipse

Wer einen Kreis zeichnen will, sollte bedenken, dass ein Kreis nur eine spezielle Ellipse ist. Um eine Ellipse zu zeichnen, werden die Maße des umgebenden Rechtecks angegeben.
Polygon

Das Polygon wird durch ein Array von Punkten (x-y-Werten) definiert.
TextOut

Neben grafischen Gebilden lässt sich auch Text ausgeben. Der Methode TextOut werden dabei die Startkoordinaten und der zu zeichnende Text mitgegeben.

Vorher sollten Schriftart, -farbe, und -stil festgelegt werden. Das geschieht über die Eigenschaft Font von Canvas, z.B.

Canvas.Font.Name:='Arial';
Canvas.Font.Color:=clBlack;
Canvas.Font.Style:=[fsBold]; //normaler Stil wäre Style:=[]
Canvas.Font.Size:=10; //in pt

Um dieses Ganze jetzt auch praktisch anwenden zu können, ist natürlich noch eine konkrete Leinwand nötig, nämlich die "Drucker-Leinwand", die in der Unit Printers verfügbar ist. Dazu mehr im nächsten Abschnitt.
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.
Steht doch alles drinnen!
Ein Tag ohne Delphi ist ein verlorener Tag!

Homepage zu meinem neuen Programm: StreamZ
  Mit Zitat antworten Zitat