Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Listview drucken, Zeilen beim Ausdruck färben (https://www.delphipraxis.net/181959-listview-drucken-zeilen-beim-ausdruck-faerben.html)

dr. jack1 20. Sep 2014 16:43


Listview drucken, Zeilen beim Ausdruck färben
 
Hallo zusammen,

ich möchte eine Listview ausdrucken aber das Ganze mit grau gefärbten Zeilen.

Mit dem ListViewCustomDrawItem kann ich es wie gewünscht darstellen (weiß-grau-weiß-grau), jedoch erfolgt der Ausdruck ohne die Zeilenfärbung. Hat jemand eine Idee wie das geht?

Google war leider nicht mein Freund bzw. habe ich nur gefunden wie Listviews gefärbt werden...

Danke :)

Andreas L. 20. Sep 2014 19:22

AW: Listview drucken, Zeilen beim Ausdruck färben
 
Hi dr. jack1,

wie druckst du die ListView? Ohne Code kann man da nicht viel sagen... ;)

EDIT: Kopierst du das ListView.Canvas auf das Printer.Canvas?

Luckie 20. Sep 2014 20:46

AW: Listview drucken, Zeilen beim Ausdruck färben
 
Nimm eine Report Komponente oder zeichne/schreibe selbst auf den Drucker Canvas. Ich gehe mal davon aus, dass die Daten nicht im Listview gespeichert sind.

dr. jack1 20. Sep 2014 21:25

AW: Listview drucken, Zeilen beim Ausdruck färben
 
Das wäre der Code zum Drucken. SO tief stecke ich leider nicht in der Materie um hier noch eine Färbung einfügen zu können.

Delphi-Quellcode:
procedure Ttfg_druck.BitBtn7Click(Sender: TObject);
var
   pWidth, pHeight, i: Integer;
   v, h: Real;
   CurItem, iColumnCount: Integer;
   //aCols: array[0..50] of Integer; // Delphi 3
   aCols: array of Integer; // Delphi 5
   iTotColsWidth, iInnerWidth, TopMarg, LinesOnPage, CurLine, TekstHeight, CurCol: Integer;
   CurRect: TRect;
   CurStr: string;
   CurLeft, NumPages, TmpPos: Integer;
   lvTitel: string;

   begin
       begin
   if PrintDialog1.Execute then
   begin

     iColumnCount := listview1.Columns.Count;
     SetLength(aCols, iColumnCount + 1); // + 1 nodig ??? Delphi 5
     Printer.Title := 'TFG Monatsausdruck';
     Printer.Copies := 1;
     Printer.Orientation := poLandscape;
     Printer.BeginDoc;
     pHeight := Printer.PageHeight;
     pWidth := Printer.PageWidth;

     v := (pHeight + (2 * GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY))) / 21;
     //0.95 is a strange correction factor on the clients printer
     h := (pWidth + (2 * GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX))) /(29.7 * 0.95);

     // calculate total width
     iTotColsWidth := 0;
     for i := 0 to iColumnCount - 1 do
       iTotColsWidth := iTotColsWidth + listview1.Columns[i].Width;

     // calculate space between lMargin and rMargin
    aCols[0] := Round(1.5 * h); //left margin ?
    aCols[iColumnCount + 0] := pWidth - Round(1.5 * h); //rigth margin ?
    iInnerWidth := aCols[iColumnCount + 0] - aCols[0]; // space between margins ?

     //calculate start of each column
     for i := 0 to iColumnCount - 1 do
       aCols[i + 1] := aCols[i] + Round(listview1.Columns[i].Width / iTotColsWidth * iInnerWidth);
     TopMarg := Round(2.5 * v);
     with Printer.Canvas do
     begin
       Font.Size := 8;
       Font.Style := [];
       Font.Name := 'Calibri';
       Font.Color := RGB(0, 0, 0);
       TekstHeight := Printer.Canvas.TextHeight('dummy');
       LinesOnPage := Round((PHeight - (5 * v)) / TekstHeight);
       NumPages := 1;

       // gather number of pages to print
       while (NumPages * LinesOnPage) < listview1.Items.Count do
         inc(NumPages);
       // start
       CurLine := 0;
       for CurItem := 0 to listview1.Items.Count - 1 do
       begin
         if (CurLine > LinesOnPage) or (CurLine = 0) then
         begin
           if (CurLine > LinesOnPage) then Printer.NewPage;
           CurLine := 1;
           if Printer.PageNumber = NumPages then
           begin
             MoveTo(aCols[1], topMarg);
             for i := 1 to iColumnCount - 1 do
             begin
               LineTo(aCols[i], TopMarg + (TekstHeight * (listview1.Items.Count - CurItem + 2)));
               MoveTo(aCols[i + 1], topMarg);
             end;
           end
           else
           begin
             // draw vertical lines between data
             for i := 1 to iColumnCount - 1 do
             begin
               MoveTo(aCols[i], topMarg);
               LineTo(aCols[i], TopMarg + (TekstHeight * (LinesOnPage + 1)));
             end;
           end;

           Font.Style := [fsBold];
           // print column headers
           for i := 0 to iColumnCount - 1 do
           begin
             TextRect(Rect(aCols[i] + Round(0.1 * h), TopMarg - Round(0.1 * v), aCols[i + 1] - Round(0.1 * h)
               , TopMarg + TekstHeight - Round(0.1 * v)), ((aCols[i + 1] - aCols[i]) div 2) +
               aCols[i] - (TextWidth(listview1.Columns.Items[i].Caption) div 2),
               TopMarg - Round(0.1 * v), listview1.Columns.Items[i].Caption);
             //showmessage('print kolom: '+IntToStr(i));
           end;

           // draw horizontal line beneath column headers
           MoveTo(aCols[0] - Round(0.1 * h), TopMarg + TekstHeight - Round(0.05 * v));
           LineTo(aCols[iColumnCount] + Round(0.1 * h), TopMarg + TekstHeight - Round(0.05 * v));

           // print date and page number
           Font.Size := 8;
           Font.Style := [];
           TmpPos := (TextWidth('Datum: ' + DateToStr(Date) + ' Seite: ' +
             IntToStr(Printer.PageNumber) + ' / ' + IntToStr(NumPages))) div 2;

           TmpPos := PWidth - Round(1.5 * h) - (TmpPos * 2);

           Font.Size := 8;
           Font.Style := [];
           TextOut(TmpPos, Round(0.5 * v), 'Datum: ' + DateToStr(Date) +
             ' Seite: ' + IntToStr(Printer.PageNumber) + ' / ' + IntToStr(NumPages));

           // print report title
           Font.Size := 18;
           if TmpPos < ((PWidth + TextWidth(lvTitel)) div 2 + Round(0.75 * h)) then
             TextOut((PWidth - TextWidth(lvTitel)) div 2, Round(1 * v), lvTitel)
           else
             TextOut(Round(3 * h), Round(1 * v), lvTitel);

           Font.Size := 8;
           Font.Style := [];
         end;

         CurRect.Top := TopMarg + (CurLine * TekstHeight);
         CurRect.Bottom := TopMarg + ((CurLine + 1) * TekstHeight);

         // print contents of Listview
         for CurCol := -1 to iColumnCount - 2 do
         begin
           CurRect.Left := aCols[CurCol + 1] + Round(0.1 * h);
           CurRect.Right := aCols[CurCol + 2] - Round(0.1 * h);
           try
             if CurCol = -1 then

                  CurStr := listview1.Items[CurItem].Caption
             else
                  CurStr := listview1.Items[CurItem].SubItems[CurCol]
           except
             CurStr := ' ';
           end;
           CurLeft := CurRect.Left; // align left side
           // write string in TextRect
           TextRect(CurRect, CurLeft, CurRect.Top, CurStr);
         end;
         Inc(CurLine);
       end;
     end;
     Printer.EndDoc;
   end;
end;


end;

Luckie 20. Sep 2014 21:44

AW: Listview drucken, Zeilen beim Ausdruck färben
 
Teil den Spaghetti Code erst mal in einzelne Prozeduren auf. Am besten in einer Klasse kapseln, damit du keine globalen Variablen brauchst. So steigt man da ja kaum durch.

DP-Maintenance 20. Sep 2014 21:45

Dieses Thema wurde am "20. Sep 2014, 22:45 Uhr" von "Luckie" aus dem Forum "Algorithmen, Datenstrukturen und Klassendesign" in das Forum "GUI-Design mit VCL / FireMonkey / Common Controls" verschoben.

dr. jack1 21. Sep 2014 16:14

AW: Listview drucken, Zeilen beim Ausdruck färben
 
Joar der Spaghetti Code ist so recht lang, aber er funktioniert. Habe ihn, ehrlich gesagt, auch nur kopiert.
Das Färben bekomme ich nicht hin, weil (ganz unten) der Code pro Spalte ausgelesen wird, nicht zeilenweise :(
Hat da jemand eine Idee wie es funktionieren könnte?

Luckie 21. Sep 2014 20:10

AW: Listview drucken, Zeilen beim Ausdruck färben
 
Zeilenweise auf den Canvas vom Drucker ausgeben und nicht spaltenweise.

Und er mag ja funktionieren, aber wie man sieht, verstehst du ihn selber nicht. Deswegen mal übersichtlich aufteilen, dann kann man ihn auch einfacher modifizieren.

Puke 21. Sep 2014 21:29

AW: Listview drucken, Zeilen beim Ausdruck färben
 
Vermutung :glaskugel::
Imho muss nur ein
Delphi-Quellcode:
brush.color := clGrey;
eingefügt werden. Aber ohne Gewähr ...

Captnemo 22. Sep 2014 07:10

AW: Listview drucken, Zeilen beim Ausdruck färben
 
Er mag unten zwar spaltenweise ausgegeben werden,
aber vorher wird ja Zeile für Zeile diese "spaltenweise" Ausgabe in einer Schleife durchgeführt
Delphi-Quellcode:
       for CurItem := 0 to listview1.Items.Count - 1 do
        begin
          if (CurLine > LinesOnPage) or (CurLine = 0) then
und (zumindest in diesem Code)
könntest du hier
Delphi-Quellcode:
         for CurCol := -1 to iColumnCount - 2 do
          begin
            CurRect.Left := aCols[CurCol + 1] + Round(0.1 * h);
            CurRect.Right := aCols[CurCol + 2] - Round(0.1 * h);
            try
              if CurCol = -1 then

                   CurStr := listview1.Items[CurItem].Caption
              else
                   CurStr := listview1.Items[CurItem].SubItems[CurCol]
            except
              CurStr := ' ';
            end;
            CurLeft := CurRect.Left; // align left side
            // write string in TextRect

            if (CurLine mod 2 = 0)        //Abhängig davon, ob Curline gerade oder ungerade
              brush.color = clWhite else  //ist, die brush.color des Canvas setzen
              brush.color = clGray;
            FillRect(CurRect);            //Dann einfach mal ein gefülltes Rechteck Zeichnen
                                           //ggf. könnten noch Linien für die Zeilentrennung oder
                                           //Spaltentrennung gezeichnet werden

            TextRect(CurRect, CurLeft, CurRect.Top, CurStr);
          end;
Macht den Code zwar nicht besser, aber so würd's gehen.

Aber ich muss allen Anderen hier zustimmen. Teil dir den Code erst mal in Procedure und Funktionen auf, damit er lesbar wird.
Mach dir ne Klasse dafür, dann kannst du die Variablen besser überschauen, weil Sie dann zu der Klasse gehören.

Der Vorteil, nach dem du das in eine Klasse gepackt hast, oder das in Funktionen oder Proceduren aufgeteilt hast, ist, dass du auch genau weißt was du tust und warum, und dir die Frage nach der Position einer solchen Änderung ganz allein beantworten kannst. Abgesehen davon, dass du sie auch leichter wiederfindest :-)
Denn was ich daran sehr zu schätzen gelernt habe, ist die Tatsache, dass man bei späteren Änderungen mit [CTRL]+[linke Maustaste] dann recht schnell in eine verwendete Funktion, eine verwendete Procedure und deren Deklarationen springen kann. Ein Vorteil, der einem nicht nur das Suchen erspart, sondern auch Unmengen an Zeit.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:54 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