AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi [Drucken] Textlänge in Millimeter ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

[Drucken] Textlänge in Millimeter ermitteln

Ein Thema von s.h.a.r.k · begonnen am 26. Feb 2008 · letzter Beitrag vom 27. Feb 2008
Antwort Antwort
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#1

[Drucken] Textlänge in Millimeter ermitteln

  Alt 26. Feb 2008, 13:37
Hallo,

und zwar sitze ich gerade wieder mal vor einem Problem, mit welchen ich nicht ganz klar komme. Mir geht es im Folgenden darum, dass ich einen String unbekannter Länge habe und diesen ausdrucken will.

Zunächst allerdings noch eine Vorbetrachtung, um meinen eigentlichen Ansatz verständlich zu machen:

Um die Größe des Blattes zu berechnen habe ich mehrere Möglichkeiten. Zum einen kann ich mir per GetDeviceCaps() die Größe des Blattes im Millimeter ausgeben lassen, oder eben selbst berechnen. Ich will nun den Weg über das selbst berechnen gehen, da ich ich darauf auf die Größe der Schrift in Millimeter schließen will.

Die Formel für die Breite des Blattes in Millimeter berechnet sich wie folgt und stimmen auch exakt:

Delphi-Quellcode:
width_in_mm := GetDeviceCaps(Printer.Canvas.Handle, HORZRES) // Breite in Pixel
             / GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSX) // Auflösung des Druckers in X-Richtung
             * 25.4; // Inch in Millimeter umrechnen (2.54cm = 1 inch)
Nun habe ich mir eine eigene Methode geschrieben, welche die Textlänge in Pixel zurückgibt, dann diese, wie oben gezeigt in Millimeter umrechnet und dann entsprechend einen Zeilenumbruch macht. Das ganze funktioniert allerdings nicht, warum auch immer! Ich hab mir schon gedacht, dass sich ein Logikfehler eingeschlichen hat, aber bei der Blattgröße stimmt es ja auch *argh*

Was ich nicht ganz verstehe ist zudem folgendes: Ändere ich per setMapMode() von MM_TEXT auf MM_LOMETRIC bzw. anders herum, dann liefert mir die Canvas.textWidth()-Methode auch andere Werte. Aber das darf doch nicht sein?

Hier mal mein Code - evtl. findet ihr was:
Delphi-Quellcode:
(*******************************************************************************
Class/Method : printString
Information : Druckt einen Text mit beliebiger Länge aus und wandelt "//" in
Zeilenumbrüche um.
*)

procedure TPrintLaufzettel.printString(ACanvas : TCanvas;
                                       x, y : Integer;
                                       MaxWidth : Integer;
                                       AStr : String;
                                       AFontHeight : Integer);
var
  d : Integer;
  t : String;
  c : String;
  lpx : Integer;
  len : Extended;
begin
  // Auflösung des Druckers ermitteln
  lpx := GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSX);

  // evtl. y berichtigen
  if (y > 0) then
    y := y * (-1);

  with ACanvas do
  begin
    Font.Height := AFontHeight;

    d := 0;
    while (length(AStr) > 0) do
    begin
      t := '';
      c := '';
      len := 0;
      while (length(AStr) > 0) and (len < MaxWidth) do
      begin
        // nächstes Wort kopieren und in AStr ausschneiden
        t := t + c;
        delete(AStr, 1, length(c));
        if (pos(' ', AStr) = 0) and (length(AStr) > 0) then
          c := AStr
        else
          c := copy(AStr, 1, pos(' ', AStr));

        // Auf Zeilenumbruch prüfen
        if (pos('//', c) > 0) then
        begin
          delete(c, length(c) - 2, length(c)); // alles hinter dem Backslash entfernen
          t := t + c; // t vervollständigen
          delete(AStr, 1, length(c) + 2); // AStr kürzen
          break; // Schleife verlassen, da Zeilenumbruch erfolgen soll
        end;

        // Länge des Textes in Millimeter ausgeben neu berechnen
        len := textWidth(trim(t + c)) * 10 / lpx * 25.4;
      end;

      TextOut(x, y + d, trim(t)); // Text ausdrucken
      dec(d, AFontHeight + 6); // Abstand für nächste Zeile berechnen
    end;
  end;
end;
Mit freundlichen Grüßen
der (gerade verzweifelte) Hai
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: [Drucken] Textlänge in Millimeter ermitteln

  Alt 26. Feb 2008, 13:47
Zitat von s.h.a.r.k:
Was ich nicht ganz verstehe ist zudem folgendes: Ändere ich per setMapMode() von MM_TEXT auf MM_LOMETRIC bzw. anders herum, dann liefert mir die Canvas.textWidth()-Methode auch andere Werte. Aber das darf doch nicht sein?
Doch einfach mal die Hilfe lesen:
Zitat:
Each logical unit is mapped to one device pixel. Positive x is to the right; positive y is down.
und
Zitat:
Each logical unit is mapped to 0.1 millimeter. Positive x is to the right; positive y is up.
Wenn du sie in Millimetern haben willst, dann setz den MapMode auf MM_LOMETRIC.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#3

Re: [Drucken] Textlänge in Millimeter ermitteln

  Alt 27. Feb 2008, 13:38
Habe irgendwie den Wald vor lauter Bäumen nicht gesehen... Danke!

Hier die (von mehreren Fehlern bereinigte) Lösung für jeden den sie interessieren sollte.

Delphi-Quellcode:
(*******************************************************************************
Class/Method : printString
Information  : Druckt einen Text mit beliebiger Länge aus und wandelt "//" in
                Zeilenumbrüche um.
*)

procedure TPrintLaufzettel.printString(ACanvas : TCanvas;
                                       x, y : Integer;
                                       MaxWidth : Integer;
                                       AStr : String;
                                       AFontHeight : Integer);
var
  d : Integer;
  t : String;
  c : String;
  lpx : Integer;
  len : Extended;
begin
  // MapMode setzen
  setMapMode(Printer.Canvas.Handle, MM_LOMETRIC);

  // Textausrichtung
  setTextAlign(Printer.Canvas.Handle, TA_LEFT + TA_TOP);

  // Auflösung des Druckers ermitteln
  lpx := GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSX);

  // evtl. y berichtigen, da auf dem Drucker gedruckt wird muss
  // y negativ sein
  if (y > 0) then
    y := y * (-1);

  with ACanvas do
  begin
    Font.Height := AFontHeight;

    d := 0;
    while (length(AStr) > 0) do
    begin
      t := '';
      c := '';
      len := 0;
      while (length(AStr) > 0) and (len < MaxWidth) do
      begin
        // nächstes Wort kopieren und in AStr ausschneiden
        t := t + c;
        delete(AStr, 1, length(c));
        if (pos(' ', AStr) = 0) and (length(AStr) > 0) then
          c := AStr
        else
          c := copy(AStr, 1, pos(' ', AStr));

        // Auf Zeilenumbruch prüfen
        if (pos('//', c) > 0) then
        begin
          // Prüfen, ob bisherige Zeile mit neuem Text nicht zu lang ist
          len := textWidth(trim(t + copy(c, 1, pos('//', c) - 1)));
          if (len > MaxWidth) then
            break;

          delete(c, length(c) - 2, length(c)); // alles hinter dem Backslash entfernen
          t := t + c; // t vervollständigen
          delete(AStr, 1, length(c) + 2); // AStr kürzen
          break; // Schleife verlassen, da Zeilenumbruch erfolgen soll
        end;

        // Länge des Textes in Millimeter ausgeben neu berechnen
        len := textWidth(trim(t + c));
      end;

      TextOut(x, y + d, trim(t)); // Text ausdrucken
      dec(d, AFontHeight + 6); // Abstand für nächste Zeile berechnen
    end;
  end;
end;
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.544 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: [Drucken] Textlänge in Millimeter ermitteln

  Alt 27. Feb 2008, 14:01
Ich habe es jetzt nicht ausprobiert, aber 3 Dinge:
Delphi-Quellcode:
  // Textausrichtung
  setTextAlign(Printer.Canvas.Handle, TA_LEFT + TA_TOP); //bitte or statt +

  // Auflösung des Druckers ermitteln
  lpx := GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSX);

  // evtl. y berichtigen, da auf dem Drucker gedruckt wird muss
  // y negativ sein
  y := -abs(y); //ist kürzer ;)
Und wozu brauchst Du ACanvas?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#5

Re: [Drucken] Textlänge in Millimeter ermitteln

  Alt 27. Feb 2008, 17:30
Oh, das mit dem ACanvas war irgendwie noch von der vorherigen Methode übrig geblieben, welche ich komplett geändert hatte *schäm*

Wo liegt der Unterschied zwischen dem OR und dem verwendeten +?!

Das mit der kürzeren Schreibweise sei mal so dahingestellt
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.544 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: [Drucken] Textlänge in Millimeter ermitteln

  Alt 27. Feb 2008, 17:35
Zitat von s.h.a.r.k:
Wo liegt der Unterschied zwischen dem OR und dem verwendeten +?!
Schau mal hier unter "Fallstricke".
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:37 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