Einzelnen Beitrag anzeigen

Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#7

AW: Eigene Druckvorschau mit TMetafile und TImage

  Alt 5. Jan 2021, 07:35
Moin...
Delphi-Quellcode:

procedure TfmVorschau.CreateMetaFile;
begin
PrevMeta := TMetafile.Create;
PrevMeta.Enhanced := true;
PrevMeta.SetSize(PWidth,PHeight); //Größe des Metafiles, je nach Papierformat
PrevMetaCanvas := TMetafileCanvas.Create(PrevMeta,0); //Canvas erzeugen
PrintUtils.AktCanvas := PrevMetaCanvas; //aktuellen Canvas für Unit PrintUtils festlegen, diese enthält die Basisdruckroutinen
SetMapMode(AktCanvas.Handle,MM_TEXT);
SetTextAlign(AktCanvas.Handle,TA_BaseLine);
end;

...

procedure TfmVorschau.NewPage;
begin
//Freigabe des MetafileCanvas der VORHERIGEN Druckseite
PrevMetaCanvas.Free;
//PrevMeta.SaveToFile('D:\Test_Firebird_Server\' + IntToStr(AnzPages) + '.emf'); //diese Variante funktioniert

//Metafile der VORHERIGEN Druckseite in Objektliste ablegen und freigeben
MFList.Add(PrevMeta);
PrevMeta.Free;

//neue Seite erzeugen
Inc(AnzPages);
CreateMetafile; //neues Metafile für nächste Seite erzeugen
end;

//Abschlussprozedur nach dem Erzeugen der letzten Druckseite
procedure TfmVorschau.FinishPreview;
begin
PrevMetaCanvas.Free;
//PrevMeta.SaveToFile('D:\Test_Firebird_Server\' + IntToStr(AnzPages) + '.emf'); //siehe oben
MFList.Add(PrevMeta);
PrevMeta.Free;
end;
Unklarheiten:
Ich verstehe das so...Jede Seite besteht aus einem PrevMeta und immer einem PrevMetaCanvas?
1. Der MetaCanvas ist imho ein Teil des PrevMeta. Warum ist PrevMetaCanvas dann keine Property von PrevMeta? Das macht die Freigabe einfacher...
2. Warum nicht alle Druckseiten erzeugen und in die Liste legen? Und dann die Liste durchiterieren und drucken bzw. anzeigen?
3.
Delphi-Quellcode:
procedure TfmVorschau.FinishPreview;
begin
PrevMetaCanvas.Free; // Freigabe des Canvas
MFList.Add(PrevMeta); // MetaData in die Liste packen
PrevMeta.Free; // MetaData freigeben
end;
Warum erst in die Liste aufnehmen und gleich wieder freigeben? Erst am Ende die Liste komplett freigeben!
4. Bitte keine globalen Variablen.

Vorschlag (nur das Wichtigste):
Delphi-Quellcode:
interface
   // Muster
   TMetaFileOwn = class(TMetaFile) // oder so
   strict private
     FMetaFileCanvas: TMetaFileCanvas;
   public
     constructor Create;
     destructor Destroy; override;
     property MetaFileCanvas: TMetaFileCanvas read FMetaFileCanvas write FMetaFileCanvas
   end;
   // Muster

   TfmVorschau = class(TForm)
   strict private
     FAnzahlPages: Integer;
     FAktPage: Integer;
     FCurrentMetaData: TMetaData; // die aktuell gewählten Daten aus der Liste (Previous / Prior über Buttons etc.)
     FMFList: TObjectList<TMetaFileOwn>;
   public
   end;

var
  fmVorschau: TfmVorschau;

implementation

constructor TMetaFileOwn.Create;
begin
  inherited;
  FMetaFileCanvas := TMetaFileCanvas.Create(Self, 0); //Canvas erzeugen, Self = TMetaFile;
end;

destructor TMetaFileOwn.Destroy; override;
begin
  FMetaFileCanvas.Free;
end;

procedure TfmVorschau.FormCreate(Sender: TObject);
begin
  AktPage := 1;
  FMFList := TObjectList<TMetaFileOwn>.Create;
end;

procedure TfmVorschau.FormDestroy(Sender: TObject);
begin
  FinishPreview; // Liste leeren nicht nötig
  FMFList.Free; // Liste leeren macht Free sowieso...nur als Erklärung
end;

procedure TfmVorschau.CreateMetaFile;
begin
  FCurrentMetaData := TMetaFileOwn.Create;
  FCurrentMetaData.Enhanced := true;
  FCurrentMetaDataSetSize(PWidth, PHeight); //Größe des Metafiles, je nach Papierformat
  PrintUtils.AktCanvas := FCurrentMetaData.MetaFileCanvas; //aktuellen Canvas für Unit PrintUtils festlegen, diese enthält die Basisdruckroutinen
  SetMapMode(AktCanvas.Handle, MM_TEXT);
  SetTextAlign(AktCanvas.Handle, TA_BaseLine);
  FMFList.Add(FCurrentMetaData); // eine nach der Anderen in die Liste
end;

procedure TfmVorschau.NewPage;
begin
  CreateMetafile; //neues Metafile für nächste Seite erzeugen
  FAnzahlPages := FMFList.Count;
end;

procedure TfmVorschau.ShowPreview; // irgendwo müssen die Seiten auch angezeigt werden
begin
  Show(FMFList); // der Anzeigeprocedure die Liste übergeben
end;

procedure TfmVorschau.FinishPreview;
begin
  FMFList.Clear; // alle Objekte freigegeben
end;

Geändert von haentschman ( 5. Jan 2021 um 08:20 Uhr)
  Mit Zitat antworten Zitat