Autor |
Beitrag |
georgfischerx
      
Beiträge: 37
|
Verfasst: Mi 18.06.03 18:12
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.
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
      
Beiträge: 997
|
Verfasst: Mi 18.06.03 19:45
Hallo,
versuch' mal, mit "SetMapMode()" auf 0,01mm zu setzen ("HIMETRIC"). Genauer geht's nicht mehr.
_________________ Life is a bad adventure, but the graphic is really good!
|
|
AndyB
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: Mi 18.06.03 20:09
Auf Delphi-Source gibt es dazu ein Tutorial
_________________ Ist Zeit wirklich Geld?
|
|
georgfischerx 
      
Beiträge: 37
|
Verfasst: 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.
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
      
Beiträge: 997
|
Verfasst: Fr 20.06.03 22:48
Villeicht, wenn du nicht Font.Size, sondern Sonft.Height setzt ????
_________________ Life is a bad adventure, but the graphic is really good!
|
|
AndyB
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: 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.
Und noch was für dein Font.Size:
Quelle: efg's Computer Lab - Delphi Printing Info and Links
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); | |
_________________ Ist Zeit wirklich Geld?
|
|
georgfischerx 
      
Beiträge: 37
|
Verfasst: 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
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: 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') |
_________________ Ist Zeit wirklich Geld?
|
|
|