Respecting user printer selections before printing a preview.



Sample code -
Printing from the preview or after a 'Prepare'
==============================================

These changes force the saved metafile to be printed by the current printer object,
which is selected and setup by a standard print dialog. All the users settings are 
respected by the printer, including the paper dimensions, 2 per page, paper source,
resolution, collation, copies and orientation.

The new method PrintMetafileDirect may be called after a prepare like this -

quickrep1.prepare;
// you can call a printer dialog here ...
quickrep1.qrprinter.PrintMetafileDirect( 1, 6 ); // for instance.

After pasting in these changes, rebuild the libraries as described here
www.quickreport.co.uk/building.html


Changes in QRPrntr.pas
----------------------

First, move the property 'aPrinterSettings' of TQRPrinter
to the Public properties ( file qrprntr.pas).

1. Add this new public method.

Declare it here in the TQRPrinter class definition

..
..
  public
    // standard printer
{$ifdef VER36PRO}
    constructor Create( ParentRep : TObject );
{$else}
    constructor Create;
{$endif}
    destructor Destroy; override;
    // **** new method
    procedure PrintMetafileDirect( frompage, topage : integer);
    function GetPage(Value : integer) : TMetafile;



Add code body anywhere after implementation

// Called from the preview, prints the saved metafile direct to 'printer'
procedure TQRPrinter.PrintMetafileDirect( frompage, topage : integer);
var
     pagefile : TMetafile;
     i : integer;
     qrpr : TQRPrinter;
     pwidth, pheight, Lxfactor, Lyfactor : extended;
begin
      if status <> mpFinished then exit;
      printer.begindoc;
      LXFactor := GetDeviceCaps(Printer.Handle, LogPixelsX) / 254;
      LYFactor := GetDeviceCaps(Printer.Handle, LogPixelsY) / 254;
      if self.PaperSize = Custom then
      begin
        pwidth := self.PaperWidth*LXFactor; // width in pix
        pheight := self.PaperLength*LYFactor; // height in pix
      end
      else
      begin
        pheight := printer.PageHeight;
        pwidth := printer.PageWidth;
      end;
      qrpr := self;
      for i := frompage to topage do
      begin
          pagefile := qrpr.pagelist.GetPage(i);
          printer.Canvas.StretchDraw( rect( 0, 0, round(pwidth), round(pheight)), pagefile );
          if i <> topage then printer.NewPage;
      end;
      printer.enddoc;
end;



Changes in QRPrev.pas
---------------------

0. put a print dialog control called printdialog1 on the form.

1. new module vars
..
implementation

uses QuickRpt;
var
    gfrompage, gtopage : integer;// 2 module vars
{$R *.DFM}
..
..

2. Replace this method

procedure TQRStandardPreview.PrintClick(Sender: TObject);
begin
    qrprinter.PrintMetafileDirect( gfrompage, gtopage);
end;


3. Add this method

NOTE : put 'printers, winspool' in the USES clause and
add SetPrinterOptionsToReport to class declaration of TQRStandardPreview.

// transfer quickreport settings to current printer
procedure TQRStandardPreview.SetPrinterOptionsToReport;
var
    hDevMode,hNewDevMode,hPrinter: THandle;
    Device,Driver,Port: array[0..79] of Char;
    rc,iSize : integer; 
    DevMode,NewDevMode: PDevMode;
begin
 rc := IDCANCEL;
 Printer.GetPrinter (Device,Driver,Port,hDevMode);
 if hDevMode <> 0 then
  begin
    iSize := GlobalSize (hDevMode);
    hNewDevMode := GlobalAlloc (GHND,iSize);
    iCop := 0;
    iCol := 0;
    if hNewDevMode <> 0 then
      try
        DevMode := GlobalLock (hDevMode);
        NewDevMode := GlobalLock (hNewDevMode);
        if (DevMode <> nil) and (NewDevMode <> nil) then
        begin
            Move (DevMode^,NewDevMode^,iSize);
            OpenPrinter (Device, hPrinter, nil);
            rc := DocumentProperties ( Handle, hPrinter, Device, NewDevMode^, NewDevMode^,
                                       DM_OUT_BUFFER or DM_IN_BUFFER);
            // Duplex
            if qrprinter.aPrinterSettings.ExtendedDuplex <> 0 then
               NewDevMode^.dmDuplex := qrprinter.aPrinterSettings.ExtendedDuplex
            else
            begin
               if qrprinter.aPrinterSettings.Duplex then
                  NewDevMode^.dmDuplex := dmdup_horizontal
               else
                  NewDevMode^.dmDuplex := dmdup_simplex;
            end;
            // Orientation
            if qrprinter.aPrinterSettings.Orientation=poPortrait then
               NewDevMode^.dmOrientation := dmorient_portrait
            else
               NewDevMode^.dmOrientation := dmorient_landscape;
            // bin code
            if  qrprinter.aPrinterSettings.UseCustomBinCode then
                     NewDevMode^.dmDefaultSource := qrprinter.aPrinterSettings.CustomBinCode
            else
                     NewDevMode^.dmDefaultSource := cQRBinTranslate[qrprinter.aPrinterSettings.OutputBin];
            // paper size
            if not qrprinter.aPrinterSettings.UseCustomPaperCode then
                    NewDevMode^.dmPaperSize := cQRPaperTranslate[qrprinter.aPrinterSettings.PaperSize]
            else
                    NewDevMode^.dmPaperSize := qrprinter.aPrinterSettings.CustomPaperCode;
        end;

      finally
        GlobalUnlock (hDevMode);
        GlobalUnlock (hNewDevMode);
        ClosePrinter (hPrinter);
      end;
    if rc = IDOK then
      begin
        Printer.SetPrinter (Device,Driver,Port,hNewDevMode);
        GlobalFree (hDevMode);
      end
    else if hNewDevMode <> 0 then
          GlobalFree (hNewDevMode);
  end;
end;

3.1 Replace this method

procedure TQRStandardPreview.PrintSetupClick(Sender: TObject);
begin
  // sets the printer options so the dialog will show them
  SetPrinterOptionsToReport;
  PrintDialog1.Options := [poPageNums, poSelection];
  PrintDialog1.FromPage := 1;
  PrintDialog1.MinPage := 1;
  PrintDialog1.ToPage := qrprinter.PageCount;
  PrintDialog1.MaxPage := qrprinter.PageCount;
  if PrintDialog1.execute then
  begin
       gfrompage := PrintDialog1.FromPage;
       gtopage := PrintDialog1.ToPage;
  end;
  // safety first
  if gfrompage = 0 then gfrompage := 1;
  if gtopage = 0 then gtopage := qrprinter.pagecount;
end;


4. Replace this method -

procedure TQRStandardPreview.QRPreviewPageAvailable(Sender: TObject;
  PageNum: Integer);
begin
  UpdateInfo;
  // set the default print page range
  gtopage := qrprinter.PageCount;
  gfrompage := 1;
  if qrprinter.status = mpFinished then
  begin
    PrintSetup.Enabled := true;
    Print.Enabled := true;
  end;
end;