You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 07:05:09