You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用TMetafilePrinter时如何正确获取纸张尺寸?

解决TMetafilePrinter获取纸张尺寸始终返回屏幕尺寸的问题

你遇到的这个问题很典型——TMetafilePrinter如果没有正确绑定打印机设备并配置纸张参数,它的Canvas Handle会默认关联到屏幕DC,导致GetDeviceCaps返回的是屏幕物理尺寸而非纸张尺寸。下面是具体的分析和解决方案:

问题根源

当你直接创建TMetafilePrinter而未指定打印机、未设置纸张参数就调用BeginDoc时,组件会 fallback 到使用屏幕设备上下文(DC),这就是为什么无论你选A3/A4/A5还是横竖方向,得到的都是固定的屏幕尺寸值。

解决方案

要正确获取打印机纸张的尺寸,需要按以下步骤操作:

  1. 绑定目标打印机:明确指定要使用的打印机(默认打印机或特定打印机)
  2. 配置纸张参数:在BeginDoc前设置纸张大小和页面方向
  3. 正确获取尺寸:可以通过GetDeviceCaps获取物理尺寸,或直接使用组件内置属性获取像素尺寸

完整代码示例

var
  MFPrinter: TMetaFilePrinter;
  DC: HDC;
  PhysicalW, PhysicalH, PixelW, PixelH: Integer;
begin
  MFPrinter := TMetaFilePrinter.Create(nil);
  try
    // 绑定到系统默认打印机(也可通过PrinterIndex指定特定打印机)
    MFPrinter.PrinterIndex := Printer.PrinterIndex;
    
    // 设置纸张尺寸(可选psA3/psA4/psA5等)
    MFPrinter.PaperSize := psA4;
    // 设置页面方向(可选poPortrait纵向/poLandscape横向)
    MFPrinter.Orientation := poPortrait;
    
    // 启动文档打印流程
    MFPrinter.BeginDoc;
    try
      DC := MFPrinter.Canvas.Handle;
      
      // 获取纸张物理尺寸(单位:毫米)
      PhysicalW := GetDeviceCaps(DC, HORZSIZE);
      PhysicalH := GetDeviceCaps(DC, VERTSIZE);
      ShowMessageFmt('纸张物理尺寸:%dmm × %dmm', [PhysicalW, PhysicalH]);
      
      // 获取纸张像素尺寸(基于打印机DPI)
      PixelW := MFPrinter.PageWidth;
      PixelH := MFPrinter.PageHeight;
      ShowMessageFmt('纸张像素尺寸:%dpx × %dpx', [PixelW, PixelH]);
    finally
      // 结束文档流程
      MFPrinter.EndDoc;
    end;
  finally
    MFPrinter.Free;
  end;
end;

额外注意事项

  • 如果需要使用自定义纸张尺寸,可以设置MFPrinter.PaperSizepsCustom,然后手动指定PaperWidthPaperHeight(单位:百分之一英寸)
  • 若设置的纸张尺寸不被当前打印机驱动支持,组件会自动 fallback 到打印机的默认纸张,建议先调用MFPrinter.Refresh加载打印机的可用纸张列表
  • GetDeviceCapsHORZSIZE/VERTSIZE返回物理尺寸,HORZRES/VERTRES返回对应像素数,可根据你的业务需求选择

内容的提问来源于stack exchange,提问作者Pele

火山引擎 最新活动