|
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;
|