[gelöst] Fragen zum Drucken unter Windows

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1196
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

[gelöst] Fragen zum Drucken unter Windows

Beitrag von kralle »

Moin,

ich fange an mich mit dem Ausdrucken zu beschäftigen und habe folgenden Code aus verschiedenen gefundenen Beiträgen zusammengestellt:

Code: Alles auswählen

 
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, PrintersDlgs, Forms, Controls, Graphics, Dialogs,
  StdCtrls, printers;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    PrintDialog1: TPrintDialog;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
const
  TOTAL_PAGES = 4; // Maximale Anzahl von Seiten die Gedruckt werden sollen
Var
    TestString:string;
    page, startPage, endPage : Integer;
begin
     TestString:='abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 äöüß ÄÖÜ';
     // Druckerdaten ermitteln
     //
     // erlauben das im Druckerdialog die Option Drucke von Seite x bis Seite y aktiv ist
     // Set up print dialog options
     PrintDialog1.MinPage := 1; // Erste erlaubte Seitennummer
     PrintDialog1.MaxPage := TOTAL_PAGES; // Höchste erlaubte Seitennummer
     PrintDialog1.ToPage := TOTAL_PAGES; // 1 bis Höchste Erlaubte Seitennummer
     PrintDialog1.Options := [poPageNums];
     // Drucken-Dialog anzeigen
     if PrintDialog1.Execute then
        Begin
          // Den gewählten Drucker ins Memo schreiben
          Memo1.Append(Printer.Printers[Printer.PrinterIndex]);
          // maximale Seitenhöhe in Pixel
          Memo1.Append(IntToStr(Printer.PageHeight));
          // maximale Seitenbreite in Pixel
          Memo1.Append(IntToStr(Printer.PageWidth));
          // Prüfen wieviel Platz der gewählte Text auf dem Drucker-Canvas in der Breite braucht
          Memo1.Append(TestString);
          Memo1.Append(IntToStr(Printer.Canvas.TextWidth(TestString)));
          // Prüfen wieviel Platz der gewählte Text auf dem Drucker-Canvas in der Höhe braucht
          Memo1.Append(TestString);
          Memo1.Append(IntToStr(Printer.Canvas.TextHeight(TestString)));
          // Papierausrichtung ermitteln und setzen
          // poLandscape
          //
          Memo1.Append('Ausrichtung = '); //+String(Printer.Orientation)); **** Wie ermitteln? *****
          Printer.Orientation:= poLandscape;
          // Anzahl der im Dialog ausgewählten Kopien setzen
          Memo1.Append('Es sollen '+IntToStr(PrintDialog1.Copies)+' Kopien erstellt werden.');
          Printer.Copies := PrintDialog1.Copies;
 
 
          // Titel des Druckauftrages festlegen
          Printer.Title := 'Druckauftrag 1';
          // Schriftgröße 12 festlegen
          Printer.Canvas.Font.Size := 36;
          // Schriftart Verdana festlegen
          Printer.Canvas.Font.Name := 'Verdana';
 
 
          // Druckauftrag starten:
          // Der Befehl startet einen Druckauftrag, (nicht eine neue Seite!)
 
          Printer.BeginDoc;
 
          // Sollen ALLE Seiten gedruckt werden oder nur von x bis y
 
          if PrintDialog1.PrintRange = prPageNums then
             begin
                  startpage := PrintDialog1.FromPage;
                  endPage := PrintDialog1.ToPage;
             end
          else // All pages
               begin
                    startPage := 1;
                    endPage := TOTAL_PAGES;
               end;
 
         // Set up the start page number
         page := startPage;
 
         // Keep printing whilst all OK
         while ((not Printer.Aborted) and Printer.Printing) and (page <= endPage) do
            begin
                 // Schriftfarbe einstellen
                 Printer.Canvas.Font.Color := clBlue;
                 // *******************************************************************
                 // Einen Text an einer bestimmten Position des Drucker-Canvas drucken
                 // *******************************************************************
                 Printer.Canvas.TextOut(0,0, 'Page number = '+IntToStr(page)); // *** Warum nicht linke obere Ecke???
                 Printer.Canvas.TextOut(0,Printer.Canvas.Font.Size*2,teststring);
                 // Die Seitenzahl erhöhen
                 Inc(page);
 
                 // Eine neue Seite ausgeben solange bis die letzte ausgedruckt wurde
                 if (page <= endPage) and (not Printer.Aborted) then
 
                 // Neue Seite erstellen:
                 // Dieser Befehl erstellt eine neue Seite und gibt die Möglichkeit auf ihr zu drucken.
                 // Der Befehl kann beliebig oft zwischen Printer.BeginDoc; und Printer.EndDoc; aufgerufen werden.
                 // Für jeden Aufruf wird später eine neue Seite gedruckt.
 
                 Printer.NewPage;
            end;
 
          // Druckauftrag beenden:
 
          Printer.EndDoc;
 
          end;
 
end;
 
end. 
 
Ein Punkt ist mir zur Zeit noch unklar:

Wie man auf dem Bild sehen kann, beginnt der Druck nicht in der linken, oberen Ecke.
Warum?
Und wie ändert man das?

Gruß HEiko
Dateianhänge
Ausdruck_l.jpg
Zuletzt geändert von kralle am So 12. Apr 2015, 13:56, insgesamt 1-mal geändert.
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Mathias
Beiträge: 6918
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zum Drucken unter Windows

Beitrag von Mathias »

Seitenränder könnte ein Stichwort sein. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10873
Registriert: Mo 11. Sep 2006, 19:01

Re: Fragen zum Drucken unter Windows

Beitrag von theo »

Kommt auch auf den Drucker an. Meiner kann nicht bei 0,0 zu drucken anfangen aus mechanischen Gründen.

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1196
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Fragen zum Drucken unter Windows

Beitrag von kralle »

Hallo Mathias,
Mathias hat geschrieben:Seitenränder könnte ein Stichwort sein. :wink:
Das war das richtige Stichwort.
Wobei ich bei diesem riesigen Abstand von oben nicht mehr an Ränder gedacht habe.
Kann ich mir die eingestellten Ränder eines Druckers in mm irgendwie anzeigen lassen?

Gruß Heiko
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen zum Drucken unter Windows

Beitrag von Michl »

Falls ich nichts verhauen habe:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
begin
  if PrinterSetupDialog1.Execute then
    ShowMessage(
      'Der gewählte Drucker hat folgende Konfiguration:' + LineEnding +
      'DPI in X-Richtung: '         + IntToStr(Printer.XDPI) + LineEnding +
      'DPI in Y-Richtung: '         + IntToStr(Printer.YDPI) + LineEnding +
      'Druckbare Breite in Pixel: ' + IntToStr(Printer.PageWidth) + LineEnding +
      'Druckbare Höhe in Pixel: '   + IntToStr(Printer.PageHeight) + LineEnding +
      'Linker Druckrand in Pixel: ' + IntToStr(Printer.PaperSize.PaperRect.WorkRect.Left) + LineEnding +
      'Oberer Druckrand in Pixel: ' + IntToStr(Printer.PaperSize.PaperRect.WorkRect.Top));
end;
Die Umrechnung von DPI (zu Inch) zu mm bekommst du sicherlich so hin?!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1196
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Fragen zum Drucken unter Windows

Beitrag von kralle »

Hallo Michl,
Michl hat geschrieben:Falls ich nichts verhauen habe:

Code: Alles auswählen

 
      'DPI in X-Richtung: '         + IntToStr(Printer.XDPI) + LineEnding +
      'DPI in Y-Richtung: '         + IntToStr(Printer.YDPI) + LineEnding +
      'Druckbare Breite in Pixel: ' + IntToStr(Printer.PageWidth) + LineEnding +
      'Druckbare Höhe in Pixel: '   + IntToStr(Printer.PageHeight) + LineEnding +
      'Linker Druckrand in Pixel: ' + IntToStr(Printer.PaperSize.PaperRect.WorkRect.Left) + LineEnding +
      'Oberer Druckrand in Pixel: ' + IntToStr(Printer.PaperSize.PaperRect.WorkRect.Top));
 
Mit diesen Werten kannn ich das Papierformat aber nur dann ermitteln, wenn alle Ränder Null sind.
Wenn aber z.B. Rechtss ein Rand von 10mm eingestellt ist, dann weißt Du nur noch das Du

Code: Alles auswählen

IntToStr(Printer.PageWidth)
Platz von Links nach rechts hast, aber nicht wie Breit das Blatt ist.
Man müsste also erst einmal die Werte für die Ränder sichern, Alle Ränder auf Null setzten

Code: Alles auswählen

IntToStr(Printer.PageWidth)
und

Code: Alles auswählen

IntToStr(Printer.PageHeight)
neu auslesen und die gesicherten Werte zurück schreiben.
Dann könnte man auch eine Aussage über den Rechten Rand und das Papierformat treffen.

Ob das Schreiben von

Code: Alles auswählen

Printer.PaperSize.PaperRect.WorkRect.Left
und Co funktioniert habe ich noch nicht probiert.
Gruß Heiko
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen zum Drucken unter Windows

Beitrag von Michl »

Ich weiss zwar nicht, wofür du die Info brauchst, da die Druckränder vom Nutzer eingestellt werden. Für mich ist eigentlich immer nur PageWidth, PageHeight (und XDPI und YDPI für Grafiken) interessant, zur Berechnung von Canvas-Zeichnungen. IMHO sollten die Druckerränder so zu ermitteln sein:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
begin
  if PrinterSetupDialog1.Execute then
    ShowMessage(
      'Der gewählte Drucker hat folgende Konfiguration:' + LineEnding +
      'DPI in X-Richtung: '          + IntToStr(Printer.XDPI) + LineEnding +
      'DPI in Y-Richtung: '          + IntToStr(Printer.YDPI) + LineEnding +
      'Druckbare Breite in Pixel: '  + IntToStr(Printer.PageWidth) + LineEnding +
      'Druckbare Höhe in Pixel: '    + IntToStr(Printer.PageHeight) + LineEnding +
      'Linker Druckrand in Pixel: '  + IntToStr(Printer.PaperSize.PaperRect.WorkRect.Left) + LineEnding +
      'Oberer Druckrand in Pixel: '  + IntToStr(Printer.PaperSize.PaperRect.WorkRect.Top) + LineEnding +
      'Rechter Druckrand in Pixel: ' + IntToStr(Printer.PaperSize.PaperRect.PhysicalRect.Right - Printer.PaperSize.PaperRect.WorkRect.Right) + LineEnding +
      'Unterer Druckrand in Pixel: ' + IntToStr(Printer.PaperSize.PaperRect.PhysicalRect.Bottom - Printer.PaperSize.PaperRect.WorkRect.Bottom));
end;
kralle hat geschrieben:Man müsste also erst einmal die Werte für die Ränder sichern, Alle Ränder auf Null setzten
Das verstehe ich nicht. Es ist Printer.PaperSize.PaperRect.WorkRect.Right - Printer.PaperSize.PaperRect.WorkRect.Left = Printer.PageWidth

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1196
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Fragen zum Drucken unter Windows

Beitrag von kralle »

Moin,
Michl hat geschrieben:Ich weiss zwar nicht, wofür du die Info brauchst,
in erster Linie um zuverstehen wie da was zusammenhängt.
Michl hat geschrieben:da die Druckränder vom Nutzer eingestellt werden.
bzw. vom Drucker geliefert werden.
Michl hat geschrieben: Für mich ist eigentlich immer nur PageWidth, PageHeight (und XDPI und YDPI für Grafiken) interessant, zur Berechnung von Canvas-Zeichnungen.
Das versuche ich gerade zu verstehen.
Michl hat geschrieben: IMHO sollten die Druckerränder so zu ermitteln sein:
Bis auf den unteren Teil, hatte ich das schon hin bekommen.
Michl hat geschrieben:Es ist Printer.PaperSize.PaperRect.WorkRect.Right - Printer.PaperSize.PaperRect.WorkRect.Left = Printer.PageWidth
Diesen Rattenschwanz hinter "Printer." ist mir neu und habe den so noch nicht im Netz gesehen.

Danke, für Deine ausführliche Hilfe.

Gruß HEiko
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Antworten