Entwickler-Ecke
Sonstiges (Delphi) - Präziser Druck auf beliebigem Windows-Drucker ...
georgfischerx - Mi 18.06.03 18:12
Titel: Präziser Druck auf beliebigem Windows-Drucker ...
Hallo allerseits,
ich habe das Problem, dass ich eine A4-Seite mit Texten und kleinen Graphiken sehr präzise an den richtigen Ort drucken sollte - und dies absolut druckerunabhängig auf 0.5 mm genau. WinWord kann das.
Mein Programm, das Printer.Canvas.TextOut etc. benützt, kann das aber nicht. Es kommt nicht auf genau dasselbe hinaus, ob auf einen HP-Laserjet 6MP oder Lexmark Optra M gedruckt wird. Kleine Abweichungen sind immer da.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
| If FrmMain.DlgPrint.Execute Then Begin With Printer Do Begin Orientation := poPortrait; BeginDoc;
Long := Printer.Canvas.Font.PixelsPerInch; Frac := Long / 600 + 0.0000001;
Koordinat[1] := Trunc(800*Frac); Koordinat[2] := Trunc(800*Frac); Koordinat[3] := Trunc((Bmp.Width + 800) * Frac); Koordinat[4] := Trunc((Bmp.Height + 800)* Frac);
MyRect := Rect(Koordinat[1], Koordinat[2], Koordinat[3], Koordinat[4]); Canvas.StretchDraw(MyRect, Bmp);
StringX[1] := ' Katalog '; StringX[2] := ' Kassettendienst ';
StringX[3] := ' Die Kassetten in diesem Katalog '; StringX[4] := ' sind nicht für den Leihdienst be- '; StringX[5] := ' stimmt. Sie können zum Stückpreis '; StringX[6] := ' von Fr. 8.-- (inkl. Porto und Ver- '; StringX[7] := ' packung) bezogen werden. '; StringX[8] := ' Bitte beiliegende Bestellkarte (letzte '; StringX[9] := ' te Seite) benützen. ';
Canvas.Font.Style := [fsBold]; Canvas.Font.Name := 'Arial'; Canvas.Font.Size := 33;
Canvas.TextOut(Trunc(60*Frac), Trunc(3000*Frac), StringX[1]); Canvas.TextOut(Trunc(60*Frac), Trunc(3300*Frac), StringX[2]);
Canvas.Font.Style := []; Canvas.Font.Size := 30;
Canvas.TextOut(Trunc(60*Frac), Trunc(4200*Frac), StringX[3]); Canvas.TextOut(Trunc(60*Frac), Trunc(4500*Frac), StringX[4]); Canvas.TextOut(Trunc(60*Frac), Trunc(4800*Frac), StringX[5]); Canvas.TextOut(Trunc(60*Frac), Trunc(5100*Frac), StringX[6]); Canvas.TextOut(Trunc(60*Frac), Trunc(5400*Frac), StringX[7]); Canvas.TextOut(Trunc(60*Frac), Trunc(5700*Frac), StringX[8]); Canvas.TextOut(Trunc(60*Frac), Trunc(6000*Frac), StringX[9]);
NewPage; |
etc.
Woran liegt das? Besten Dank im Voraus für die Antworten!
GeorgX
Moderiert von
tommie-lie: Code- durch Delphi-Tags ersetzt
Andreas Pfau - Mi 18.06.03 19:45
Hallo,
versuch' mal, mit "SetMapMode()" auf 0,01mm zu setzen ("HIMETRIC"). Genauer geht's nicht mehr.
georgfischerx - Fr 20.06.03 19:44
Titel: Präziser Ausdruck ...
Sorry, aber das funktioniert leider gar nicht. Das Einzige, was jetzt geht, sind die präzisen Koordinaten. Aber die Schriften sehen jetzt TOTAL anders aus, je nachdem, welchen Drucker man verwendet.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49:
| If PrintDialog1.Execute Then Begin With Printer Do Begin Printer.Orientation := poPortrait; BeginDoc; SetMapMode(Printer.Canvas.Handle, MM_LOMETRIC); Long := Printer.Canvas.Font.PixelsPerInch;
Koordinat[1] := 300; Koordinat[2] := -300; Koordinat[3] := Bmp.Width + 300; Koordinat[4] := - Bmp.Height - 300;
MyRect := Rect(Koordinat[1], Koordinat[2], Koordinat[3], Koordinat[4]); Canvas.StretchDraw(MyRect, Bmp);
StringX[1] := ' Katalog '; StringX[2] := ' Kassettendienst ';
StringX[3] := ' Die Kassetten in diesem Katalog '; StringX[4] := ' sind nicht für den Leihdienst be- '; StringX[5] := ' stimmt. Sie können zum Stückpreis '; StringX[6] := ' von Fr. 8.-- (inkl. Porto und Ver- '; StringX[7] := ' packung) bezogen werden. '; StringX[8] := ' Bitte beiliegende Bestellkarte (letzte '; StringX[9] := ' te Seite) benützen. ';
Canvas.Font.Style := [fsBold]; Canvas.Font.Name := 'Arial'; Canvas.Font.Size := 15;
Canvas.TextOut(100, -1100, StringX[1]); Canvas.TextOut(100, -1250, StringX[2]);
Canvas.Font.Style := []; Canvas.Font.Size := 12;
Canvas.TextOut(100, -1500 , StringX[3]); Canvas.TextOut(100, -1630 , StringX[4]); Canvas.TextOut(100, -1760 , StringX[5]); Canvas.TextOut(100, -1890 , StringX[6]); Canvas.TextOut(100, -2020 , StringX[7]); Canvas.TextOut(100, -2150 , StringX[8]); Canvas.TextOut(100, -2280 , StringX[9]);
EndDoc; End; |
Auf einem HP PSC 500 (Tintenstrahler) ein TOTAL anderes Ergebnis als auf einem HP Laserjet. Woran liegt das ?
Ich freue mich auf Eure Antworten !
Georg
P.S. Auch die Koordinaten stimmen nicht auf jedem Drucker. Ich habe soeben 20 verschiedene Drucker ausprobiert. Ergebnis: Deprimierend.
Andreas Pfau - Fr 20.06.03 22:48
Villeicht, wenn du nicht Font.Size, sondern Sonft.Height setzt ????
AndyB - Sa 21.06.03 00:39
Titel: Re: Präziser Ausdruck ...
georgfischerx hat folgendes geschrieben: |
Auf einem HP PSC 500 (Tintenstrahler) ein TOTAL anderes Ergebnis
als auf einem HP Laserjet. Woran liegt das ? |
Das liegt an der
bedruckbaren Fläche. Nicht jeder Drucker beginnt ganz links oben auf dem Papier. Du musst also den PHYSICALOFFSETX/Y, den du in DPI bekommst (also Umrechnen auf 1/10 mm ist angesagt) einberechnen.
Zitat: |
Auch die Koordinaten stimmen nicht auf jedem Drucker. Ich habe soeben 20 verschiedene Drucker ausprobiert. Ergebnis: Deprimierend. |
Wie schon gesagt die Druckfläche, insbesondere der Ort, an dem für den Drucker, der Nullpunkt ist.
Zitat: |
Delphi-Quelltext 1:
| Canvas.StretchDraw(MyRect, Bmp); | |
Bei den 20 Druckern ist dir keiner untergekommen, der das Bild nicht druckt? Bei mir reichten da schon 2. Eine bessere StretchDraw Funktion ist da die API Funktion
StretchDIBits [
http://homepages.borland.com/efg2lab/Library/Delphi/Printing/#PrintBitmap].
Und noch was für dein Font.Size:
Quelle:
efg's Computer Lab - Delphi Printing Info and Links [
http://homepages.borland.com/efg2lab/Library/Delphi/Printing/index.html]
Zitat: |
Set the Height in a device-independent way and never use the font.size.
Delphi-Quelltext 1:
| Printer.Canvas.Font.Height := MulDiv(GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSY), FontSize, 72); | |
georgfischerx - Sa 21.06.03 10:46
Titel: Präziser Audruck ...
Vielen Dank für Eure Antworten. Wie ich sehe, wird das Ganze für mich zu kompliziert. Einen einfachen, druckerunabhängigen Druck gibt es nicht. Offenbar haben die WinWord-Programmierer sehr viel Code gebraucht, um so etwas zu realisieren. Ich gebe auf.
Georg
AndyB - Sa 21.06.03 11:15
Titel: Re: Präziser Audruck ...
georgfischerx hat folgendes geschrieben: |
Ich gebe auf. |
Na so unheimlich schwer ist es nun auch wieder nicht. Bei Bitmaps wird es halt etwas kompliziert, aber das lässt sich mit einer "einmal geschrieben, immer wieder benutzt"en Funktion in den Griff bekommen.
Zu den Koordinaten:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| function GetPrintAreaStart: TPoint;
begin Result.X := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALOFFSETX); Result.Y := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALOFFSETY); DPToLP(Printer.Canvas.Handle, Result, 1); end;
function GetPhysicalOffset: TPoint;
begin Result.X := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALOFFSETX); Result.Y := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALOFFSETY); end;
function GetPrintAreaSize: TSize;
begin Result.cx := GetDeviceCaps(Printer.Canvas.Handle, HORZRES); Result.cy := GetDeviceCaps(Printer.Canvas.Handle, VERTRES); DPToLP(Printer.Canvas.Handle, Result, 1); end;
function GetPageSize: TSize;
begin Result.cx := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALWIDTH); Result.cy := GetDeviceCaps(Printer.Canvas.Handle, PHYSICALHEIGHT); DPToLP(Printer.Canvas.Handle, Result, 1); end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| SetMapMode(Printer.Canvas.Handle, MM_LOMETRIC);
SetViewportOrgEx(dc, GetPhysicalOffset.X, -GetPhysicalOffset.Y, nil);
Printer.Canvas.Font.Height := 100;
Printer.Canvas.TextOut(0, 0, 'Test am Nullpunk') |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!