{*****************************************************************************
  This file is part of the Lazarus Component Library (LCL)

  See the file COPYING.modifiedLGPL.txt, included in this distribution,
  for details about the license.
 *****************************************************************************

  Author: Olivier GUILBAUD

  Abstract:
    Little sample for show how to use PrintersDlgs unit

------------------------------------------------------------------------------}
unit frmselprinter;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Types, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
  PrintersDlgs, StdCtrls, Grids, Menus, EditBtn, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    btnTPrintDialog: TButton;
    Button2: TButton;
    Button3: TButton;
    btnDirectPrint: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    btnRotateBin: TButton;
    btnRestoreDefaultBin: TButton;
    btnPrintWithDlg: TButton;
    chkNativeDlg: TCheckBox;
    chkAsSheet: TCheckBox;
    chkOutputFile: TCheckBox;
    chkTestImgs: TCheckBox;
    cbPrinters: TComboBox;
    cbPapers: TComboBox;
    comboTests: TComboBox;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    txtPageSetupDlgTitle: TEdit;
    txtPrinterSetupDlgTitle: TEdit;
    txtPrintDialogTitle: TEdit;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    txtOutputFile: TFileNameEdit;
    Label1: TLABEL;
    PAGED: TPageSetupDialog;
    PD: TPrintDialog;
    PopupMenu1: TPopupMenu;
    PSD: TPrinterSetupDialog;
    SGrid: TStringGrid;
    procedure btnPrintWithDlgClick(Sender: TObject);
    procedure btnTPrintDialogClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure btnDirectPrintClick(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure btnRotateBinClick(Sender: TObject);
    procedure btnRestoreDefaultBinClick(Sender: TObject);
    procedure cbPapersSelect(Sender: TObject);
    procedure cbPrintersSelect(Sender: TObject);
    procedure comboTestsSelect(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure SGridSelectCell(Sender: TObject; aCol, aRow: Integer;
      var CanSelect: Boolean);
  private
    ck : Integer;
    procedure OnPrintDialogAsSetupResult(sender: TObject; Success: boolean);
    procedure OnPrintSetupDialogResult(sender: TObject; Success: boolean);
    procedure UpdatePrinterInfo;
    procedure AddInfo(const Desc : String; Const Info : String);
    procedure DrawGraphic(X,Y,AWidth,AHeight:Integer; Graphic: TGraphic);
    function CM(Avalue: Double; VertRes:boolean=true): Integer;
    function MM(AValue: Double; VertRes:boolean=true): Integer;
    function Inch(AValue: Double; VertRes:boolean=true): Integer;
    function Per(AValue: Double; VertRes:boolean=true): Integer;
    procedure CenterText(const X,Y: Integer; const AText: string);
    function FormatDots(Dots: Integer):string;
    procedure PrintSamplePage(PrintImgs:boolean);
    procedure PrintMultiPage;
    procedure PrintMultiPageMultiPaper;
    procedure PrintRulersPage;
    procedure PrintTest;
  public
  
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation
uses
  Printers,OsPrinters,LCLType,LClProc;

{$R *.lfm}

const
  PAGE_COUNT = 2;
  MULTIPAPER_COUNT = 4;
  {$ifdef Darwin}
  PAPER_LEGAL   = 'US Legal';
  PAPER_LETTER  = 'US Letter';
  {$else}
  PAPER_LEGAL   = 'Legal';
  PAPER_LETTER  = 'Letter';
  {$endif}


{ TForm1 }

procedure TForm1.AddInfo(const Desc: String; const Info: String);
begin
  SGrid.Cells[0,ck] := Desc;
  SGrid.Cells[1,ck] := Info;
  Inc(ck);
end;

procedure TForm1.DrawGraphic(X, Y, AWidth, AHeight: Integer; Graphic: TGraphic);
var
  Ratio: Double;
begin
  if (AWidth<=0) or (AHeight<=0) then begin
    if Graphic.Width=0 then
      ratio := 1
    else
      ratio := Graphic.Height/Graphic.Width;
    if AWidth<=0 then
      AWidth := round(AHeight/ratio)
    else
    if AHeight<=0 then
      AHeight := round(AWidth * ratio);
  end;

  if (AWidth>0) and (AHeight>0) then
    Printer.Canvas.StretchDraw(Bounds(X,Y,AWidth,AHeight), Graphic);
end;

function TForm1.CM(Avalue: Double; VertRes: boolean=true): Integer;
begin
  result := MM(AValue*10, vertRes);
end;

function TForm1.MM(AValue: Double; VertRes:boolean=true): Integer;
begin
  if VertRes then
    result := Round(AValue*Printer.YDPI/25.4)
  else
    result := Round(AValue*Printer.XDPI/25.4);
end;

function TForm1.Inch(AValue: Double; VertRes:boolean=true): Integer;
begin
  if VertRes then
    result := Round(AValue*Printer.YDPI)
  else
    result := Round(AValue*Printer.XDPI);
end;

function TForm1.Per(AValue: Double; VertRes:boolean=true): Integer;
begin
  if VertRes then
    result := Round(AValue*Printer.PageHeight/100)
  else
    result := Round(AValue*Printer.PageWidth/100);
end;

procedure TForm1.CenterText(const X, Y: Integer; const AText: string);
var
  Sz: TSize;
begin
  Sz := Printer.Canvas.TextExtent(AText);
  //WriteLn('X=',X,' Y=',Y,' Sz.Cx=',Sz.Cx,' Sz.Cy=',Sz.Cy);
  Printer.Canvas.TextOut(X - Sz.cx div 2, Y - Sz.cy div 2, AText);
end;

function TForm1.FormatDots(Dots: Integer): string;
begin
  result := format('%d dots (%f mm, %f in)',[Dots, Dots*25.4/Printer.YDPI, Dots/Printer.YDPI]);
end;

procedure TForm1.PrintSamplePage(PrintImgs: boolean);
var
  Pic: TPicture;
  pgw,pgh: Integer;
  Hin: Integer; // half inch
begin
  try
    Printer.Title := 'Printer test for printers4lazarus package';
    if chkOutputFile.Checked then
      Printer.FileName := txtOutputFile.FileName
    else
      Printer.FileName := '';
    Printer.BeginDoc;

    // some often used consts
    pgw := Printer.PageWidth;
    pgh := Printer.PageHeight;
    Hin := Inch(0.5);
    //DebugLn('Page width=%d height=%d',[pgw, pgh]);

    // center title text on page width
    Printer.Canvas.Font.Size := 12;
    Printer.Canvas.Font.Color:= clBlue;
    CenterText(pgw div 2, CM(0.5), 'This is test for lazarus printer4lazarus package');

    // print margins marks, assumes XRes=YRes
    Printer.Canvas.Pen.Color:=clBlack;
    Printer.Canvas.Line(0, HIn, 0, 0);            // top-left
    Printer.Canvas.Line(0, 0, HIn, 0);

    Printer.Canvas.Brush.Color := clSilver;
    Printer.Canvas.EllipseC(Hin,Hin,Hin div 2,Hin div 2);
    CenterText(Hin, Hin, '1');

    Printer.Canvas.Pen.Color := clRed;
    Printer.Canvas.Pen.Width := 1;
    Printer.Canvas.Frame(0,0,pgw,pgh);

    Printer.Canvas.Pen.Color := clBlack;
    Printer.Canvas.Pen.Width := 3;
    Printer.Canvas.Line(0, pgh-HIn, 0, pgh);      // bottom-left
    Printer.Canvas.Line(0, pgh, HIn, pgh);
    Printer.Canvas.Line(pgw-Hin, pgh, pgw, pgh);  // bottom-right
    Printer.Canvas.Line(pgw,pgh,pgw,pgh-HIn);
    Printer.Canvas.Line(pgw-Hin, 0, pgw, 0);      // top-right
    Printer.Canvas.Line(pgw,0,pgw,HIn);

    // Image test
    if PrintImgs then
    begin
      Pic := TPicture.Create;
      Pic.LoadFromFile('../../../../images/splash_logo.png');
      // draw logo scaled down to 7 centimeters wide preserving image aspect
      DrawGraphic(CM(1.5), CM(1.5), MM(70), 0, Pic.Graphic);
      // left 3 mm at the right and do it again but using 2 inch tall image
      DrawGraphic(CM(1.5+7)+MM(3), CM(1.5), 0, Inch(2), Pic.Graphic);
      Pic.Free;
    end;

    Printer.EndDoc;

  except
    on E:Exception do
    begin
      Printer.Abort;
      Application.MessageBox(pChar(e.message),'Error',mb_iconhand);
    end;
  end;

  UpdatePrinterInfo;
end;

procedure TForm1.PrintMultiPage;
const
  ColorArray: array[1..PAGE_COUNT] of TColor = (clAqua, clLime);
var
  {%H-}pgw, {%H-}pgh, Hin, Page: Integer;
  R: TRect;
  te: TTextStyle;
begin
  try
    Printer.Title := 'Multipage Sample';

    if chkOutputFile.Checked then
      Printer.FileName := txtOutputFile.FileName
    else
      Printer.FileName := '';

    Printer.BeginDoc;

    // some often used consts
    pgw := Printer.PageWidth-1;
    pgh := Printer.PageHeight-1;
    Hin := Inch(0.5);

    Te := Printer.Canvas.TextStyle;
    Te.Alignment := taCenter;
    Te.Layout := tlCenter;

    Printer.Canvas.Font.Size:=20;

    for Page:=1 to PAGE_COUNT do begin
      Printer.Canvas.Pen.Color := clBlack;
      Printer.Canvas.Brush.Color := ColorArray[Page];
      R := Rect(0, 0, 3*Hin, Hin);
      Printer.Canvas.Rectangle(R);
      Printer.canvas.TextRect(R, R.Left, R.Top, format('Page %d',[Page]), Te);
      if Page<>PAGE_COUNT then
        Printer.NewPage;
    end;

    Printer.EndDoc;

  except
    on E:Exception do
    begin
      Printer.Abort;
      Application.MessageBox(pChar(e.message),'Error',mb_iconhand);
    end;
  end;

end;

procedure TForm1.PrintMultiPageMultiPaper;
const
  ColorArray: array[1..MULTIPAPER_COUNT] of TColor = (clAqua, clLime, clFuchsia, clYellow);
  PaperArray: array[1..MULTIPAPER_COUNT] of string[20] = (PAPER_LETTER{dummy}, PAPER_LEGAL, 'A4', PAPER_LETTER);
var
  {%H-}pgw, {%H-}pgh, Hin, Page: Integer;
  R: TRect;
  te: TTextStyle;
begin
  try
    Printer.Title := 'Multipapers Sample';

    if chkOutputFile.Checked then
      Printer.FileName := txtOutputFile.FileName
    else
      Printer.FileName := '';

    Printer.BeginDoc;

    // some often used consts
    pgw := Printer.PageWidth-1;
    pgh := Printer.PageHeight-1;
    Hin := Inch(0.5);

    Te := Printer.Canvas.TextStyle;
    Te.Alignment := taCenter;
    Te.Layout := tlCenter;

    Printer.Canvas.Font.Size:=20;
    Page := 1;
    while Page<=MULTIPAPER_COUNT do begin
      Printer.Canvas.Pen.Color := clBlack;
      Printer.Canvas.Brush.Color := ColorArray[Page];
      R := Rect(0, 0, 5*Hin, Hin);
      Printer.Canvas.Rectangle(R);
      Printer.canvas.TextRect(R, R.Left, R.Top, format('Page %d: %s',[Page, Printer.PaperSize.PaperName]), Te);
      if Page<>MULTIPAPER_COUNT then begin
        Printer.EndPage;
        Printer.PaperSize.PaperName := PaperArray[Page+1];
        //Printer.Orientation := PaperOrArray[Page+1];  // needs fixing under macOS, should work under windows
        Printer.BeginPage;
      end;
      inc(page);
    end;

    Printer.EndDoc;

  except
    on E:Exception do
    begin
      Printer.Abort;
      Application.MessageBox(pChar(e.message),'Error',mb_iconhand);
    end;
  end;

end;

procedure TForm1.PrintRulersPage;
const
  LONG_LINE   = 3.0;
  MID_LINE    = 2.1;
  SMALL_LINE  = 1.3;
var
  pgw, pgh, oldFontSize: Integer;
  h, w: Double;
  oldStyle: TBrushStyle;
  ts: TSize;
  procedure DrawVertRuler(x: double);
  var
    y: double;
    lSize: double;
  begin
    Printer.Canvas.Line(mm(x), 0, mm(x), mm(h));
    y := 0.0;
    Printer.Canvas.TextOut( MM(x - LONG_LINE) - ts.cx - 3, MM(y) - ts.cy div 2, format('%3.0f',[y]));
    while y<h do begin
      if trunc(y) mod 10 = 0 then lSize := LONG_LINE else
      if trunc(y) mod 5 = 0 then  lSize := MID_LINE
      else                        lSize := SMALL_LINE;
      Printer.Canvas.Line( MM(x - lSize), MM(y), MM(x + lSize)+1, MM(y) );
      y := y + 1.0;
      if trunc(y) mod 10 = 0 then
        Printer.Canvas.TextOut( MM(x - lSize) - ts.cx - 3, MM(y) - ts.cy div 2, format('%3.0f',[y]));
    end;
  end;
  procedure DrawHorzRuler(y: double);
  var
    x: double;
    lSize: double;
  begin
    Printer.Canvas.Line(0, mm(y), mm(w), mm(y));
    x := 0.0;
    Printer.Canvas.TextOut( MM(x) - ts.cx div 2, MM(y + LONG_LINE) + ts.cy + 3, format('%3.0f',[x]));
    while x<w do begin
      if trunc(x) mod 10 = 0 then lSize := LONG_LINE else
      if trunc(x) mod 5 = 0 then  lSize := MID_LINE
      else                        lSize := SMALL_LINE;
      Printer.Canvas.Line( MM(x), MM(y - lSize), MM(x), MM(y + lSize)+1);
      x := x + 1.0;
      if trunc(x) mod 10 = 0 then
        Printer.Canvas.TextOut( MM(x) - ts.cx div 2, MM(y + LONG_LINE) + 3, format('%3.0f',[x]));
    end;
  end;
begin
  try
    Printer.Title := 'printers4lazarus Rulers sample page';
    if chkOutputFile.Checked then
      Printer.FileName := txtOutputFile.FileName
    else
      Printer.FileName := '';

    Printer.BeginDoc;

    // for testing high resolution printing, where available.
    Printer.Canvas.Font.Size := 6;
    Printer.Canvas.Font.Color := clBlack;
    Printer.Canvas.Brush.Style := bsClear;
    Printer.Canvas.Pen.Width := 1;
    Printer.Canvas.Pen.Color := clBlack;
    pgw := Printer.PageWidth;
    pgh := Printer.PageHeight;

    h := pgh*25.4/Printer.YDPI;
    w := pgw*25.4/Printer.XDPI;
    ts := Printer.Canvas.TextExtent('000');

    DrawVertRuler( w/2 );
    DrawHorzRuler( h/2 );

    Printer.EndDoc;

  except
    on E:Exception do
    begin
      Printer.Abort;
      Application.MessageBox(pChar(e.message),'Error',mb_iconhand);
    end;
  end;

  UpdatePrinterInfo;
end;

procedure TForm1.UpdatePrinterInfo;
var
  i: Integer;
  s: string;
  hRes,vRes: Integer;
begin
  try
    cbPrinters.Clear;
    cbPapers.Clear;
    ck := SGrid.FixedRows;
    SGrid.Clean;
    with Printer do
    begin
      if Printers.Count=0 then
      begin
        AddInfo('printer', 'no printers are installed');
        exit;
      end;
      cbPrinters.Items.Assign(Printers);
      cbPrinters.ItemIndex := PrinterIndex;

      cbPapers.items.Assign(PaperSize.SupportedPapers);
      if cbPapers.items.Count>0 then
      begin
        s := PaperSize.PaperName;
        i := cbPapers.Items.IndexOf(s);
        cbPapers.ItemIndex := i;
      end;

      AddInfo('Printer',Printers[PrinterIndex]);
      case Orientation of
        poPortrait : AddInfo('Orientation','Portrait');
        poLandscape : AddInfo('Orientation','Landscape');
        poReverseLandscape : AddInfo('Orientation','ReverseLandscape');
        poReversePortrait  :AddInfo('Orientation','ReversePortrait');
      end;
      case PrinterType of
        ptLocal: AddInfo('PrinterType','Local');
        ptNetWork: AddInfo('PrinterType','Network');
      end;
      case PrinterState of
        psNoDefine: AddInfo('PrinterState','Undefined');
        psReady:AddInfo('PrinterState','Ready');
        psPrinting:AddInfo('PrinterState','Printing');
        psStopped:AddInfo('PrinterState','Stopped');
      end;
      hRes := XDPI;
      vRes := YDPI;
      AddInfo('Resolution X,Y', format('%d,%d dpi',[hRes,vRes]));
      AddInfo('PaperSize',PaperSize.PaperName);
      with Printer.PaperSize.PaperRect.PhysicalRect do
      begin
        AddInfo('Paper Width', FormatDots(Right-Left));
        AddInfo('Paper Height', FormatDots(Bottom-Top));
      end;
      AddInfo('Printable Width',FormatDots(PageWidth));
      AddInfo('Printable Height',FormatDots(PageHeight));
      AddInfo('Copies',IntToStr(Copies));
      if CanRenderCopies then
        AddInfo('CanRenderCopies','true')
      else
        AddInfo('CanRenderCopies','false');
      AddInfo('Default Bin', DefaultBinName);
      i := SupportedBins.IndexOf(BinName);
      s := BinName; // <- workaround for ugly FPC 2.7.1 string encoding conversion
      s := BinName + format(' (%d of %d)',[i+1, SupportedBins.Count]); // ditto
      //AddInfo('Current Bin', BinName + ' ');
      AddInfo('Current Bin', s);

      if not CanPrint then
        Application.MessageBox('Selected printer cannot print currently!',
          'Warning',mb_iconexclamation);
    end;
  except on E:Exception do
    begin
      Application.MessageBox(PChar(e.message),'Error',mb_iconhand);
    end;
  end;
end;

procedure TForm1.OnPrintSetupDialogResult(sender: TObject; Success: boolean);
begin
  if Success then
    UpdatePrinterInfo;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  PSD.Title := txtPrinterSetupDlgTitle.Text;
  PSD.AttachTo := nil;
  PSD.OnDialogResult := @OnPrintSetupDialogResult;
  if chkAsSheet.Checked then
    PSD.AttachTo := Self;
  PSD.Execute;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Printer.PrinterIndex := -1;
  UpdatePrinterInfo;
end;

procedure TForm1.btnDirectPrintClick(Sender: TObject);
begin
  PrintTest;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  UpdatePrinterInfo;
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  {$IFDEF MSWindows}
  TWinPrinter(Printer).AdvancedProperties;
  {$ELSE}
  ShowMessage('Printer.AdvancedProperties is not yet implemented for this platform');
  {$ENDIF}
  UpdatePrinterInfo;
end;

procedure TForm1.Button7Click(Sender: TObject);
var
 s : String;
begin
  PageD.Title:= txtPageSetupDlgTitle.Text;
  if PAGED.Execute then
  begin
    UpdatePrinterInfo;
    with PAGED  do begin
      if PAGED.Units = pmMillimeters then
      begin
        s :=' milimeters';
        s := Format('[%d,%d,%d,%d] %s',[MarginTop div 100,
          MarginLeft div 100, MarginBottom div 100, MarginRight div 100,
          s]);
      end
      else
      begin
        s :=' inches';
        s := Format('[%d,%d,%d,%d] %s',[MarginTop div 1000,
          MarginLeft div 1000,MarginBottom div 1000,MarginRight div 1000,
          s]);
      end;
      AddInfo('Margins',s);
    end;
  end;
end;

procedure TForm1.btnRotateBinClick(Sender: TObject);
var
  i: Integer;
  cur: String;
  Lst: TStrings;
begin

  // get list of bins
  Lst := Printer.SupportedBins;
  cur := Printer.BinName;

  // get current bin index and find next bin in list
  if Lst.Count>0 then begin
    i := Lst.IndexOf(cur);
    inc(i);
    if i>Lst.Count-1 then
      i := 0;
    cur := Lst[i];
  end else
    cur := '';

  // select next bin
  Printer.BinName:=cur;
  UpdatePrinterInfo;
end;

procedure TForm1.btnRestoreDefaultBinClick(Sender: TObject);
begin
  Printer.RestoreDefaultBin;
  UpdatePrinterInfo;
end;

procedure TForm1.cbPapersSelect(Sender: TObject);
begin
  Printer.PaperSize.PaperName := cbPapers.Text;
  UpdatePrinterInfo;
end;

procedure TForm1.cbPrintersSelect(Sender: TObject);
begin
  Printer.PrinterIndex := cbPrinters.ItemIndex;
  UpdatePrinterInfo;
end;

procedure TForm1.comboTestsSelect(Sender: TObject);
var
  aMin, aMax: Integer;
begin
  aMin := 1;
  aMax := 1;
  case comboTests.ItemIndex of
    2: aMax := PAGE_COUNT;
    3: aMax := MULTIPAPER_COUNT;
  end;
  PD.MinPage := aMin;
  PD.MaxPage := aMax;
  PD.FromPage := aMin;
  PD.ToPage := aMax;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  {$ifdef LCLCocoa}
  chkAsSheet.enabled := true;
  chkNativeDlg.Enabled := true;
  {$endif}
  if SGrid.FixedRows=1 then
    SGrid.RowHeights[0] := btnTPrintDialog.Height;
  UpdatePrinterInfo;
end;

procedure TForm1.SGridSelectCell(Sender: TObject; aCol, aRow: Integer;
  var CanSelect: Boolean);
begin
  CanSelect := ACol>0;
end;

procedure TForm1.PrintTest;
begin
  case comboTests.ItemIndex of
    1:
      PrintSamplePage(true);
    2:
      PrintMultiPage;
    3:
      PrintMultiPageMultiPaper;
    4:
      PrintRulersPage;
    else
      PrintSamplePage(false);
  end;
end;

procedure TForm1.OnPrintDialogAsSetupResult(sender: TObject; Success: boolean);
var
  s,x: String;
begin
  if Success then
  begin
    x := '';
    UpdatePrinterInfo;
    if PD.Collate then AddInfo('Collate','true')
    else               AddInfo('Collate','false');
    if PD.PrintRange=prPageNums then x :='Pages range,';
    if PD.PrintRange=prSelection then x :='Selection,';
    if PD.PrintToFile then x := x + ' ,PrintToFile,';

    s := Format(x + ' From : %d to %d,Copies:%d',[PD.FromPage,PD.ToPage,PD.Copies]);
    Application.MessageBox(pChar(s),'Info',mb_iconinformation);
  end;
end;

procedure TForm1.btnTPrintDialogClick(Sender: TObject);
var
 before: boolean;
begin
  {$ifdef LCLCOCOA}
  //PD.Options := PD.Options + [poBeforeBeginDoc];
  before := poBeforeBeginDoc in PD.Options;
  {$else}
  before := true;
  {$endif}
  if before then
  begin
    PD.Title := txtPrintDialogTitle.Text;
    PD.PrintToFile := false;
    PD.AttachTo := nil;
    if chkAsSheet.Checked then
      PD.AttachTo := Self;
    PD.OnDialogResult := @OnPrintDialogAsSetupResult;
    PD.Execute;
  end else
  begin
    ShowMessage(
      'Using the print dialog as a printer setup dialog'^M+
      'is disabled by default in the LCL Cocoa widgetset.'^M^M+
      'If you want to enable it, turn on the print dialog'^M+
      'option poBeforeBeginDoc'
      );
  end;
end;

procedure TForm1.btnPrintWithDlgClick(Sender: TObject);
begin
  PD.Title := txtPrintDialogTitle.Text;
  PD.PrintToFile := false;
  PD.AttachTo := nil;
  if chkNativeDlg.Checked then begin
    PD.OnDialogResult := nil;  // dialog result is uninteresting in this case
    PD.Options := PD.Options - [poBeforeBeginDoc];
  end
  else
  begin
    PD.OnDialogResult := @OnPrintDialogAsSetupResult;
    PD.Options := PD.Options + [poBeforeBeginDoc];
  end;
  if chkAsSheet.Checked then
    PD.AttachTo := Self;
  if PD.Execute then
    PrintTest
end;

end.
