人人范文网 范文大全

动态调整打印机纸张大小

发布时间:2020-03-02 00:14:26 来源:范文大全 收藏本文 下载本文 手机版

动态调整打印机纸张大小

江苏省昆山市地方税务局(215300) 陆陈军

信息管理系统中经常要提供各种打印功能,例如报表打印、凭证打印以及发票打印。 在这些打印过程中所需要纸张的大小往往是不一致的,例如,打印报表有可能使用A4纸或 A3纸,打印凭证或发票可能需要将打印纸张设置成自定义大小。如果在同一台打印机上打 印这些内容,那么就应该针对不同的打印内容设置不同的纸张尺寸。显然如果用手动的方 法来设置打印机的纸张尺寸是件很麻烦的事,最好的方法是让程序动态地修改打印机的纸 张尺寸。

解决问题的思路

通过查阅API函数技术文档可知,每个打印机都拥有唯一的一个叫做DevMode的结构, 与打印机相关的各项参数被存放在这个结构中。通过对DevMode结构的分析,发现与设置 打印机纸张大小有关的结构成员有四项:dmFields、dmPaperSize、dmPaperLength以及d mPaperWidth。dmFields是DevMode的标志位初始化部分,如果要修改结构中的某些成员, 那么dmFields中相应位应被置位。dmPaperSize表示打印机当前默认的打印纸张的大小, 若要设置自定义纸张该项应为0(注,上述解释是根据微软提供的技术文档,但是在Delphi 中应将该成员设置成$100即256)。dmPaperLength和dmPaperWidth只是在设置自定义大小 纸张时使用,分别表示纸张的长度和宽度。如何对打印机的DevMode结构进行修改呢?无非 采用两种方法,一种是利用Delphi 提供的TPrinter类中的某些方法,还有一种是调用与打 印有关的API函数。下面就以Delphi为开发工具,以Epson 1600K为默认打印机,用两种不 同的方法来实现这一功能。

方法一:利用Delphi 的TPrinter类

TPrinter类是Delphi对Windows打印处理系统的封装,它能够帮助程序员在开发打印 程序时尽可能地减少工作量。在程序中使用TPrinter,只要在单元的Use子句后面添加Pr inters即可。当前打印机的DevMode结构的句柄可以通过调用Tprinter类中的GetPrinte r方法来获取。当程序获得DevMode结构的句柄后,就调用GlobalLock函数来得到指向该结 构的指针,随后可对结构中的某些成员进行修改。下面就举一个例子来说明这一问题:假 设当前打印机的默认纸张尺寸是A3纸,现在要打印长度为114mm、宽度为190mm的纸张。为 了简单起见,我们只在Form1上放置一个Button1按钮,增加一个OnClick事件,在Use子句后 添加Printers。程序的代码如下:

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;

方法二:利用有关打印的Windows API函数

解决问题的思路和第一种方法类似,首先要获取当前打印机的DevMode结构的指针,然 后再对该结构进行修改,从而修改打印机纸张大小。要完成上述功能,就得调用Document Properties函数。利用该函数程序就可以获取并修改与当前打印机相关的DevMode结构中 的成员。DocumentProperties函数申明如下:

LONG DocumentProperties

(

HWND

hWnd,

HANDLE

hPrinter,

LPTSTR

pDeviceName,

PDEVMODE pDevModeOutput,

PDEVMODE pDevModeInput,

DWORD

fMode

);

六个参数中只有pDevModeOutput是输出变量,其余五个参数必须由程序给出具体值。 其中,hWnd表征当前窗口的句柄值;hPrinter表示当前打印机的句柄;pDeviceName是对打

印机设备的描述;pDevModeOutput是指向句柄值为hPrinter的打印机DevMode结构的指针 ;pDevModeInput是指向一个修改后的DevMode结构的指针,该结构有待于被句柄值为hPri nter的打印机接受;fMode定义了该函数的具体功能,如果取值DM_IN_BUFFER那么表示打印 机接受由参数pDevModeInput表示的由程序修改了的DevMode值,如果取值DM_OUT_BUFFER 那么程序可以通过参数pDevModeOutput来获取打印机的DevMode值,如果fMode为零,则函 数返回的值表示结构DevMode所需的字节数。承接上述例子,现在将190*114大小的纸张设 成A4纸。再往Form1上放置按钮Button2,增加OnClick事件,在Use子句后面添加WinSpool 。代码如下:

Procedure TForm1.Button2Click(Sender: TObject);

var

PrnHd : THandle;

PrnInfo : PPrinterInfo1;

pcbNeeded : DWORD;

PDevModeBytes : DWORD;

DevMode: PDeviceMode;

PrnHdc : HDC;

DocInfo : PDocInfo;

begin

OpenPrinter(‘Epson LQ-1600K\',PrnHd,nil); // 获得打印机句柄PrnHd

GetMem(PrnInfo,1024);

GetPrinter(PrnHd,1,PrnInfo,1024,@pcbNeeded);

PDevModeBytes := DocumentProperties( Handle,PrnHd,prninfo^.pDescription, DevMode^,DevMode^,0 );

{ 获取DevMode结构所需的字节数 }

GetMem(DevMode,PDevModeBytes); // 给结构DevMode分配空间

DocumentProperties( Handle,PrnHd,PrnInfo^.pDescription,DevMode^,DevMode^ ,DM_OUT_BUFFER ); // 获取打印机的DevMode结构

With DevMode^ do begin

dmPaperSize := DMPAPER_A4

; // 将纸张设置成A4纸

dmFields := dmFields or DM_PAPERSIZE;

end;

DocumentProperties( Handle,PrnHd,PrnInfo^.pDescription,DevMode^,DevMode^ ,DM_OUT_BUFFER or DM_IN_BUFFER);//修改DevMode 结构。

{ 下面的代码是为了测试打印机是否按A4纸大小来打印 }

PrnHdc := CreateDC( nil, ‘Epson LQ-1600K\',nil,DevMode );

GetMem( DocInfo, 100 );

With DocInfo^ do begin

cbSize := sizeof(DocInfo);

lpszDocName := nil;

lpszOutput := nil;

lpszDatatype := nil;

fwType := DI_APPBANDING;

end;

StartDoc( PrnHdc, DocInfo^);

StartPage(PrnHdc);

TextOut( PrnHdc, 10, 10, ‘Hello My Friend!\',17);

EndPage(PrnHdc);

EndDoc(PrnHdc);

DeleteDC(PrnHdc);

FreeMem(DocInfo);

FreeMem(PrnInfo);

FreeMem(DevMode);

end;

至此,程序实现了本文开头所提出的要求。需要指出的是,上述代码是在程序运行时

,动态地改变打印机纸张大小,而不改变打印机默认纸张大小。也就是说当打印程序运行 结束后,打印机还是会按照默认打印纸张大小来打印、走纸。动态调整打印机纸张尺寸也 是因打印机而异,某些打印机基本不支持自定义纸张,例如惠普的HP DeskJet 1120C 喷墨 打印机以及众多激光打印机。因此在这些打印机上,不能实现按任意纸张大小打印。对于 一些针式打印机则没有上述问题。

上述程序是在Windows 95环境下,用Delphi 4.0为开发工具调试通过。

纸张大小

A1A2A3A4纸张大小

a5纸张大小

A、B系列纸张大小

打印纸张规格大小

自荐信纸张大小是多少

自荐信纸张大小是多少

打印纸张大小设置

书法纸张作品的大小

word不同大小纸张设置方法

动态调整打印机纸张大小
《动态调整打印机纸张大小.doc》
将本文的Word文档下载到电脑,方便编辑。
推荐度:
点击下载文档
点击下载本文文档