Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Im druck Zeilenumbruch erzwingen (https://www.delphipraxis.net/167644-im-druck-zeilenumbruch-erzwingen.html)

m-werk 11. Apr 2012 09:13

Im druck Zeilenumbruch erzwingen
 
Hallo,

ich bin gerade dabei, einen Druck-Button zu realisieren. Soweit funktioniert schon mal alles bis auf eine Sache.

In meiner DB habe ich ein Memo-Feld, wo einiges eingetragen werden kann. Das Problem ist der Druck. Wie kann ich einen Zeilenumbruch hier (Im Code unten unter Anmerkung) erzwingen?
Code:
procedure TForm1.BtnPrintClick(Sender: TObject);
var rec : TRect;
begin
if PrintDialog1.Execute then
  begin
    rec.Left := 400;
    rec.Top := 1150;
    rec.Right := 3000;
    rec.Bottom := 3000;
    Printer.BeginDoc;
    Printer.Canvas.Font.Size:=10;
    Printer.Canvas.TextOut(3500,200,DateTimeToStr(now));
    Printer.Canvas.Font.Size:=12;
    Printer.Canvas.Font.Style:=[fsBold];
    Printer.Canvas.TextOut(400,200,ADOQuery1.FieldValues['Nachname']);
    Printer.Canvas.TextOut(1500,200,ADOQuery1.FieldValues['Vorname']);
    Printer.Canvas.Font.Style:=[];
    Printer.Canvas.TextOut(400,350,ADOQuery1.FieldValues['Adresse']);
    Printer.Canvas.TextOut(1500,350,ADOQuery1.FieldValues['Ort']);
    Printer.Canvas.Font.Style:=[fsUnderline];
    Printer.Canvas.TextOut(400,600,'Telefon:');
    Printer.Canvas.Font.Style:=[];
    Printer.Canvas.TextOut(400,750,ADOQuery1.FieldValues['Telefon1']);
    Printer.Canvas.TextOut(1500,750,ADOQuery1.FieldValues['Telefon2']);
    Printer.Canvas.TextOut(2500,750,ADOQuery1.FieldValues['Telefon3']);
    Printer.Canvas.Font.Style:=[fsUnderline];
    Printer.Canvas.TextOut(400,1000, 'Beschreibung:');
    Printer.Canvas.Font.Style:=[];
    Printer.Canvas.TextRect(Rec,400,1150,ADOQuery1.FieldValues['Anmerkung']);
  end;
  Printer.EndDoc;
end;

DeddyH 11. Apr 2012 09:17

AW: Im druck Zeilenumbruch erzwingen
 
IIRC schneidet TextRect gnadenlos alles ab, was nicht in das Rechteck passt. Hilft Dir vielleicht MSDN-Library durchsuchenDrawText weiter?

himitsu 11. Apr 2012 09:19

AW: Im druck Zeilenumbruch erzwingen
 
Eventuel könntest du dir auch die verschiedenen Report-Tools ansehn?

Da erstellst du graphisch ein Layout des Ausdrucks (so wie im FormDesigner) und oftmals kann man dieses dann auch direkt mit dem passenden Datensatz befüllen, oder gleich mehreren davon.

Bummi 11. Apr 2012 09:30

AW: Im druck Zeilenumbruch erzwingen
 
Wenn Du es zu Fuß machen willst wirst Du per

Canvas.TextRect(r,s,[tfCalcRect ,tfWordBreak]);

testen müssen ob es noch auf die Seite passt, den String gegf. zerlegen und zwischenrein ein Newpage absetzen

m-werk 11. Apr 2012 09:38

AW: Im druck Zeilenumbruch erzwingen
 
Das mit DrawText hab ich mir schon angesehen, aber leider komm ich hier nicht weiter wie ich es einbauen kann.
Reports wollte ich vermeiden.

Wie stelle ich es denn mit DrawText an? Ich hab mich schon die Finger wund gesucht aber noch nichts gefunden, wie ich mit DrawText arbeiten kann!

Bummi 11. Apr 2012 09:45

AW: Im druck Zeilenumbruch erzwingen
 
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
wobei HDC Canvas.Handle ist

m-werk 11. Apr 2012 09:51

AW: Im druck Zeilenumbruch erzwingen
 
Das ist es ja, was ich nicht verstehe. Ich versteh nicht, wie ich es wo in mein kleines Projekt einbauen kann.

DeddyH 11. Apr 2012 09:52

AW: Im druck Zeilenumbruch erzwingen
 
Printer.Canvas.Handle, um genau zu sein. Hier ein kurzes Beispiel, das den String FText auf die Zeichenfläche des Formulars schreibt:
Delphi-Quellcode:
procedure TForm1.FormPaint(Sender: TObject);
var
  R: TRect;
begin
  R := ClientRect;
  InflateRect(R, -3, -3); //Offset von 3 Pixeln in X- und Y-Richtung
  DrawText(Canvas.Handle, PChar(FText), -1, R, DT_TOP or DT_LEFT or DT_WORDBREAK);
end;

himitsu 11. Apr 2012 09:55

AW: Im druck Zeilenumbruch erzwingen
 
TextRect geht am Ende auch nur auf DrawTextEx los.
Du kannst also entweder direkt die WinAPI nutzen, oder eben diesen Wrapper.

Die Namen der Parameter sind ähnlich und da du den VCL-Quellcode besitzt, kannst'e och einfach nachsehn, was wie so zusammenhängt.
Nun könntest du dir die Delphi-Hilfe ansehn (OH: Delphi-Referenz durchsuchenTCanvas.TextRect) und auch die Hilfe vom Windows (MSDN: MSDN-Library durchsuchenDrawTextEx).
Darin stehen alle nötigen Informationen, wie man diese Funktion verwendet.

Die Breite hast du dir vorgegeben und die Höhe müßtest du eventuell noch berechnen.

PS: Ich würde dir noch raten entweder die Auflösung dieses Canvas anzupassen oder zumindestens dieses zu beachten, denn wenn du deinen Ausdruck z.B. für 300 DPI erstellst und dann jemand kommt und mit 150 DPI druckt, dann ist alles doppelt so groß und 75% des Ausdrucks fehlen.
(Daheim hab ich irgendwo eine uralte Demo für den TPrinter rumliegen ... mal sehn ob ich die heute abend finde)


Nja, der Vorteil an diesen Repoerts ist eben, daß sie für dich diese ganzen Berechnungen und nötigen Anpassungen durchführen,
was aber nicht heißt, daß man sich auch selber abmühen kann und versucht alles selber zu machen.

m-werk 11. Apr 2012 10:17

AW: Im druck Zeilenumbruch erzwingen
 
So, ich hab nun mit dem obrigen Code einen Versuch gestartet. Ich sehe jetzt den Text in meiner From ganz oben. Wie bekomme ich diesen aber nun auf Papier?

himitsu 11. Apr 2012 10:25

AW: Im druck Zeilenumbruch erzwingen
 
Zitat:

Delphi-Quellcode:
procedure TForm1.FormPaint(Sender: TObject);
var
  R: TRect;
begin
  R := ClientRect;
  InflateRect(R, -3, -3); //Offset von 3 Pixeln in X- und Y-Richtung
  DrawText(Canvas.Handle, PChar(FText), -1, R, DT_TOP or DT_LEFT or DT_WORDBREAK);
end;

Canvas = Self.Canvas (bzw. FormX.Canvas)
und ClientRect = Größe/Position des Zeichenbereichs

Was wird man da wohl nun anpassen müssen, um die Schrift auf den Ausdruck zu bekommen?

DeddyH 11. Apr 2012 10:33

AW: Im druck Zeilenumbruch erzwingen
 
Indem Du nicht das Handle des eigenen Canvas, sondern das des Printer.Canvas übergibst. Allerdings sind da noch einige andere Dinge zu beachten, siehe himitsus Einwände, Drucken ist eben leider nicht ganz so einfach mit Delphi, wenn man alles selbst übernehmen möchte.

m-werk 11. Apr 2012 10:48

AW: Im druck Zeilenumbruch erzwingen
 
Ok, ich habs nun fast hinbekommen. Es wird zwar ausgedruckt, aber ich komm mit den Positionen nicht klar. Es erscheint immer wieder in der linken Ecke oben. Auch wenn ich den wert von InflateRect ändere. Wenn ich den auf -400 einstelle, kommt nichts auf Papier
Code:
procedure TForm1.BtnPrintClick(Sender: TObject);
var rec : TRect;
begin
if PrintDialog1.Execute then
  begin
    rec.Left := 400;
    rec.Top := 1150;
    rec.Right := 4000;
    rec.Bottom := 3000;
    Printer.BeginDoc;
    Printer.Canvas.Font.Size:=10;
    Printer.Canvas.TextOut(3500,200,DateTimeToStr(now));
    Printer.Canvas.Font.Size:=12;
    Printer.Canvas.Font.Style:=[fsBold];
    Printer.Canvas.TextOut(400,200,DBEditNachname.Text);
    Printer.Canvas.TextOut(1500,200,DBEditVorname.Text);
    Printer.Canvas.Font.Style:=[];
    Printer.Canvas.TextOut(400,350,DBEditAdresse.Text);
    Printer.Canvas.TextOut(1500,350,DBEditOrt.Text);
    Printer.Canvas.Font.Style:=[fsUnderline];
    Printer.Canvas.TextOut(400,600,'Telefon:');
    Printer.Canvas.Font.Style:=[];
    Printer.Canvas.TextOut(400,750,DBEditTelefon1.Text);
    Printer.Canvas.TextOut(1500,750,DBEditTelefon2.Text);
    Printer.Canvas.TextOut(2500,750,DBEditTelefon3.Text);
    Printer.Canvas.Font.Style:=[fsUnderline];
    Printer.Canvas.TextOut(400,1000, 'Beschreibung:');
    Printer.Canvas.Font.Style:=[];
    rec := ClientRect;
    InflateRect(rec, -3, -3);
    DrawText(Printer.Canvas.Handle, PChar(DBMemo1.Text), -1, rec, DT_TOP or DT_LEFT or DT_WORDBREAK);
end;

DeddyH 11. Apr 2012 10:52

AW: Im druck Zeilenumbruch erzwingen
 
Das mit dem ClientRect war ja auch nur ein Beispiel, Du musst das Rechteck schon passend definieren.

m-werk 11. Apr 2012 11:02

AW: Im druck Zeilenumbruch erzwingen
 
Danke für die Hilfe, inzwischen hab ich es auch rausgefunden.

Jetzt funktioniert es.

Betreffend der Auflösung versteh ich nicht ganz, was damit gemeint ist.

himitsu 11. Apr 2012 11:20

AW: Im druck Zeilenumbruch erzwingen
 
Du druckst in einer festen Größe (Pixel) ... was ist aber, wenn ein Drucker mal mehr oder weniger Pixel darstellt?

Dann verändert sich die größe der Pixel und damit auch die Größe deiner Schrift und aller anderen Maße (wie z.B. die Position der Texte). :wink:

Tipp: nimm eine Form, stell sie auf Vollbild und schreibe darauf einen Text (im OnPaint mit TextOut).
Und nun verstell man die Auflösung deines Monitors.

m-werk 11. Apr 2012 11:50

AW: Im druck Zeilenumbruch erzwingen
 
Ok, da es aber nur Text ist, würden 72 Pixel reichen. Kann man irgendow einstellen, dass er NUR mit der vorgegebenen Auflösung druckt?

Bummi 11. Apr 2012 12:12

AW: Im druck Zeilenumbruch erzwingen
 
Wenn Du nicht umrechnen willst kannst Du per
SetCanvasZoomAndRotation, hier enthalten
http://www.delphipraxis.net/167172-r...-ausgeben.html
das Printercanvas an die von Dir gewünschte Auflösung "umstellen"

DeddyH 11. Apr 2012 12:13

AW: Im druck Zeilenumbruch erzwingen
 
Du kannst in Millimentern statt in Pixeln drucken. Dazu musst Du mit MSDN-Library durchsuchenSetMapMode die Einheit umstellen. Ein kurzes Beispiel findest Du z.B. bei den Schweizern.

m-werk 11. Apr 2012 12:59

AW: Im druck Zeilenumbruch erzwingen
 
Ich hab mir das Beispiel von den schweizen angesehen und habe Font.Height:=50; eingegeben.

Am Ausdruck ändert sich die Schriftgröße aber NUR in dieser Zeile:
Code:
Printer.Canvas.TextOut(3500,200,DateTimeToStr(now));
Bei den anderen Codezeilen, wo der Text von der DBEdit.Text stammt, ist die Schriftgröße immer gleich.

Bummi 11. Apr 2012 13:01

AW: Im druck Zeilenumbruch erzwingen
 
Hast Du Deine anderen Fontsizeangaben entfernt=

m-werk 11. Apr 2012 13:12

AW: Im druck Zeilenumbruch erzwingen
 
Ups, diese habe ich übersehen. Hab dies nun auch geändert. Jetzt funktioniert es.

Reicht es jetzt mit den Höhenangaben oder muss ich noch etwas berücksichtigen?

Eine Frage hätte ich noch.
Wenn ich auf Drucken klicke kommt zuerst immer das Windows-Formular, wo ich den Drucker auswählen kann. Gibt es nicht einen Befehl, der gleich auf den Standart-Drucker zugreift, so dass, wenn ich auf Drucken klicke, gleich gedruckt wird?

Bummi 11. Apr 2012 13:14

AW: Im druck Zeilenumbruch erzwingen
 
Lass die Zeile
Delphi-Quellcode:
if PrintDialog1.Execute then
weg ....

DeddyH 11. Apr 2012 13:14

AW: Im druck Zeilenumbruch erzwingen
 
Zitat:

Delphi-Quellcode:
if PrintDialog1.Execute then

Wenn Du selbst einen Dialog aufrufst, sollte der dann auch kommen :roll:

m-werk 11. Apr 2012 13:19

AW: Im druck Zeilenumbruch erzwingen
 
Spitze, ich glaub, jetzt hab ich alles. Danke für die tolle Unterstützung!


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz