VFP下打印机的设置编程

VFP下打印机的设置编程
2008-09-29 13:03
VFP本身提供了部分相关打印机的数据返回函数以及部分设置项,但在打印机的直接控制方面没有提供
相应的策略,这里从分析打印机的Devmode和PRINTER_INFO_2的结构来详细说明一下VFP打印机的相关操作编程。首先看下打印机的基本数据结构Devmode:

Private Type DEVMODE
    dmDeviceName As String * 32 &&打印设备名称,每个打印机驱动程序都有一个唯一的字符串。
    dmSpecVersion As Integer     &&指定 Win32 软件开发工具包中 DEVMODE 结构的版本号。
    dmDriverVersion As Integer   &&指定由打印机驱动程序开发商分配的打印机驱动程序版本号。
    dmSize As Integer            &&指定 DEVMODE 结构的字节大小。
    dmDriverExtra As Integer     &&指定设备的数据可选 dmDriverData 成员的字节大小。
    dmFields As Long             &&指定 DEVMODE 结构中的哪些其余成员已被初始化。
    dmOrientation As Integer     &&指定纸张的方向。它可以为 1(纵向)或 2(横向)。
    dmPaperSize As Integer       &&指定打印的纸张大小。
    dmPaperLength As Integer     &&替代由PaperSize成员为自定义纸张大小的高度,PaperSize为0或256时有效。
    dmPaperWidth As Integer      &&代由PaperSize成员为自定义纸张大小的宽度,PaperSize为0或256时有效。
    dmScale As Integer           &&指定打印输出的缩放系数,输出的纸张大小是按缩放值/100从实际纸张大小缩放得到的。
    dmCopies As Integer          &&指定打印份数(如果打印设备支持多页打印)。
    dmDefaultSource As Integer   &&指定送纸的默认纸盒。
    dmPrintQuality As Integer    &&指定打印机的分辨率。值: -4高品质、-3中品质、-2低品质和 -1草稿。
    dmColor As Integer           &&指定是否以彩色打印输出结果。值为 1(彩色)和 2(单色)。
    dmDuplex As Integer          &&指定是否在纸张的双面打印输出结果。1单面、2水平、3垂直。(需要打印机支持)
    dmYResolution As Integer     &&指定打印机的 y 方向分辨率(以每英寸点数 (dpi) 为单位)。
    dmTTOption As Integer        &&指定如何打印 TrueType 字体。
    dmCollate As Integer         &&指定在打印多份时是否使用逐份打印。
    dmFormName As String * 32    &&指定要使用的纸张大小;例如,“Letter”或“Legal”。
    dmUnusedPadding As Integer   &&用于在将来的版本中填充空格、字符或数值。
    dmBitsPerPel As Integer      &&指定显示设备的颜色分辨率(以每像素的位数为单位)。
    dmPelsWidth As Long          &&指定可见设备表面(屏幕或打印机)的宽度(以像素为单位)。
    dmPelsHeight As Long         &&指定可见设备表面(屏幕或打印机)的高度(以像素为单位)。
    dmDisplayFlags As Long       &&指定设备的显示模式。
    dmDisplayFrequency As Long   &&指定显示设备在特定模式下的频率(以赫兹(每秒周数)为单位)。
End Type

从上面的Devmode的结构我们可以看出,该结构几乎囊口了打印机设置的全部参数,那么我们在进行打印机的相关
编程设计时只要改变该结构的相关参数值就可以了,而且打印机的专用动态连接库winspool.drv也为我们提供了
两个相关的设置函数:DocumentProperties和SetPrinter,我们先看下这两个函数的VFP声明及相关说明:
DECLARE INTEGER DocumentProperties IN winspool.drv;
                INTEGER hWnd,;
                INTEGER hPrinter,;
                STRING pDeviceName,;
                STRING @pDevModeOutput,;
                STRING @pDevModeInput,;
                INTEGER fMode
说明:  
这是一个灵活的打印机配置控制函数。该函数定义了两个DEVMODE结构,可在创建一个设备场景时为单个应用程序改变
打印机设置。甚至能在文档打印期间改变打印机设置 。
返回值:  
Long,由fMode字段的值决定。如下所示:  
若fMode为零,这个函数就返回DEVMODE结构的尺寸。注意这个结构可能比类型定义文件API32.TXT中规定的尺寸大  
若fMode设置了DM_IN_PROMPT标志,那么打印机设置对话框就会出现。在这种情况下,
返回值将是常数IDOK 或IDCANCEL——具体由用户关闭对话框时按下的按钮决定  
在其他任何情况下,该函数执行成功后会返回IDOK。而在任何情况下,如函数执行失败,都会返回一个负数 。
参数表     
参数             类型 及说明     
hwnd             Long,对话框父窗口的句柄。这通常是当前的活动窗体     
hPrinter         Long,一个已打开的打印机对象的句柄     
pDeviceName      String,打印机的名字     
pDevModeOutput   Long,指向一个DEVMODE数据结构的指针。请参考DocumentProperties运行模式表。
注意这个指针必须引用一个足够大的缓冲区,它能同时容下专用打印机驱动程序数据,以及标准的DEVMODE结构    
pDevModeInput   Long,指向一个DEVMODE数据结构的指针。请参考DocumentProperties运行模式表     
fMode   Long,决定这个函数运作模式的一个标志。请参考DocumentProperties运行模式表。

这个函数应当注意的一点就是它是设置针对当前的单个应用程序有效的,如果要设置全局有效则使用SetPrinter函数。
我们再看下SetPrinter的声明:
DECLARE INTEGER SetPrinter IN winspool.drv;
        INTEGER hPrinter,;
        INTEGER lvl,;
        STRING @ pPrinter,;
        INTEGER cmd
说明
对一台打印机的状态进行控制
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表 参数 类型及说明
hPrinter Long,指定一个已打开的打印机的句柄(用OpenPrinter取得)
Level Long,0,2或3(4或5用于windows95,5或6用于NT 4.0)。如Command不是零,则这个参数必须是零
pPrinter Byte,包含一个PRINTER_INFO_x的结构的缓冲区,其中的x代表级别的设定(Level)。
Command Long,下述值之一:                   
零 根据PRINTER_INFO_x结构改变打印机
PRINTER_CONTROL_PAUSE 暂停打印机
PRINTER_CONTROL_PURGE 删除打印机的所有作业
PRINTER_CONTROL_RESUME 恢复一台暂停的打印机
PRINTER_CONTROL_SET_STATUS 载入打印机的PRINTER_CONTROL_STATUS结构(不可在NT 3.51下使用)
注解
在PRINTER_INFO_2结构的基础上设置打印机状态时,pServerName,AveragePPM,Status和cJobs字段都会被忽略

改函数被用来对某一打印机进行一个全局设置。
改函数引用了一个在PRINTER_INFO_X结构,起结构定义如下:
Type PRINTER_INFO_2
    pServerName As Long
    pPrinterName As Long
    pShareName As Long
    pPortName As Long
    pDriverName As Long
    pComment As Long
    pLocation As Long
    pDevMode As Long   &&DevMode结构指针
    pSepFile As Long
    pPrintProcessor As Long
    pDataType As Long
    pParameters As Long
    pSecurityDescriptor As Long
    Attributes As Long
    Priority As Long
    DefaultPriority As Long
    StartTime As Long
    UntilTime As Long
    Status As Long
    cJobs As Long
    AveragePPM As Long
End Type

OK!现在我们就可以来根据这两个结构来定义自己的打印机了,首先我们先看下如何用DocumentProperties函数和DEVMODE
结构来定义当前程序的打印机:

本篇文章所需要的API声明:


DECLARE INTEGER OpenPrinter IN winspool.drv;
         STRING pPrinterName, INTEGER @phPrinter, INTEGER pDefault
DECLARE INTEGER GetProfileString IN kernel32;
         STRING lpApp, STRING lpKey, STRING lpDefault,;
         STRING @lpReturnedString, INTEGER nSize
DECLARE INTEGER ClosePrinter IN winspool.drv INTEGER hPrinter
DECLARE INTEGER DocumentProperties IN winspool.drv;
         INTEGER hWnd, INTEGER hPrinter, STRING pDeviceName,;
         STRING @pDevModeOutput, STRING @pDevModeInput, INTEGER fMode
DECLARE INTEGER SetPrinter IN winspool.drv;
        INTEGER hPrinter,;
        INTEGER lvl,;
        STRING @ pPrinter,;
        INTEGER cmd
DECLARE INTEGER GetPrinter IN winspool.drv AS GetPrinterA;
        INTEGER   hPrinter,;
        INTEGER   Lvl,;
        STRING   @pPrinter,;
        INTEGER   cbBuf,;
        INTEGER @ pcbNeeded


示例1:用DocumentProperties函数来更改当前程序打印机的打印方向:
*-----------------------------------------------------------------*
*-VFP应用程式算法群:12787940 行者孙:310727570-*
*-----------------------------------------------------------------*
#DEFINE IDCANCEL 2&&横向
#DEFINE DM_OUT_BUFFER 2
#DEFINE DM_IN_BUFFER 8
#DEFINE DM_IN_PROMPT 4
local hWindow, cPrinter, cDriver, cPort, hPrinter, nBufsize, cDevmode
APRINTERS(gaPrinters)&&改函数用来获取VFP默认打印机名称,注意VFP默认并不代表系统全局默认。
cPrinter=gaPrinters(1,1)
hPrinter = 0
OpenPrinter(cPrinter,@hPrinter,0)
IF hPrinter = 0
     Messagebox("不能打开默认打印机!", 48, "错误")
     RETURN
ENDIF
nBufsize = DocumentProperties(hWindow, hPrinter, cPrinter,0,0,0)&&获取DEVMODE结构大小
cDevmode = Repli(Chr(0), nBufsize)
nOrient= DMORIENT_LANDSCAPE&&横向
DocumentProperties(hWindow, hPrinter, cPrinter, @cDevmode, 0, DM_OUT_BUFFER)&&获取DEVMODE结构缓冲区字串
cDevmode=SUBSTR(cDevmode,1,44)+BINTOC(nOrient,'2rs')+SUBSTR(cDevmode,47,nBufsize-47)&&更改DEVMODE结构中打印走向的部分
DocumentProperties(hWindow, hPrinter, cPrinter, @cDevmode,@cDevmode,DM_IN_BUFFER+DM_OUT_BUFFER)&&更新打印机DEVMOD
DocumentProperties(hWindow, hPrinter, cPrinter, @cDevmode, @cDevmode, DM_IN_PROMPT+DM_IN_BUFFER+DM_OUT_BUFFER)&&看看变了没
ClosePrinter(hPrinter)

这样设置打印机是不是很简单?如果在VFP中测试本段代码会发现在VFP中打印机设置确实变了,但在控制面板中并没有变,这就是所谓的
DocumentProperties函数是用来设置当前单一程序的打印机。
OK,接下来我们再利用SetPrinter来设置系统打印机:
示例2:用SetPrinter来进行系统打印机的走向和纸张设置
*-----------------------------------------------------------------*
*-VFP应用程式算法群:12787940 行者孙:310727570-*
*-----------------------------------------------------------------*
nOrient=2&&横向
PaperSize=0x0B&& A5
nSize=0
lcBuffer = Repli(Chr(0), 120)
GetProfileString("Windows", "Device", ",,,",    @lcBuffer, Len(lcBuffer))
lcBuffer = STRTRAN(lcBuffer, Chr(0), "")
cPrinter = SUBSTR(lcBuffer, 1, AT(",", lcBuffer, 1)-1)&&系统当前默认打印机名称
hPrinter = 0
OpenPrinter(cPrinter,@hPrinter,0)
nBufsize = DocumentProperties(0, hPrinter,cPrinter,0,0,0)
GetPrinterA(hPrinter,2,0,0,@nSize)
pPrinter=REPLICATE(CHR(0),nSize)
GetPrinterA(hPrinter,2,@pPrinter,nSize,@nSize)
s=CTOBIN(SUBSTR(pPrinter,29,4),'4rs')
cDevmode=SYS(2600,s,nBufsize)&&读取Devmode结构
aDevmode=AT(cDevmode,pPrinter)&&找出Devmode结构在PRINTER_INFO_2中的位置
&&设置新的走向,就是把PRINTER_INFO_2中的Devmode结构中的走向改掉
pPrinter=STUFF(pPrinter,aDevmode+44,1,CHR(nOrient))
pPrinter=STUFF(pPrinter,aDevmode+76,1,CHR(nOrient))
&&纸张就是把PRINTER_INFO_2中的Devmode结构中的纸张改掉
pPrinter=STUFF(pPrinter,aDevmode+46,1,CHR(PaperSize))
pPrinter=STUFF(pPrinter,aDevmode+78,1,CHR(PaperSize))
SetPrinter(hPrinter,2,@pPrinter,0)
ClosePrinter(hPrinter)

再打开控制面板中的默认打印机看看是不是走向和纸张都变了?
就这么简单,大家可以利用Devmode结构设计出几乎包括打印机设置参数的程式。
展开阅读全文

没有更多推荐了,返回首页