动态调整打印机纸张大小.doc_第1页
动态调整打印机纸张大小.doc_第2页
动态调整打印机纸张大小.doc_第3页
动态调整打印机纸张大小.doc_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

动态调整打印机纸张大小 江苏省昆山市地方税务局(215300) 陆陈军信息管理系统中经常要提供各种打印功能,例如报表打印、凭证打印以及发票打印。在这些打印过程中所需要纸张的大小往往是不一致的,例如,打印报表有可能使用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。程序的代码如下:Procedure TForm1.Button1Click(Sender: TObject);varDevice : array0.cchDeviceName - 1 of Char;Driver : array0.(MAX_PATH-1) of Char;Port : array0.32of Char;hDMode : THandle;pDMode : PDevMode;beginPrinter.GetPrinter(Device,Driver,Port,hDMode);/ 获取打印机DevMode结构的句柄值,存放在hDMode中if hDMode 0 then beginpDMode := GlobalLock(hDMode); / 获取指向打印机DevMode结构的/ 指针if pDMode nil then beginpDMode.dmPaperSize := 256; / 如果要将当前打印机纸张变为自定义dmPaperSize必须设置成256pDMode.dmPaperLength := 1140;pDMode.dmPaperWidth := 1900;pDMode.dmFields := pDMode.dmFields orDM_PAPERSIZE;pDMode.dmFields := pDMode.dmFields orDM_PAPERLENGTH;pDMode.dmFields := pDMode.dmFields orDM_PAPERWIDTH; 以上三条语句是对相应的dmFields成员进行置位。ResetDC(Printer.Handle,pDMode); /设置打印机设备环境句柄的值GlobalUnlock(hDMode);end;end; 下面的代码是为了测试打印机是否按190*114纸张大小来打印 with Printer do beginBeginDoc;Canvas.TextOut(10,10,Hello, My Friend!);EndDoc;end;end;方法二:利用有关打印的Windows API函数解决问题的思路和第一种方法类似,首先要获取当前打印机的DevMode结构的指针,然后再对该结构进行修改,从而修改打印机纸张大小。要完成上述功能,就得调用DocumentProperties函数。利用该函数程序就可以获取并修改与当前打印机相关的DevMode结构中的成员。DocumentProperties函数申明如下:LONG DocumentProperties(HWND hWnd,HANDLEhPrinter,LPTSTRpDeviceName,PDEVMODE pDevModeOutput,PDEVMODE pDevModeInput,DWORDfMode);六个参数中只有pDevModeOutput是输出变量,其余五个参数必须由程序给出具体值。其中,hWnd表征当前窗口的句柄值;hPrinter表示当前打印机的句柄;pDeviceName是对打印机设备的描述;pDevModeOutput是指向句柄值为hPrinter的打印机DevMode结构的指针;pDevModeInput是指向一个修改后的DevMode结构的指针,该结构有待于被句柄值为hPrinter的打印机接受;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);varPrnHd : THandle;PrnInfo : PPrinterInfo1;pcbNeeded : DWORD;PDevModeBytes : DWORD;DevMode: PDeviceMode;PrnHdc : HDC;DocInfo : PDocInfo;beginOpenPrinter(Epson LQ-1600K,PrnHd,nil); / 获得打印机句柄PrnHdGetMem(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 begindmPaperSize := 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 begincbSize := 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;至此,程序实现了本文开头所提出的要求。需要指出的是,上述代码是在程序运行时,动态地改变打印机纸张

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论