Delphi VCL中能否通过代码设置TPrintDialog的打印机名与纸张尺寸?
Delphi VCL中TPrintDialog恢复上次打印参数的实现方法
要让TPrintDialog直接加载上次保存的打印机、纸张尺寸和打印方向,核心是通过操作TPrintDialog封装的Windows PRINTDLG结构体和打印机的DevMode参数实现,无需自定义对话框。
步骤1:保存上次打印参数
用户确认打印后,从TPrintDialog的Printer对象中提取参数,存入配置文件(示例用INI):
procedure SavePrintSettings(const IniFile: string; PrintDialog: TPrintDialog); var Ini: TIniFile; DevMode: PDevMode; CurrPrinterName: string; begin Ini := TIniFile.Create(IniFile); try // 保存当前打印机名称 CurrPrinterName := PrintDialog.Printer.Printers[PrintDialog.Printer.PrinterIndex]; Ini.WriteString('PrintSettings', 'PrinterName', CurrPrinterName); // 获取打印机DevMode结构,保存方向、纸张尺寸 DevMode := PrintDialog.Printer.DevMode; if Assigned(DevMode) then begin Ini.WriteInteger('PrintSettings', 'Orientation', DevMode^.dmOrientation); Ini.WriteInteger('PrintSettings', 'PaperSize', DevMode^.dmPaperSize); // 自定义纸张需额外保存宽高 if DevMode^.dmPaperSize = DMPAPER_USER then begin Ini.WriteInteger('PrintSettings', 'PaperWidth', DevMode^.dmPaperWidth); Ini.WriteInteger('PrintSettings', 'PaperLength', DevMode^.dmPaperLength); end; end; finally Ini.Free; end; end;
步骤2:加载参数到TPrintDialog
在调用Execute前,读取配置文件并修改TPrintDialog的相关参数:
procedure LoadPrintSettings(const IniFile: string; PrintDialog: TPrintDialog); var Ini: TIniFile; TargetPrinterName: string; PrinterIdx: Integer; DevMode: PDevMode; begin Ini := TIniFile.Create(IniFile); try TargetPrinterName := Ini.ReadString('PrintSettings', 'PrinterName', PrintDialog.Printer.Printers[0]); // 定位目标打印机索引,不存在则用默认 PrinterIdx := PrintDialog.Printer.Printers.IndexOf(TargetPrinterName); if PrinterIdx >= 0 then PrintDialog.Printer.PrinterIndex := PrinterIdx; // 修改DevMode参数 DevMode := PrintDialog.Printer.DevMode; if Assigned(DevMode) then begin DevMode^.dmOrientation := Ini.ReadInteger('PrintSettings', 'Orientation', DMORIENT_PORTRAIT); DevMode^.dmPaperSize := Ini.ReadInteger('PrintSettings', 'PaperSize', DMPAPER_LETTER); // 恢复自定义纸张尺寸 if DevMode^.dmPaperSize = DMPAPER_USER then begin DevMode^.dmPaperWidth := Ini.ReadInteger('PrintSettings', 'PaperWidth', 0); DevMode^.dmPaperLength := Ini.ReadInteger('PrintSettings', 'PaperLength', 0); end; // 标记DevMode字段已修改,确保对话框生效 DevMode^.dmFields := DevMode^.dmFields or DM_ORIENTATION or DM_PAPERSIZE or DM_PAPERWIDTH or DM_PAPERLENGTH; end; // 关键:修改对话框Flags,强制使用自定义DevMode参数 PrintDialog.PrintDlgStruct.Flags := PrintDialog.PrintDlgStruct.Flags and not PD_RETURNDEFAULT; PrintDialog.PrintDlgStruct.Flags := PrintDialog.PrintDlgStruct.Flags or PD_USEDEVMODECOPIESANDCOLLATE; finally Ini.Free; end; end;
步骤3:调用示例
procedure TMainForm.btnPrintClick(Sender: TObject); var PrintDlg: TPrintDialog; begin PrintDlg := TPrintDialog.Create(nil); try LoadPrintSettings('PrintConfig.ini', PrintDlg); if PrintDlg.Execute then begin // 执行打印逻辑 PrintDlg.Printer.BeginDoc; PrintDlg.Printer.Canvas.TextOut(100, 100, '打印测试内容'); PrintDlg.Printer.EndDoc; // 保存本次打印参数 SavePrintSettings('PrintConfig.ini', PrintDlg); end; finally PrintDlg.Free; end; end;
注意事项
- 若保存的打印机已被移除,会自动 fallback 到系统默认打印机;
- 自定义纸张尺寸需目标打印机支持,否则会被打印机驱动自动修正;
- 必须修改
PrintDlgStruct.Flags,否则自定义的DevMode参数不会被对话框加载。
内容的提问来源于stack exchange,提问作者user2580203
相关产品推荐
相关产品推荐

