diff --git a/components/printers/printer4lazarus.lpk b/components/printers/printer4lazarus.lpk index a64edc3931..28be104d27 100644 --- a/components/printers/printer4lazarus.lpk +++ b/components/printers/printer4lazarus.lpk @@ -26,7 +26,7 @@ - + @@ -128,6 +128,14 @@ + + + + + + + + diff --git a/components/printers/readme.txt b/components/printers/readme.txt index a15c1d33f4..b194c69266 100644 --- a/components/printers/readme.txt +++ b/components/printers/readme.txt @@ -4,9 +4,19 @@ Printer4Lazarus package This package add some components. TPrinterSetupDialog : for update properties of selected printer TPrintDialog : for select and/or update an printer before printing + TPageSetupDialog : to select margins (currently only under Windows) Win32 : Native implementation +Notes: + 1. TPrinter.CanRenderCopies return information if printer driver is able to print more then one copy at once. + Not all printers drivers support that feature (n that case programmer should print document requested times) + + 2.TPrintDialog.Options indicate which controls should be visible in dialog. + TPrintDialog.PrintToFile indicate that output will be redirected to file. + + 3.Some (mostly advanced) settings of printer driver are not preserved between two calls to TPrintDialog.Execute function. + Linux : Yous must install CUPS and libcups v1.1.19 or more. @@ -14,3 +24,4 @@ Linux : FAQ : Q:If I use Printers unit, the call of printer object générate an exception "Access Violation" R:Add in uses clause of your project, osPrinters + diff --git a/components/printers/sample/frmselprinter.lfm b/components/printers/sample/frmselprinter.lfm index a346a41198..936ad82689 100644 --- a/components/printers/sample/frmselprinter.lfm +++ b/components/printers/sample/frmselprinter.lfm @@ -4,22 +4,22 @@ object Form1: TForm1 ClientHeight = 487 ClientWidth = 339 OnCreate = FormCreate - PixelsPerInch = 75 + PixelsPerInch = 96 Position = poDesktopCenter HorzScrollBar.Page = 338 VertScrollBar.Page = 486 - Left = 212 + Left = 230 Height = 487 - Top = 47 + Top = 36 Width = 339 object Label1: TLabel Caption = 'This sample show how to use the printer dialogs' Color = clNone ParentColor = False Left = 16 - Height = 13 + Height = 14 Top = 8 - Width = 269 + Width = 226 end object Button2: TButton BorderSpacing.InnerBorder = 2 @@ -51,17 +51,17 @@ object Form1: TForm1 MaxSize = 350 ReadOnly = True Title.Caption = 'Information' - Width = 250 + Width = 230 end> - DefaultColWidth = 70 + DefaultColWidth = 90 FixedColor = clBtnFace Flat = True GridLineWidth = 0 Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goSmoothScroll] - RowCount = 12 + RowCount = 15 ScrollBars = ssAutoBoth VisibleColCount = 1 - VisibleRowCount = 11 + VisibleRowCount = 14 Left = 8 Height = 288 Top = 192 @@ -118,10 +118,20 @@ object Form1: TForm1 Width = 320 end object PSD: TPrinterSetupDialog + Title = 'Testing dialog title' left = 176 top = 240 end object PD: TPrintDialog + Collate = True + Copies = 1 + FromPage = 2 + MinPage = 2 + MaxPage = 5 + Options = [poPrintToFile, poPageNums, poSelection, poWarning, poHelp] + PrintToFile = True + ToPage = 3 + Title = 'Testing title' left = 176 top = 272 end diff --git a/components/printers/sample/frmselprinter.lrs b/components/printers/sample/frmselprinter.lrs index e82db23da6..230bd587ee 100644 --- a/components/printers/sample/frmselprinter.lrs +++ b/components/printers/sample/frmselprinter.lrs @@ -1,26 +1,26 @@ -{ This is an automatically generated lazarus resource file } +{ To jest automatycznie wygenerowany plik zasobów lazarusa } LazarusResources.Add('TForm1','FORMDATA',[ 'TPF0'#6'TForm1'#5'Form1'#13'ActiveControl'#7#7'Button2'#7'Caption'#6#5'Form1' +#12'ClientHeight'#3#231#1#11'ClientWidth'#3'S'#1#8'OnCreate'#7#10'FormCreate' - +#13'PixelsPerInch'#2'K'#8'Position'#7#15'poDesktopCenter'#18'HorzScrollBar.P' - +'age'#3'R'#1#18'VertScrollBar.Page'#3#230#1#4'Left'#3#212#0#6'Height'#3#231#1 - +#3'Top'#2'/'#5'Width'#3'S'#1#0#6'TLabel'#6'Label1'#7'Caption'#6'/This sample' + +#13'PixelsPerInch'#2'`'#8'Position'#7#15'poDesktopCenter'#18'HorzScrollBar.P' + +'age'#3'R'#1#18'VertScrollBar.Page'#3#230#1#4'Left'#3#230#0#6'Height'#3#231#1 + +#3'Top'#2'$'#5'Width'#3'S'#1#0#6'TLabel'#6'Label1'#7'Caption'#6'/This sample' +' show how to use the printer dialogs'#5'Color'#7#6'clNone'#11'ParentColor'#8 - +#4'Left'#2#16#6'Height'#2#13#3'Top'#2#8#5'Width'#3#13#1#0#0#7'TButton'#7'But' - +'ton2'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#27'Execute TPrinterSet' - +'upDialog'#7'OnClick'#7#12'Button2Click'#8'TabOrder'#2#0#4'Left'#2#8#6'Heigh' - +'t'#2#27#3'Top'#2'3'#5'Width'#3'@'#1#0#0#7'TButton'#7'Button1'#25'BorderSpac' - +'ing.InnerBorder'#2#2#7'Caption'#6#20'Execute TPrintDialog'#7'OnClick'#7#12 + +#4'Left'#2#16#6'Height'#2#14#3'Top'#2#8#5'Width'#3#226#0#0#0#7'TButton'#7'Bu' + +'tton2'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#27'Execute TPrinterSe' + +'tupDialog'#7'OnClick'#7#12'Button2Click'#8'TabOrder'#2#0#4'Left'#2#8#6'Heig' + +'ht'#2#27#3'Top'#2'3'#5'Width'#3'@'#1#0#0#7'TButton'#7'Button1'#25'BorderSpa' + +'cing.InnerBorder'#2#2#7'Caption'#6#20'Execute TPrintDialog'#7'OnClick'#7#12 +'Button1Click'#8'TabOrder'#2#1#4'Left'#2#8#6'Height'#2#27#3'Top'#2'N'#5'Widt' +'h'#3'@'#1#0#0#11'TStringGrid'#5'SGrid'#15'AutoFillColumns'#9#11'BorderStyle' +#7#6'bsNone'#8'ColCount'#2#2#7'Columns'#14#1#7'MinSize'#2'<'#7'MaxSize'#3'^' - +#1#8'ReadOnly'#9#13'Title.Caption'#6#11'Information'#5'Width'#3#250#0#0#0#15 - +'DefaultColWidth'#2'F'#10'FixedColor'#7#9'clBtnFace'#4'Flat'#9#13'GridLineWi' + +#1#8'ReadOnly'#9#13'Title.Caption'#6#11'Information'#5'Width'#3#230#0#0#0#15 + +'DefaultColWidth'#2'Z'#10'FixedColor'#7#9'clBtnFace'#4'Flat'#9#13'GridLineWi' +'dth'#2#0#7'Options'#11#15'goFixedVertLine'#15'goFixedHorzLine'#10'goVertLin' - +'e'#10'goHorzLine'#13'goRangeSelect'#14'goSmoothScroll'#0#8'RowCount'#2#12#10 + +'e'#10'goHorzLine'#13'goRangeSelect'#14'goSmoothScroll'#0#8'RowCount'#2#15#10 +'ScrollBars'#7#10'ssAutoBoth'#15'VisibleColCount'#2#1#15'VisibleRowCount'#2 - +#11#4'Left'#2#8#6'Height'#3' '#1#3'Top'#3#192#0#5'Width'#3'@'#1#0#0#7'TButto' + +#14#4'Left'#2#8#6'Height'#3' '#1#3'Top'#3#192#0#5'Width'#3'@'#1#0#0#7'TButto' +'n'#7'Button3'#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#24'Get default' +' printer info'#7'OnClick'#7#12'Button3Click'#8'TabOrder'#2#2#4'Left'#2#8#6 +'Height'#2#27#3'Top'#2'i'#5'Width'#3'@'#1#0#0#7'TButton'#7'Button4'#25'Borde' @@ -34,9 +34,12 @@ LazarusResources.Add('TForm1','FORMDATA',[ +'Height'#2#25#3'Top'#3#157#0#5'Width'#3#224#0#0#0#7'TButton'#7'Button7'#25'B' +'orderSpacing.InnerBorder'#2#2#7'Caption'#6#24'Execute TPageSetupDialog'#7'O' +'nClick'#7#12'Button7Click'#8'TabOrder'#2#6#4'Left'#2#8#6'Height'#2#27#3'Top' - +#2#24#5'Width'#3'@'#1#0#0#19'TPrinterSetupDialog'#3'PSD'#4'left'#3#176#0#3't' - +'op'#3#240#0#0#0#12'TPrintDialog'#2'PD'#4'left'#3#176#0#3'top'#3#16#1#0#0#10 - +'TPopupMenu'#10'PopupMenu1'#4'left'#3#216#0#3'top'#3#240#0#0#0#16'TPageSetup' - +'Dialog'#5'PAGED'#5'Title'#6#25'Ustawienie strony raportu'#4'left'#3#176#0#3 - +'top'#3'0'#1#0#0#0 + +#2#24#5'Width'#3'@'#1#0#0#19'TPrinterSetupDialog'#3'PSD'#5'Title'#6#20'Testi' + +'ng dialog title'#4'left'#3#176#0#3'top'#3#240#0#0#0#12'TPrintDialog'#2'PD'#7 + +'Collate'#9#6'Copies'#2#1#8'FromPage'#2#2#7'MinPage'#2#2#7'MaxPage'#2#5#7'Op' + +'tions'#11#13'poPrintToFile'#10'poPageNums'#11'poSelection'#9'poWarning'#6'p' + +'oHelp'#0#11'PrintToFile'#9#6'ToPage'#2#3#5'Title'#6#13'Testing title'#4'lef' + +'t'#3#176#0#3'top'#3#16#1#0#0#10'TPopupMenu'#10'PopupMenu1'#4'left'#3#216#0#3 + +'top'#3#240#0#0#0#16'TPageSetupDialog'#5'PAGED'#5'Title'#6#25'Ustawienie str' + +'ony raportu'#4'left'#3#176#0#3'top'#3'0'#1#0#0#0 ]); diff --git a/components/printers/sample/frmselprinter.pas b/components/printers/sample/frmselprinter.pas index eac3e60d95..af99bccb66 100644 --- a/components/printers/sample/frmselprinter.pas +++ b/components/printers/sample/frmselprinter.pas @@ -54,8 +54,11 @@ type procedure Button7Click(Sender: TObject); procedure FormCreate(Sender: TObject); private + ck : Integer; procedure UpdatePrinterInfo; + procedure AddInfo(const Desc : String; Const Info : String); public + { public declarations } end; @@ -68,18 +71,14 @@ uses { 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.UpdatePrinterInfo; -var - ck : Integer; - s : String; - -procedure AddInfo(const Desc : String; Const Info : String); - begin - SGrid.Cells[0,ck] := Desc; - SGrid.Cells[1,ck] := Info; - Inc(ck); - end; begin try ck := 1; @@ -109,23 +108,10 @@ begin psStopped:AddInfo('PrinterState','Stopped'); end; AddInfo('PaperSize',PaperSize.PaperName); - with PAGED do begin - if PAGED.Units = unMM then - begin - s :=' milimeters'; - s := Format('[%d,%d,%d,%d] %s',[Margins.Top div 100, - Margins.Left div 100, Margins.Bottom div 100, Margins.Right div 100, - s]); - end - else - begin - s :=' inches'; - s := Format('[%d,%d,%d,%d] %s',[Margins.Top div 1000, - Margins.Left div 1000,Margins.Bottom div 1000,Margins.Right div 1000, - s]); - end; - AddInfo('Margins',s); - end; + if CanRenderCopies then AddInfo('CanRenderCopies','true') + else + AddInfo('CanRenderCopies','false'); + if not CanPrint then Application.MessageBox('Selected printer cannot print currently!', 'Warning',mb_iconexclamation); @@ -135,7 +121,6 @@ begin end; end; - procedure TForm1.Button2Click(Sender: TObject); begin if PSD.Execute then @@ -157,15 +142,15 @@ begin Printer.Canvas.Font.Size := 12; Printer.Canvas.TextOut(0,0,'This is test for lazarus printer4lazarus package'); Printer.EndDoc; - except on E:Exception do - begin - Printer.Abort; - Application.MessageBox(pChar(e.message),'Error',mb_iconhand); + except + on E:Exception do + begin + Printer.Abort; + Application.MessageBox(pChar(e.message),'Error',mb_iconhand); + end; end; end; -end; - procedure TForm1.Button5Click(Sender: TObject); begin UpdatePrinterInfo; @@ -174,15 +159,37 @@ end; procedure TForm1.Button6Click(Sender: TObject); begin {$IFDEF WIN32} - TWinPrinter(Printer).Properties; + TWinPrinter(Printer).AdvancedProperties; {$ELSE} - ShowMessage('Printer.Properties is not implemented for this platform'); + ShowMessage('Printer.AdvancedProperties is not yet implemented for this platform'); {$ENDIF} end; procedure TForm1.Button7Click(Sender: TObject); +var + s : String; begin - if PAGED.Execute then UpdatePrinterInfo; + if PAGED.Execute then + begin + UpdatePrinterInfo; + with PAGED do begin + if PAGED.Units = unMM then + begin + s :=' milimeters'; + s := Format('[%d,%d,%d,%d] %s',[Margins.Top div 100, + Margins.Left div 100, Margins.Bottom div 100, Margins.Right div 100, + s]); + end + else + begin + s :=' inches'; + s := Format('[%d,%d,%d,%d] %s',[Margins.Top div 1000, + Margins.Left div 1000,Margins.Bottom div 1000,Margins.Right div 1000, + s]); + end; + AddInfo('Margins',s); + end; + end; end; procedure TForm1.FormCreate(Sender: TObject); @@ -194,16 +201,12 @@ procedure TForm1.Button1Click(Sender: TObject); var s,x : String; begin - PD.Copies := 4; - PD.FromPage := 1; - PD.ToPage := 5; - PD.MinPage := 1; - PD.MaxPage := 5; - PD.PrintRange := prAllPages; - //PD.Options := [poPageNums,poSelection,poPrintToFile]; if PD.Execute then begin 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,'; diff --git a/components/printers/sample/selectprinter.lpi b/components/printers/sample/selectprinter.lpi index 61fca8c76f..54a84071d5 100644 --- a/components/printers/sample/selectprinter.lpi +++ b/components/printers/sample/selectprinter.lpi @@ -1,7 +1,7 @@ - + @@ -16,44 +16,45 @@ - + - + - + - + - + - - - - - - - - - - + + - + + + + + + + + + + @@ -61,7 +62,7 @@ - + @@ -77,19 +78,30 @@ + - + + + + + + + + + + + @@ -102,19 +114,25 @@ - - - - - - - + + + + + + + + + + + + + diff --git a/components/printers/win32/winprinters.inc b/components/printers/win32/winprinters.inc index 2f95faf2a6..22de0e5cfc 100644 --- a/components/printers/win32/winprinters.inc +++ b/components/printers/win32/winprinters.inc @@ -127,9 +127,6 @@ begin fLastHandleType:=0; end; - - - procedure TWinPrinter.DoBeginDoc; var Inf: TDocInfo; begin @@ -138,7 +135,6 @@ begin if fPrinterHandle=0 then raise EPrinter.Create('Printer handle not defined'); - SetDC; Canvas.Handle:=fDC; Canvas.Refresh; @@ -175,36 +171,6 @@ begin AbortDoc(fDC); end; -(* -function TWinPrinter.GetDefaultPrinter : String; -var - PrtCount : DWORD; - Needed : DWORD; - Buffer : PChar; - DefaultPrinter : array[0..79] of Char; -begin - Result:=''; - Needed:=0; - EnumPrinters(PRINTER_ENUM_DEFAULT,nil,5,nil,0,Needed,PrtCount); - if Needed>0 then - begin - GetMem(Buffer,Needed); - try - if EnumPrinters(PRINTER_ENUM_DEFAULT,nil,5,Buffer,Needed,Needed,PrtCount) then - Result := String(PPRINTER_INFO_5(Buffer)^.pPrinterName); - finally - FreeMem(Buffer); - end; - end - else - begin - GetProfileString(PChar('windows'),PChar('device'),PChar(''),DefaultPrinter,SizeOf(DefaultPrinter)); - if pos(',',DefaultPrinter)<>0 then - Result:=Copy(DefaultPrinter,1,Pos(',',DefaultPrinter)-1); - end; -end; -*) - //Enum all defined printers. First printer it's default procedure TWinPrinter.DoEnumPrinters(Lst: TStrings); Var Flags : DWORD; @@ -348,18 +314,14 @@ begin FreeMem(Buffer); end; - //Retreive the code of papers - - FillChar(ArPapers,SizeOf(ArPapers),0); PaperC:=DeviceCapabilities(PChar(Pdev.Name),PCHar(PDev.Port), DC_PAPERS,@ArPapers,nil); if PaperC<=0 then raise EPrinter.CreateFmt('DoEnumPapers error : %d, (%s)',[GetLastError,SysErrorMessage(GetLastError)]); for i:=0 to PaperC-1 do - Lst.Objects[i]:=TObject(Pointer(Integer(ArPapers[i]))); + Lst.Objects[i]:=TObject(ptrint(ArPapers[i])); end; - end; function TWinPrinter.DoGetDefaultPaperName: string; @@ -372,7 +334,7 @@ begin begin PDev:=TPrinterDevice(Printers.Objects[PrinterIndex]); - i:=PaperSize.SupportedPapers.IndexOfObject(TObject(Pointer(Integer(PDev.DefaultPaper)))); + i:=PaperSize.SupportedPapers.IndexOfObject(TObject(ptrint(PDev.DefaultPaper))); if i<>-1 then Result:=PaperSize.SupportedPapers.Strings[i]; end; @@ -394,7 +356,7 @@ begin if i<>-1 then begin ClearDC; - j:=SHORT(Pointer(PaperSize.SupportedPapers.Objects[i])); + j:=SHORT(ptrint(PaperSize.SupportedPapers.Objects[i])); PDev.DevMode.dmPaperSize:=j; end; end; @@ -470,7 +432,7 @@ begin PDev:=TPrinterDevice(Printers.Objects[PrinterIndex]); ClearDC; - PDev.DevMode.dmCopies:=aValue; + PDev.DevMode.dmCopies:=SHORT(aValue); end; end; @@ -570,7 +532,6 @@ begin finally FreeMem(InfoPrt); end; - end; function TWinPrinter.GetCanPrint: Boolean; @@ -579,12 +540,26 @@ begin Result := (DoGetPrinterState <> psStopped); end; -procedure TWinPrinter.Properties; +function TWinPrinter.GetCanRenderCopies: Boolean; +var + pDev : TPrinterDevice; + Count : Integer; +begin + Result := inherited GetCanRenderCopies; + if (Printers.Count>0) then + begin + PDev:=TPrinterDevice(Printers.Objects[PrinterIndex]); + Count := DeviceCapabilities(PChar(Pdev.Name),PCHar(PDev.Port),DC_COPIES,nil,@PDev.DevMode); + Result := (Count > 1); + end; +end; + +procedure TWinPrinter.AdvancedProperties; begin PrinterProperties(TWin32WidgetSet(WidgetSet).AppHandle,fPrinterHandle); end; -INITIALIZATION +initialization Printer:=TWinPrinter.Create; {end.} diff --git a/components/printers/win32/winprinters_h.inc b/components/printers/win32/winprinters_h.inc index 8e84041643..51edb9626e 100644 --- a/components/printers/win32/winprinters_h.inc +++ b/components/printers/win32/winprinters_h.inc @@ -30,7 +30,7 @@ uses Type TWinPrinter = class(TPrinter) private - fDefaultPrinter : String; + //fDefaultPrinter : String; fLastHandleType : Byte; //0=None 1=IC 2=DC fDC : HDC; fPrinterHandle : THandle; @@ -67,6 +67,7 @@ Type function GetPrinterType: TPrinterType;override; function DoGetPrinterState: TPrinterState;override; function GetCanPrint: Boolean;override; + function GetCanRenderCopies : Boolean;override; function GetHandlePrinter : HDC; procedure SetHandlePrinter(aValue : HDC); public @@ -75,7 +76,7 @@ Type //Warning not portable functions here - procedure Properties; + procedure AdvancedProperties; //Warning it is a not potable property property Handle : HDC read GetHandlePrinter write SetHandlePrinter; diff --git a/components/printers/win32/winprndialogs.inc b/components/printers/win32/winprndialogs.inc index 95c3ff99eb..c01caf8d65 100644 --- a/components/printers/win32/winprndialogs.inc +++ b/components/printers/win32/winprndialogs.inc @@ -12,6 +12,8 @@ var DeviceMode : THandle; DevNames : PDevNames; St : PChar; + Extra,Size : Integer; + Fields : Dword; begin Result:=False; if not Assigned(Printer) then Exit; @@ -26,19 +28,17 @@ begin hWndOwner:=TWin32WidgetSet(WidgetSet).AppHandle; rtMargin := fMargins; PDev:=TPrinterDevice(Printer.Printers.Objects[Printer.PrinterIndex]); - - DeviceMode:=GlobalAlloc(GHND,SizeOf(PDev.DevMode)); + Size := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_SIZE,nil,nil); + Extra := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_EXTRA,nil,nil); + Fields := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_FIELDS,nil,nil); + DeviceMode:=GlobalAlloc(GHND,Size + Extra); try DevMode:=PDeviceMode(GlobalLock(DeviceMode)); try - //some plotters crash when DEVMODE contains other options set - //so only minimal options passed to print dialog - StrCopy(DevMode^.dmDeviceName,Pdev.DevMode.dmDeviceName); - DevMode^.dmSize := Word(SizeOf(PDev.DevMode)); - DevMode^.dmOrientation := Pdev.DevMode.dmOrientation; - DevMode^.dmFields := DM_ORIENTATION or DM_PAPERSIZE or DM_COPIES; - DevMode^.dmPaperSize := Pdev.DevMode.dmPaperSize; - DevMode^.dmCopies := Pdev.DevMode.dmCopies; + CopyMemory(DevMode,@PDev.DevMode,SizeOf(PDev.DevMode)); + DevMode^.dmSize := Word(Size); + DevMode^.dmDriverExtra := Word(Extra); + DevMode^.dmFields := Fields; finally GlobalUnLock(DeviceMode); end; @@ -72,20 +72,9 @@ begin try //Set the properties for the selected printer PDev:=TPrinterDevice(Printer.Printers.Objects[Printer.PrinterIndex]); + CopyMemory(@PDev.DevMode,DevMode,sizeof(Pdev.DevMode)); PDev.DevMode.dmSize := SizeOf(PDev.DevMode); - StrCopy(@PDev.DevMode.dmDeviceName,DevMode^.dmDeviceName); - PDev.DevMode.dmOrientation := DevMode^.dmOrientation; - PDev.DevMode.dmFields := DevMode^.dmFields; - PDev.DevMode.dmPaperSize := DevMode^.dmPaperSize; - PDev.DevMode.dmPaperLength := DevMode^.dmPaperLength; - PDev.DevMode.dmPaperWidth := DevMode^.dmPaperWidth; - PDev.DevMode.dmScale := DevMode^.dmScale; - PDev.DevMode.dmCopies := DevMode^.dmCopies; - PDev.DevMode.dmPrintQuality := DevMode^.dmPrintQuality; - PDev.DevMode.dmColor := DevMode^.dmColor; - PDev.DevMode.dmDuplex := DevMode^.dmDuplex; - PDev.DevMode.dmYResolution := DevMode^.dmYResolution; - PDev.DevMode.dmTTOption := DevMode^.dmTTOption; + PDev.DevMode.dmDriverExtra := 0; PDev.DefaultPaper := DevMode^.dmPaperSize; finally GlobalUnlock(lpp.hDevMode); @@ -110,6 +99,8 @@ var DeviceMode : THandle; DevNames : PDevNames; St : PChar; + Extra,Size : Integer; + Fields : Dword; begin Result:=False; if not Assigned(Printer) then Exit; @@ -124,19 +115,17 @@ begin hWndOwner:=TWin32WidgetSet(WidgetSet).AppHandle; PDev:=TPrinterDevice(Printer.Printers.Objects[Printer.PrinterIndex]); - - DeviceMode:=GlobalAlloc(GHND,SizeOf(PDev.DevMode)); + Size := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_SIZE,nil,nil); + Extra := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_EXTRA,nil,nil); + Fields := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_FIELDS,nil,nil); + DeviceMode:=GlobalAlloc(GHND,Size + Extra); try DevMode:=PDeviceMode(GlobalLock(DeviceMode)); try - //some plotters crash when DEVMODE contains other options set - //so only minimal options passed to print dialog - StrCopy(DevMode^.dmDeviceName,Pdev.DevMode.dmDeviceName); - DevMode^.dmSize := Word(SizeOf(PDev.DevMode)); - DevMode^.dmOrientation := Pdev.DevMode.dmOrientation; - DevMode^.dmFields := DM_ORIENTATION or DM_PAPERSIZE or DM_COPIES; - DevMode^.dmPaperSize := Pdev.DevMode.dmPaperSize; - DevMode^.dmCopies := Pdev.DevMode.dmCopies; + CopyMemory(DevMode,@PDev.DevMode,SizeOf(PDev.DevMode)); + DevMode^.dmSize := Word(Size); + DevMode^.dmDriverExtra := Word(Extra); + DevMode^.dmFields := Fields; finally GlobalUnLock(DeviceMode); end; @@ -166,20 +155,9 @@ begin try //Set the properties for the selected printer PDev:=TPrinterDevice(Printer.Printers.Objects[Printer.PrinterIndex]); + CopyMemory(@PDev.DevMode,DevMode,sizeof(Pdev.DevMode)); PDev.DevMode.dmSize := SizeOf(PDev.DevMode); - StrCopy(@PDev.DevMode.dmDeviceName,DevMode^.dmDeviceName); - PDev.DevMode.dmOrientation := DevMode^.dmOrientation; - PDev.DevMode.dmFields := DevMode^.dmFields; - PDev.DevMode.dmPaperSize := DevMode^.dmPaperSize; - PDev.DevMode.dmPaperLength := DevMode^.dmPaperLength; - PDev.DevMode.dmPaperWidth := DevMode^.dmPaperWidth; - PDev.DevMode.dmScale := DevMode^.dmScale; - PDev.DevMode.dmCopies := DevMode^.dmCopies; - PDev.DevMode.dmPrintQuality := DevMode^.dmPrintQuality; - PDev.DevMode.dmColor := DevMode^.dmColor; - PDev.DevMode.dmDuplex := DevMode^.dmDuplex; - PDev.DevMode.dmYResolution := DevMode^.dmYResolution; - PDev.DevMode.dmTTOption := DevMode^.dmTTOption; + PDev.DevMode.dmDriverExtra := 0; PDev.DefaultPaper := DevMode^.dmPaperSize; TWinPrinter(Printer).Handle := hDC; finally @@ -204,11 +182,11 @@ var lpp : tagPD; DeviceMode : THandle; DevNames : PDevNames; St : PChar; - Old : Integer; + Extra,Size : Integer; + Fields : Dword; begin Result:=False; if not Assigned(Printer) then Exit; - Old := Copies; if Printer.Printers.Count>0 then begin FillChar(lpp,SizeOf(lpp),0); @@ -216,7 +194,8 @@ begin begin lStructSize:=SizeOf(lpp); hInstance:=LCLType.HInstance; - Flags := PD_COLLATE or PD_USEDEVMODECOPIES or PD_RETURNDC; + Flags := PD_RETURNDC; + if Collate then Flags := Flags or PD_COLLATE; case PrintRange of prPageNums : Flags := Flags or PD_PAGENUMS; prSelection : Flags := Flags or PD_SELECTION; @@ -227,23 +206,23 @@ begin if not (poPageNums in Options) then Flags := Flags or PD_NOPAGENUMS; if not (poSelection in Options) then Flags := Flags or PD_NOSELECTION; if (poPrintToFile in Options ) and (poDisablePrintToFile in Options) then Flags := Flags or PD_DISABLEPRINTTOFILE; - + if (poHelp in Options) then Flags := Flags or PD_SHOWHELP; + if not (poWarning in Options) then Flags := Flags or PD_NOWARNING; + hWndOwner:=TWin32WidgetSet(WidgetSet).AppHandle; PDev:=TPrinterDevice(Printer.Printers.Objects[Printer.PrinterIndex]); - - DeviceMode:=GlobalAlloc(GHND,SizeOf(PDev.DevMode)); + Size := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_SIZE,nil,nil); + Extra := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_EXTRA,nil,nil); + Fields := DeviceCapabilities(PChar(PDev.Name),PChar(PDev.Port),DC_FIELDS,nil,nil); + DeviceMode:=GlobalAlloc(GHND,Size + Extra); try DevMode:=PDeviceMode(GlobalLock(DeviceMode)); try - //some plotters crash when DEVMODE contains other options set - //so only minimal options passed to print dialog - DevMode^.dmSize := Word(SizeOf(PDev.DevMode)); - StrCopy(DevMode^.dmDeviceName,Pdev.DevMode.dmDeviceName); - DevMode^.dmOrientation := Pdev.DevMode.dmOrientation; - DevMode^.dmFields := DM_ORIENTATION or DM_PAPERSIZE or DM_COPIES; - DevMode^.dmPaperSize := Pdev.DevMode.dmPaperSize; - DevMode^.dmCopies := Copies; + CopyMemory(DevMode,@PDev.DevMode,SizeOf(PDev.DevMode)); + DevMode^.dmSize := Word(Size); + DevMode^.dmDriverExtra := Word(Extra); + DevMode^.dmFields := Fields; finally GlobalUnLock(DeviceMode); end; @@ -279,24 +258,18 @@ begin try //Set the properties for the selected printer PDev:=TPrinterDevice(Printer.Printers.Objects[Printer.PrinterIndex]); + CopyMemory(@PDev.DevMode,DevMode,sizeof(Pdev.DevMode)); PDev.DevMode.dmSize := SizeOf(PDev.DevMode); - StrCopy(@PDev.DevMode.dmDeviceName,DevMode^.dmDeviceName); - PDev.DevMode.dmOrientation := DevMode^.dmOrientation; - PDev.DevMode.dmFields := DevMode^.dmFields; - PDev.DevMode.dmPaperSize := DevMode^.dmPaperSize; - PDev.DevMode.dmPaperLength := DevMode^.dmPaperLength; - PDev.DevMode.dmPaperWidth := DevMode^.dmPaperWidth; - PDev.DevMode.dmScale := DevMode^.dmScale; - PDev.DevMode.dmCopies := DevMode^.dmCopies; - PDev.DevMode.dmPrintQuality := DevMode^.dmPrintQuality; - PDev.DevMode.dmColor := DevMode^.dmColor; - PDev.DevMode.dmDuplex := DevMode^.dmDuplex; - PDev.DevMode.dmYResolution := DevMode^.dmYResolution; - PDev.DevMode.dmTTOption := DevMode^.dmTTOption; - PDev.DefaultPaper := DevMode^.dmPaperSize; - if DevMode^.dmCopies>1 then Copies := 1 + PDev.DevMode.dmDriverExtra := 0; + if Printer.PaperSize.SupportedPapers.IndexOfObject(TObject(Integer(DevMode^.dmPaperSize))) <> -1 + then + PDev.DefaultPaper := DevMode^.dmPaperSize + else + PDev.DefaultPaper := Integer(Printer.PaperSize.SupportedPapers.Objects[0]); + if nCopies=1 then Copies := DevMode^.dmCopies else - Copies := Old; + Copies := nCopies; + Printer.Copies := Copies; TWinPrinter(Printer).Handle := hDC; finally GlobalUnlock(lpp.hDevMode); @@ -305,9 +278,11 @@ begin PrintRange := prAllPages; PrintToFile := false; + Collate := false; if (Flags and PD_SELECTION)>0 then PrintRange := prSelection; if (Flags and PD_PAGENUMS)>0 then PrintRange := prPageNums; if (Flags and PD_PRINTTOFILE)>0 then PrintToFile := true; + if (Flags and PD_COLLATE)>0 then Collate := true; FromPage := Integer(nFromPage); ToPage := Integer(nToPage); MinPage := Integer(nMinPage); diff --git a/components/printers/win32/winutilprn.pas b/components/printers/win32/winutilprn.pas index b2b478c211..d85c610d7c 100644 --- a/components/printers/win32/winutilprn.pas +++ b/components/printers/win32/winutilprn.pas @@ -49,7 +49,7 @@ const DM_COPIES = $100; Const - Win32Orientations: array [TPrinterOrientation] of Integer = ( + Win32Orientations: array [TPrinterOrientation] of SHORT = ( DMORIENT_PORTRAIT, DMORIENT_LANDSCAPE, DMORIENT_PORTRAIT, DMORIENT_LANDSCAPE); diff --git a/lcl/printers.pas b/lcl/printers.pas index d86981fad5..3097df0cfc 100644 --- a/lcl/printers.pas +++ b/lcl/printers.pas @@ -175,6 +175,7 @@ type function DoGetPrinterState: TPrinterState; virtual; function GetPrinterType : TPrinterType; virtual; function GetCanPrint : Boolean; virtual; + function GetCanRenderCopies : Boolean; virtual; function GetXDPI: Integer; virtual; function GetYDPI: Integer; virtual; public @@ -204,7 +205,7 @@ type property Title: string read fTitle write fTitle; property PrinterType : TPrinterType read GetPrinterType; property CanPrint : Boolean read GetCanPrint; - + property CanRenderCopies : Boolean read GetCanRenderCopies; property XDPI : Integer read GetXDPI; property YDPI : Integer read GetYDPI; end; @@ -677,6 +678,11 @@ begin Result:=True; end; +function TPrinter.GetCanRenderCopies: Boolean; +begin + Result:=True; +end; + { TPaperSize } function TPaperSize.GetDefaultPaperName: string;