Delphi 动态调整打印机纸张大小
信息
管理系统中经常要提供各种打印功能,例如报表打印、凭证打印以及发票打印。在这些打印过程中所需要纸张的大小往往是不一致的,例如,打印报表有可能使用A4 纸或A3 纸,打印凭证或发票可能需要将打印纸张设置成自定义大小。如果在同一台打印机上打印这些内容,那么就应该针对不同的打印内容设置不同的纸张尺寸。显然如果用手动的方法来设置打印机的纸张尺寸是件很麻烦的事,最好的方法是让程序动态地修改打印机的纸张尺寸。
解决问题的思路
通过查阅API 函数技术
文档可知,每个打印机都拥有唯一的一个叫做DevMode 的结构,与打印机相关的各项参数被存放在这个结构中。通过对DevMode 结构的分析,发现与设置打印机纸张大小有关的结构成员有四项:dmFields、dmPaperSize、dmPaperLength 以及dmPaperWidth。dmFields 是DevMode 的标志位初始化部分,如果要修改结构中的某些成员,那么dmFields 中相应位应被置位。dmPaperSize 表示打印机当前默认的打印纸张的大小,若要设置自定义纸张该项应为0(注,上述解释是根据微软提供的技术
文档,但是在Delphi 中应将该成员设置成$100 即256)。dmPaperLength 和dmPaperWidth 只是在设置自定义大小纸张时使用,分别表示纸张的长度和宽度。如何对打印机的DevMode 结构进行修改呢?无非采用两种方法,一种是利用Delphi 提供的TPrinter 类中的某些方法,还有一种是调用与打印有关的API 函数。下面就以
Delphi 为开发工具,以Epson 1600K 为默认打印机,用两种不同的方法来实现这一功能。
方法一:利用Delphi 的TPrinter 类
TPrinter 类是Delphi 对Windows 打印处理
系统的封装,它能够帮助程序员在开发打印程序时尽可能地减少
工作量。在程序中使用TPrinter,只要在单元的Use 子句后面添加Printers 即可。当前打印机的DevMode 结构的句柄可以通过调用Tprinter 类中的GetPrinter 方法来获取。当程序获得DevMode 结构的句柄后,就调用GlobalLock 函数来得到指向该结构的指针,随后可对结构中的某些成员进行修改。下面就举一个例子来说明这一
问题:假设当前打印机的默认纸张尺寸是A3 纸,现在要打印长度为114mm、宽度为190mm 的纸张。为了简单起见,我们只在Form1 上放置一个Button1 按钮,增加一个OnClick 事件,在Use 子句后添加Printers。
程序的代码如下:
delphi代码
Procedure TForm1.Button1Click(Sender: TObject);
var
Device : array[0..cchDeviceName -1] of Char;
Driver : array[0..(MAX_PATH -1)] of Char;
Port : array[0..32]of Char;
hDMode : THandle;
pDMode : PDevMode;
begin
Printer.GetPrinter(Device,Driver,Port,hDMode);
// 获
取打印机DevMode 结构的句柄值,
存放在hDMode 中
if hDMode < > 0 then begin
pDMode := GlobalLock(hDMode);
// 获取指向打印机DevMode 结构的// 指针
if pDMode < > nil then begin
pDMode^.dmPaperSize := 256;
// 如果要将当前打印机纸张变为自定义
dmPaperSize 必须设置成256
pDMode^.dmPaperLength := 1140;
pDMode^.dmPaperWidth := 1900;
pDMode^.dmFields := pDMode^.dmFields or
DM_PAPERSIZE;
pDMode^.dmFields :=
pDMode^.dmFields or DM_PAPERLENGTH;
pDMode^.dmFields :=
pDMode^.dmFields or DM_PAPERWIDTH;
{以上三条语句是对相应
的dmFields 成员进行置位。}
ResetDC(Printer.Handle,pDMode^);
// 设置打印机设备环境句柄的值
GlobalUnlock(hDMode);
end;
end;
{ 下面的代码是为了测试打印机是否
按190 *114 纸张大小来打印}
with Printer do begin
BeginDoc;
Canvas.TextOut(10,10,'Hello, My Friend!');
EndDoc;
end;
end;
Procedure TForm1.Button1Click(Sender: TObject);
var
Device : array[0..cchDeviceName -1] of Char;
Driver : array[0..