Newsgroup: it.comp.lang.delphi
Titolo: stampa ListView

chi saprebbe dirmi come si stampa la lista di un listview?
ciao e grazie
    Andrea

 chi saprebbe dirmi come si stampa la lista di un listview?
Di bello e pronto non c'č niente (credo). Ma forse in qualche componente
free sě...
Oppure potresti farti un semplicissimo ciclo che va a scrivere tutti gli
Item e relativi SubItems su Printer...
--
Jax

 free sì...


 anche un problema di compatibilità a seconda della stampante.
mmmmmmm........
se fai come dici te in effetti......
ma l'oggetto printer mette a disposizione molte funzionalità....puoi settare
la strampante da utilizzare (printer sfrutta la stampante predefinita di
default).... e poi con le apine e la struttura DEVMODE puoi fare molto...
molto di più.
Ho programmi distribuiti in tutto il mondo in centinaia di copie che lo
fanno e ti dico che incompatibilità non ce ne sono se non rarissimi casi
(fra l'altro risolti con le apine) con qualche stampante a trasferimento
termico, stampando anche grafica (etichette nella fattispecie).
Come nota.... io preferisco fare un bel Printer.BeginDoc e Printer.EndDoc, e
fra i due utilizzare la textout.
Non credo sia necessario... ma se qualcuno necessita di esempi... sono qui a
disposition :))))
CIAOUX

 chi saprebbe dirmi come si stampa la lista di un listview?
v. sotto un esempio (piuttosto sporco, si prega di non badare troppo
alla forma) facilmente adattabile anche ad una StringGrid
Saluti
Paolo Arosio
// ------------------- INIZIO CODICE --------------------------
(* ---------------------------------------------------------------------
----------
    PrintListView(Source: TListView; MarginsMM: TRect);
    stampa Source sulla stampante predefinita, con i margini indicati
(mm)
    usa Windows.DrawText per l'output (viewStyle = vsReport)
    Autore:
      Paolo Arosio          
paolo....@tiscalinet.it
    Data:
      8 AGOSTO 2000
   ---------------------------------------------------------------------
---------- *)
unit ListViewPrinterU;
interface
uses Windows, comctrls;
procedure PrintListView(Source: TListView; MarginsMM: TRect; Orizontal:
boolean = False);
implementation
uses
  SysUtils,
  Classes,
  Printers,
  graphics,
  CommCtrl;
const
  ColLines: boolean = False;
procedure PrintListView(Source: TListView; MarginsMM: TRect; Orizontal:
boolean = False);
{todo: gestire gli header (righe Fixed) in modo che siano bold}
{todo: gestire gli header (righe Fixed) in modo che siano ripetuti sulle
pagine successive alla prima}
var ColW: array of integer;       // ampiezza colonne (unitą stampante)
    NewPageCols: array of integer;// colonna da cui iniziare nuova
pagina
    PrintableRect: TRect;         // area da stampare
    VPos,                         // posizione verticale corrente e
    LineH: integer;               // altezza linea
    VertPageCount: integer;       // num. pagine necessarie per 1 riga
    GridH: integer;               // num righe * LineH (altezza griglia
in u. stampa)
    PageH: integer;               // altezza stampabile in u. stampa
  procedure InitLocalVars;
  const
    teststr = ' abcdefghijklmopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 012
3456 789 ';
  var i: integer;
      lp: integer;
      scrwid, prtwid, pgwid, totwid: integer;
  begin
    // Inizializza area stampabile, posizione verticale
    PrintableRect := Printer.Canvas.ClipRect;
    PrintableRect.Left := PrintableRect.Left +
      MulDiv(MarginsMM.Left * GetDeviceCaps(Printer.Canvas.Handle,
LOGPIXELSX), 10, 254);
    PrintableRect.Right := PrintableRect.Right -
      MulDiv(MarginsMM.Right * GetDeviceCaps(Printer.Canvas.Handle,
LOGPIXELSX), 10, 254);
    PrintableRect.Top := PrintableRect.Top +
      MulDiv(MarginsMM.Top * GetDeviceCaps(Printer.Canvas.Handle,
LOGPIXELSY), 10, 254);
    PrintableRect.Bottom := PrintableRect.Bottom -
      MulDiv(MarginsMM.Bottom * GetDeviceCaps(Printer.Canvas.Handle,
LOGPIXELSY), 10, 254);
    LineH := MulDiv(Printer.Canvas.TextHeight(teststr), 115, 100);
    VPos := PrintableRect.Top;
    // Calcola larghezza colonne
    totwid := 0;
    pgwid := PrintableRect.Right - PrintableRect.Left;
    scrWid := Source.Canvas.TextWidth(teststr);
    prtWid := Printer.Canvas.TextWidth(teststr);
    SetLength(ColW, Source.Columns.Count);
    for i := 0 to High(ColW) do begin
      //-- ColW[i] := MulDiv(Source.Columns[i].Width, prtWid, scrWid);
      ColW[i] := MulDiv(ListView_GetColumnWidth(Source.Handle, i),
prtWid, scrWid);
      totwid := totwid + ColW[i];
    end;
    // riduce larghezza colonne se la larghezza supera di meno del 10%
la larghezza pagina
    if totwid > PrintableRect.Right-PrintableRect.Left then begin
      if totwid / pgwid <= 1.1 then begin
        for i := 0 to High(ColW) do begin
          ColW[i] := MulDiv(ColW[i], pgwid, totwid) - 1;
        end;
      end;
    end;
    // Calcola numero pagine necessarie alla stampa in orizzontale
    {todo: gestire le colonne Fixed in modo che le stampi anche sulle
pagine successive}
    VertPageCount := 1;
    lp := PrintableRect.Left;
    SetLength(NewPageCols, VertPageCount);
    NewPageCols[High(NewPageCols)] := Source.Columns.Count;
    for i := 0 to High(ColW) do begin
      if lp + ColW[i] > PrintableRect.Right then begin
        inc(VertPageCount);
        lp := PrintableRect.Left;
        NewPageCols[High(NewPageCols)] := i;
        SetLength(NewPageCols, VertPageCount);
        NewPageCols[High(NewPageCols)] := Source.Columns.Count;
      end
      else
        lp := lp + ColW[i];
    end;
    // se singola pagina, espande per occuparla tutta
    if (VertPageCount = 1) and (lp < PrintableRect.Right) then begin
      for i := 0 to High(ColW) do begin
        ColW[i] := MulDiv(ColW[i], PrintableRect.Right, lp);
      end;
    end;
    // se + di una pagina
    // tenta riduzione sino al 15 %
    GridH := Source.Items.Count * (LineH + 1);
    PageH := PrintableRect.Bottom - PrintableRect.Top;
    if (GridH > PageH) then
      if (GridH < MulDiv(PageH, 115, 100)) then
        LineH := MulDiv(LineH, PageH, GridH);
  end;
  procedure PrintRow(index: integer; VertPage: integer);forward;
  procedure PrintRowLine;
  begin
    Printer.Canvas.MoveTo(PrintableRect.Left, VPos - LineH div 6);
    Printer.Canvas.LineTo(PrintableRect.Right, VPos - LineH div 6);
  end;
  procedure PrintColHeaders(vp: integer);
  begin
    Printer.Canvas.Font.Style := [fsBold];
    PrintRow(-1, vp);
    Printer.Canvas.Font.Style := [];
    VPos := VPos + LineH div 3;
  end;
  procedure PrintColLines(vp: integer);
  var FirstCol, c, x: integer;
  begin
    Printer.Canvas.Pen.Width := 1;
    Printer.Canvas.Pen.Style := psSolid;
    FirstCol := 0;
    if vp > 0 then
      FirstCol := NewPageCols[vp - 1];
    x := PrintableRect.Left;
    for c := FirstCol to NewPageCols[vp] do begin
      Printer.Canvas.MoveTo(x, PrintableRect.Top);
      Printer.Canvas.LineTo(x, PrintableRect.Bottom);
      x := x + ColW[c];
    end;
  end;
  procedure PrintRow(index: integer; VertPage: integer);
  {todo: allineamento a sx per testo, a dx per numeri:
    serve probabilmente una proprietą associata alle colonne di Source}
  var FirstCol: integer;
      c: integer;
      s: string;
      r: TRect;
      Flags: Cardinal;
  begin
    if VPos > PrintableRect.Bottom then begin
      Printer.NewPage;
      VPos := PrintableRect.Top;
      PrintColHeaders(VertPage);
      if ColLines then
        PrintColLines(VertPage);
    end;
    FirstCol := 0;
    if VertPage > 0 then
      FirstCol := NewPageCols[VertPage - 1];
    r := Rect(PrintableRect.Left, VPos, PrintableRect.Left, VPos +
LineH);
    if index < 0 then
      r.Bottom := r.Bottom + LineH div 2;
    for c := FirstCol to NewPageCols[VertPage]-1 do begin
      r.Right := r.Left + ColW[c];
      InflateRect(r, -4, -2);
      {
      if (index = 0) or (c = 0) then
        Flags := DT_CENTER or DT_WORDBREAK or DT_EDITCONTROL
      else
      }
        Flags := DT_LEFT or DT_WORDBREAK or DT_EDITCONTROL;
      if index < 0 then begin
        s := Source.Columns[c].Caption;
      end
      else begin
        if c = 0 then
          s := Source.Items[index].Caption
        else
          s := Source.Items[index].SubItems[c-1];
      end;
      DrawText(Printer.Canvas.Handle, PChar(s), -1, r, Flags);
      InflateRect(r, 4, 2);
      r.Left := r.Left + ColW[c];
    end;
    VPos := VPos + LineH;
    if ((index + 1) mod 5) = 0 then
      PrintRowLine;
  end;
  procedure FinitLocalVars;
  begin
    Finalize(ColW);
    Finalize(NewPageCols);
  end;
var vp, r: integer;
begin
  if Orizontal then
    Printer.Orientation := poLandscape
  else
    Printer.Orientation := poPortrait;
  Printer.Title := FormatDateTime('"List"hhnnss', Now);
  Printer.BeginDoc;
 
Printer.Canvas.Font.Name
 := 'Arial';
  Printer.Canvas.Font.Size := 8;
  Printer.Canvas.Font.Style := [];
  try
    InitLocalVars;
    try
      for vp := 0 to VertPageCount-1 do begin
        if vp > 0 then begin
          Printer.NewPage;
          VPos := PrintableRect.Top;
        end;
        PrintColHeaders(vp);
        if ColLines then
          PrintColLines(vp);
        for r := 0 to Pred(Source.Items.Count) do
          PrintRow(r, vp);
      end;
    finally
      FinitLocalVars;
    end;
  finally
    Printer.EndDoc;
  end;
end;
end.