Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TPrinter: Portrait auf Landscape umzuschalten (https://www.delphipraxis.net/201179-tprinter-portrait-auf-landscape-umzuschalten.html)

Schokohase 30. Jun 2019 19:49

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Das Problem ist ganz woanders ...

In der Vcl.Dialogs wird die Unit Vcl.Printers verwendet. Da aber jetzt das Interface der Unit Vcl.Printers verändert wurde (neue Methoden) kommt der Kompiler/Linker damit nicht mehr klar (weil die vorkompilierte Vcl.Dialogs verwendet wird) und produziert diesen seltsamen Fehler.

peterbelow 1. Jul 2019 10:04

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Zitat:

Zitat von tomkupitz (Beitrag 1435687)
Ich habe mal Folgendes in Printers.pas eingebaut:

Mach das nicht, es ist nie eine gute Idee, eine der Delphi source files direkt zu verändern. Das führt zu Problemen mit anderen RTL/VCL units, die dann eventuell auch neu kompiliert werden müssen, was dann nur geht, wenn Du die Verzeichnisse mit den Sourcefiles in den search path mit aufnimmst, was dann eine ganze Lawine von anderen Versionkonflikten nach sich ziehen kann.

Mach eine Kopie der vcl.printer.pas Datei und benenne die Unit um. Modifiziere diese Datei und verwende sie dann anstelle von vcl.printers in deinem Projekt.

tomkupitz 1. Jul 2019 10:25

AW: TPrinter: Portrait auf Landscape umzuschalten
 
vcl.printer.pas ist natürlich eine Kopie im lokalen Projektverzeichnis. Originale Units ändere ich nie.

Aber die Probleme mit der vcl.printer.pas-Kopie sind so einfach nicht lösbar.

Peter: Ich werde mir mal dein Beispiel ansehen.

Danke an alle und beste Grüße

einbeliebigername 1. Jul 2019 13:14

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Hallo,

Ich habe es geschafft noch mal in meine alten Sourcen zu schauen. Tatsächlich habe ich damals nicht nur die kopierte (Vcl.)Printer.pas anders benannt, sonder auch die Klassen, Typen und Konstanten umbenannt. Eigentlich sieht mir das jetzt mehr wie nachprogrammiert (was ich heute nicht mehr machen würde) aus.
Wenn man auf das TPrinter. PageNumber verzichten kann, ist Peter’s Variante mitunter einfacher. Es kommt auf die Umgebung an.
Ich bin jetzt noch auf eine Idee gekommen um das Problem mit abhängigen Units zu umgehen.

Delphi-Quellcode:
unit Vcl.Printers.Help;

interface

uses
  System.Classes;

var
  OnPrinterBetweenPage: TNotifyEvent;

implementation

end.
Delphi-Quellcode:
unit Vcl.Printers;
...
implementation

uses
...
  Vcl.Consts,
  Vcl.Printers.Help;
...
procedure TPrinter.NewPage;
begin
  CheckPrinting(True);
  EndPage(DC);
  if Assigned(OnPrinterBetweenPage) then
    OnPrinterBetweenPage(self);
  StartPage(DC);
  Inc(FPageNumber);
  Canvas.Refresh;
end;
Damit bleibt der Interface-Abschnitt von
Delphi-Quellcode:
Vcl.Printers
unverändert. Man würde dann vor dem Drucken dem
Delphi-Quellcode:
OnPrinterBetweenPage
eine Methode zuweisen und in dieser wenn nötig das Umschalten der Ausrichtung erledigen.

einbeliebigername.

haentschman 1. Jul 2019 14:18

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Moin...8-)
Zitat:

gibt es eine Möglichkeit innerhalb eines Druckauftrages von Portrait auf Landscape umzuschalten?
In den heutigen Zeiten von FastReport (in Delphi dabei und hat mit der Problemstellung keine Probleme :zwinker:) und Co. auf TPrinter zurückzugreifen ist imho "OldSchool" :zwinker: Wäre ein Reportgenenerator eine Alternative?

tomkupitz 2. Jul 2019 10:14

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Eine Lösung ist folgende Helper Klasse, die in die Vcl.Printers.pas eingebaut werden muss:

Delphi-Quellcode:
  ...

  TPrinterHelper = class Helper for TPrinter
  public
    procedure NewPageEx(Orientation: Integer);
  end;
  ...

[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinterHelper.NewPageEx(Orientation: Integer);
begin
  CheckPrinting(True);
  EndPage(DC);

  FDevMode^.dmOrientation:=Orientation; //DMORIENT_PORTRAIT DMORIENT_LANDSCAPE

  if ResetDC(Canvas.Handle, FDevMode^)=0 then
    Exit;

  StartPage(DC);
  Inc(FPageNumber);
  Canvas.Refresh;
end;
Aufruf dann:

Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
begin
  Printer.Orientation:=poPortrait;

  Printer.BeginDoc;

  Printer.Canvas.TextOut(100, 100, 'Seite 1');

  Printer.NewPageEx(DMORIENT_LANDSCAPE);

  Printer.Canvas.TextOut(100, 100, 'Seite 2');

  Printer.EndDoc;
end;
Beste Grüße

TurboMagic 2. Jul 2019 20:55

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Zitat:

Zitat von p80286 (Beitrag 1435631)
oder aber Du schickst die Druckersteuerdaten und die zu druckenden Daten direkt an den Drucker (falls das überhaupt noch geht?)

Ja das geht noch. Eine private Anwendung von mir steuert auf dem Weg ESC/P fähige Kassendrucker an, da diese Sonderfunktionen
haben die man mit normalem GDI Druck so m.W. nicht ansteuern kann: Bon Cut zum Beispiel.

TurboMagic 2. Jul 2019 20:58

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Vielleicht mag auch mal jemand in QP einen "feature request" für das Ursprüngliche Problem
des gewünschten Änderns der Seitenorientierung innerhalb eines Druckauftrages erstellen?

Damit in irgend einer Zukunft nichts mehr an printers.pas geändert werden muss...

Detlev 13. Nov 2021 20:22

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Ich habe die von Tomkupitz in #16 vorgeschlagene Lösung verwendet und es funktioniert! Erst mal vorab: Vielen Dank. Elegante Lösung!

Ich habe dazu natürlich eine lokale Kopie der Vcl.printers.pas in meinem Projektordner gespeichert. Delphi verwendet auch automatisch diese lokale Kopie.

Ich habe aber doch noch zwei Fragen, einfach um was dazu zu lernen:

(1)

Delphi Tokyo 10.2 gibt zahlreiche Warnmeldungen des Typs "[dcc32 Warnung] Vcl.Printers.pas(943): W1025 Sprach-Feature wird nicht unterstützt: 'Benutzerdefiniertes Attribut'" auf den Zeilen mit Attribut aus.

Kann ich die Warnungen einfach ignorieren? Was bedeuten sie überhaupt? Wieso werden die Attribute nicht unterstützt, wenn sie doch exakt so in der VCL.Printers stehen?

(2)

Ich habe eine analoge Lösung ausprobiert, bei der ich die Prozedur statt als Helper-Klasse direkt in TPrinter implementiere. Ansonsten exakt gleich. Geht aber nicht: Fataler Fehler beim Compilieren ohne Angabe einer Zeile.

Warum muss es ausgerechnet eine Helper-Klasse sein? Warum kann man nicht eine eigene Prozedur in TPrinter einfügen?! Ich möchte es nur gerne verstehen.

Code:
...
 public
    constructor Create;
    destructor Destroy; override;
    procedure Abort;
    procedure BeginDoc;
    procedure EndDoc;
    procedure NewPage;
    procedure NewPageWithOrientation(AOrientation: Integer); // added!
    procedure Refresh;
...
// original
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinter.NewPage;
begin
  CheckPrinting(True);
  EndPage(DC);
  StartPage(DC);
  Inc(FPageNumber);
  Canvas.Refresh;
end;

// added
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinter.NewPageWithOrientation(AOrientation: Integer);
begin
  CheckPrinting(True);
  EndPage(DC);

  FDevMode^.dmOrientation := AOrientation;

  StartPage(DC);
  Inc(FPageNumber);
  Canvas.Refresh;
end;

TurboMagic 14. Nov 2021 13:56

AW: TPrinter: Portrait auf Landscape umzuschalten
 
Keine Ahnung auf die Schnelle: aber existiert schon ein QP Report für die Problemstellung?
Kann, falls nicht, jemand den erstellen? Dann müssen wir in Zukunft evtl. keine eigenen
Bugfixes mehr anbringen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:46 Uhr.
Seite 2 von 3     12 3      

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