打印机表单的动态设置研究与实现
[摘要]针式打印机打印分为分页打印和连续不分页打印,但利用Printer对象在不同的操作系统下进行打印设计差异较大,尤其是动态设置打印纸的类型,及动态改变打印纸的长度。在Windows98下可以很简单的利用Printer.Width和Printer.Height进行设置,但在Windows2000及XP下却相当困难。
[关键词]Printer 动态设置 连续不分页打印 分页打印
中图分类号:TP3 文献标识码:B 文章编号:1002-6908(2007)032-048-02
一、简介
打印是很多应用程序中都需要的功能,也是开发的一个难点所在,尤其是要求连续打印长度任意的表单,并且要求打印完不走纸的情况。类似这样的打印任务因其长短不一,需要在程序中自动计算出单据的长度并自动设定相应的纸张。
在VB下使用Printer对象对针式打印机进行打印程序设计时,因操作系统不同导致设计方法也不相同,在Windows98中将Printer.PaperSize设为256(自定义大小),再通过Printer.
Height、Printer.Width设为所要求的值即可实现,而Win2000/
XP下Printer.PaperSize=256却提示无效属性值,也就无法完成所要求的功能。
二、打印机页形设置原理
在运行 Windows 95、Windows 98 或 Windows Me 系统上,可以用高度(长度)和宽度或预定义的纸张大小来定义自定义页面大小。基于 Windows NT 或 Windows 2000及XP的系统仅使用定义的页形来指定页面大小。纸张的大小由DevMode结构的四个属性决定:
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmFormName As String * CCHFORMNAME
其中dmFormName用于NT系统中指定打印纸张大小为预定义的某个纸张(Form),但是VB的 Printer对象不支持FormName属性,故只能通过API函
数修改DevMode结构的dmFormName属性实现自定义打印。
在Windows NT 或Windows 2000及XP系统上使用特定的纸张大小,则必须为其定义一个页形。VB中的Printer对象具有PageSize、Height和Width属性,对应于DEVMODE的dmPaperSize、dmPaperLength 和dmPaperWidth 成员。但是Printer 对象未提供按名称选择页形的方式,而且也未提供在运行时添加自定义页形的方法,所以必须使用Win32 应用程序编程接口 (API) 来创建自定义页形或按名称选择页形。
在自定义页形时,使用的打印机表单描述结构FORM_INFO_1定义如下:
Type FORM_INFO_1
Flags As Long
pName As Long
Size As SIZEL
ImageableArea As RECT
End Type
SIZEL结构如下:
Public Type SIZEL
cx As Long
cy As Long
End Type
其中cx、cy为实际所要定义的打印纸尺寸。
在自定义页形时,使用Win32应用程序编程接口 (API)如下:
OpenPrinter:打开指定的打印机,并获取打印机的句柄。
DeleteForm:从打印机可用表单列表中删除一个表单。
AddForm:为打印机的表单列表添加一个新表单。
EnumForms:枚举一台打印机可用的表单。
GetPrinter:取得与指定打印机有关的信息。
SetPrinter:对一台打印机的状态进行控制。
CopyMemory:将从源指针所指处开始的长度为Length的内存拷贝到目的指针所指的内存处。
三、打印设计
Printer对象是一个独立于打印机设备的封装,它可以代表不同的打印机,初始时Printer对象为系统缺省的打印机。
(一)分页打印
利用Printer对象开发的打印程序主要靠其提供的NewPage(打印新的一页),CurrentX、CurrentY(置为新页的左上角,可完成多页功能),EndDoc(将打印任务加入打印机队列),KillDoc( 取消打印任务)来控制打印过程。一般情况下,打印程序完成多页打印时会多次执行NewPage,结束时执行一次EndDoc将打印任务加入打印机队列。
在进行分页打印时先确定每页打印的行数,根据行数确定能打印的页数,同时给出Printer.CurrentX,Printer.CurrentY,使用Printer.Print进行打印,当一页满以后使用Printer.NewPage来确定本页打印完毕换页。当打印新页前要重新给出Printer.CurrentX,Printer.CurrentY重复上述步骤。
(二)不分页连续打印
在Win2000/XP下同样使用Printer对象进行打印程序开发,根据具体情况动态确定打印纸的宽度及长度,然后在服务器属性中添加自定义表单,使用Windows API函数AddForm设置其宽度、长度,把项目中所需要的实际尺寸作为新纸型的宽度和高度,然后使用Windows API函数EnumForms枚举表单,从表单列表中取出所定义表单序号,根据表单名及表单序号利用SetPrinter 设置默认打印机的打印首选项为自定义表单。
四、动态设置连续打印实现
(一)添加新表单
自定义添加表单函数AddNewForm(hPrinter As Long, Form
Size As SIZEL, strFormName As String) As String ,首先使用OpenPrinter(Printer.DeviceName, mhPrinter, 0&)系统函数打开指定的打印机,并获取打印机的句柄mhPrinter,对打印机表单描述结构的变量FI1赋值,FI1.pName
为自定义表单名,FI1.Size自定义打印媒介尺寸,值为FormSizeFI1.ImageableArea 绘图的实际区域,值为FI1.Size。
对已经建立的表单,将其设置到打印机,其步骤如下:首先动态创建Byte类型数组,ReDim aFI1(Len(FI1)) As Byte,调用内存拷贝函数CopyMemory将打印机表单描述结构的变量FI1内容拷贝到内存动态数组中即aFI1,使用语句CopyMemory(aFI1(0), FI1, Len(FI1)),然后删除打印机中与自定义表单同名表单,DeleteForm(mhPrinter, FI1.pName) ,即以前设置的不同高度的表单,然后利用系统函数将新建表单添加到打印机中,其使用语句为AddForm(mhPrinter, 1, aFI1(0)),返回所添加的表单名。
(二)获取自定义表单序号
对打印机表单进行动态设置时不能直接使用表单的名称,只能使用表单的序号,为此自定义函数GetFormNum以获得新添加的表单序号,其参数为新建表单的名称,如下:Public Function GetFormNum(hFormName As Variant) As Variant,在函数中定义一个FORM_INFO_1结构变量FI1和一个数组aFI1()。
因篇幅问题不能全部显示,请点此查看更多更全内容