admin管理员组文章数量:1536088
2024年6月17日发(作者:)
EM F虚拟打印机的实现
张生生
(福建实达电脑设备有限公司福建福州350002)
【摘要】:本文简单分析了Windows(Win2000及之后的)操作系统的打印驱动程序的架构,并介
绍了一种利用其spooler组件中的processor实现EMF虚拟打印机的方法。
【关键词】:虚拟打印机EMF Spooler组件Processor
1.引言
Provider几个部分构成。Winspoo1.dry(含)之前部分是
2.1 GDI——Windows图形用户接口。
随着应用软件的不断发展,各种新的需求不断出
客户端,之后的为服务端。
现,很多时候需要将各种文档转换成特定的格式。虚
拟打印机应此而生。虚拟打印机的本质就是实现文档
应用程序调用此接口的绘图函数,再通过这些函
类型转换,对于这种程序的制作者,他无需了解各种 数调用图形渲染引擎(GRE),配合调用打印机图形驱
被转换文档的内在格式,降低了实现难度;而对于使 动库,实现最终打印图像。
用者,它是一款打印机,在各种有打印功能的文档查
看软件中很容易操作。
2.2打印机图形驱动DLL 、
完成特定的图形渲染,是GDI的一个补充。由打
EMF是Windows NT以后的操作系统支持的一种 印机生产商提供,其实现根据各种打印机的特性而不
矢量图形文件,由于其数据量小的特点,应用也很广
同。
泛。
2.3 Winspoo1.dnr——Win32 spooler客户端,提供
EMF虚拟打印机即是一款将文档转换为EMF格
API与应用程序交互。
式文件的打印机。
2.打印机驱动架构(GDI、Spooler)
主要功能:查询打印机、打印作业,查询、修改打
印机设置,显示打印机设置属性页(调用打印机驱动1
等等。
Windows打印驱动的架构略图如下:
主要函数有OpenPrinter WritePrinter ClosePrinter
等。
2.4 Spoolsv.exe——sp0oler服务程序。通过RPC
与其客户端交互。
大部分调用通过Router转发到Provider,由
Provider实现。
2.5 Spoolss.dll——Router。
主要功能:通过打印机名称/打印机句柄(来自于
打印作业)、打印机设置(来自于注册表),找到正确的
provider,转发打印作业。
应用程序调用spooler客户端的OpenPrinter,通
过spooler服务程序,调用被传到Router,然后Router
调用所有Provider的OpenPrinter,直到找到一个名称
符合的打印机,返回句柄以完成后续打印工作。
Windows打印机驱动程序是一个C/S架构,在更
小的范围内,Spooler组件也是一个C/S结构。Spooler
组件
・
(Spooler组件的以上三个部分不可定制。)
2.6 Print Provider
由Winspoo1.srv、Spoolsv.exe、Spoolss.dll、Print
Provider由打印机生产商提供,包含以下几个部
154・ 福建电脑j 20l3年第6期
J
IA
鞲
t
typedef struct tagEMR
分,各部分可以定制。
2.6.1 localsp1.dll——本地打印机上的作业管理、
调度。
{
DWORDiType;//EMR类型,宏定义为EMR_XXX
DWORDnSize;//EMR大小,单位为字节
l EMR;
在此创建Spool文件。Spool文件有Raw、Text、
EMF格式。通常为EMF格式,数据量小,可以快速完
2.6.2节中介绍了spool文件,通常这种文件是NT
成缓存(使控制返回到应用程序),也便于网络打印的
EMF格式文件。NT EMF格式一般有几个固定的数据
传输。
段,每个数据段都是EMR结构。
实际上Spool文件的内容是由GDI完成的,可能
NT EMF格式文件会按顺序出现以下几个数据段
有打印机图形驱动的配合。
2.6.2 Drocesso广__把打印作业的spool文件转换
为可被打印机接受的Raw格式。
实现打印作业暂停、恢复、取消。
Raw格式spool文件通过WritePrinter直接发给
打印机;Text格式调用StartDoc,把GDI命令发给打印
机驱动;EMF格式通过GdiEndPageEMF调用GDI的
EMFPlayBack机制把各种绘图命令传给打印机驱动,
打印成Raw格式,再通过WritePrinter发给打印机。
EMF格式Spool文件成对出现,后缀为.shd的文
件包含打印作业的设置信息,如打印机名称、文档名
称、端口名,以及DEVMODE拷贝;后缀为.sp1的文件
被称为NT EMF文件,包含一个文件头,一些内嵌字
体(可以没有),以及对应文档各页面的标准EMF页
面。
Spool文件经过processor的处理后传回给GDI处
理,生产最终的打印机可处理的文件。
2.6_3 monito广一监视器,可以修改数据内容及流
向。
包括Language monitor和Port monitor两种。前者
是Spooler和打印机之间的全双工通讯通道,可以获
取打印机信息(调用DeviceIoContro1),反馈给Spooler、
驱动、应用程序,可以修改Raw数据。后者是Spooler
与核心态端口驱动的通讯通道,管理与设置服务器打
印端口,可以实现打印端口重定向。具体实现时两者
可以合并为一个。
3.EMF和Spool文件
EMF(Enhanced MetaFile)是WMF(Windows—format
MetaFile)的升级,实现了真正意义上的设备无关性,且
可以应用于32位操作系统。
之所以被称为“元文件(metafile1 99 9是因为它是由
一
系列“元文件记录”构成的。“元文件记录”是一种变
长的结构。大部分这种结构对应各种GDI指令。该结
构通常都是以EMR结构作为第一个成员。EMR结构
的定义为:
(只列出EMR类型):
11 iType=0x100OO—NT EMF文件标志
2)[iType=0,2,3—0xFFFF]——可选的说明性数据
段,其值若为2,表示该段为嵌入字体
31 iType=OxOC——标准EMF文档起始标志,i—
Size该EMF文档的大小
41标准EMF文档结构(可以从MSDN上找到其
详细描述)
51 iType=o】【80000O 标准EMF文档结束标志
6).…・・(若有多页内容,重复3、4、5段内容)
通常,processor对此类spool文件的处理只是完
成比如缩放、合页(N—up)、小册子(booklet)打印样式等
等的逻辑处理,然后通过GdiEndPageEMF函数调用
GDI的EMFPlayBack机制把各种绘图命令传给打印
机驱动,打印成Raw格式,再通过WritePrinter函数发
送给打印机。
4.虚拟打印机可采取的设计方案
从第2节介绍的内容可以看出,要设计虚拟打印
机可以从两处着手:
其一,自定义打印机图形驱动库,将打印内容处
理成需要的文档格式。
其二,自定义Spooler组件,在processor中截取
spool文件内容,转换成需要的文档格式,或者在moni—
tor中修改数据内容,转换成需要的文档格式。
5.定制processor实现EMF虚拟打印机
从前面的介绍中可以知道,spool文件的内容基本
都是NT EMF格式,这种格式是EMF格式的一个再
包装。因此从spool文件中截取EMF内容,另存为
EMF文件是简单、快速实现EMF虚拟打印机的一种
方式。即我们需要定制processor。
5.1 Processor的函数
定制一个processor,必须实现并导出几个函数
(详细说明可以查看DDK帮助文件):
HANDLE OpenPrintProcessor(
LPWSTR pPrinterName,
2叭3年第6期l福建电脑 ・155・
囊U ;; A 00 pU丁 疆
PPRINTPROCESSOROPENDATA pPrintProcessorOpenData Control\Print\Printers: DetaultSp0olDirectory;
);
个性化假脱机目录在注册表中的位置:
HKEY
LOCALMACHINE\SYSTEM\CurrentControlSet\Con—
此函数为开始一个打印作业做准备,必须基于打
指向一个内部数据结构,该结构包含打印机名称和
DEVMODE结构的指针。
BOOL ClosePrintProcessor(
HANDLE hPrintProcessor
印作业的数据类型执行…一些初始化操作。返回的句柄
trol\Print\Printers\打印机名:SpoolDirectory。
在spool目录下可能存在多个spool文件,正存处
理的文档的名称会通过参数传递到Processor里,sDool
文件中也有记录其文档名称,通过比较_者的值我们
可以找到正确的spool文件。
5.2.2提取EMF内容并保存。
);
此函数结束打印作业,释放0penPrintPmcessor所
申请的所有资源。
BOOI ControlPrintProcessor(
HANDI E hPrintProcessor,
DWORDCommand
);
此函数控制打印作业的暂停、取消、恢复等动作。
DWORD GetPrintProcessorCapabilities(
LPTSTRpValueName,
DWORD dwAttributes,
LPBYTEpData,
DWORD nSize,
LPDWORD pcbNeeded
);
此函数获取输入的数据类型的相关能力,以便后
续执行相关处理。(有时这个函数可以不导出。)
BOOL PrintDocumentOnPrintProcessor(
HANDLE hPrintProcessor,
LPWSTR pDocumentName
);
此函数执行spool文件内容的处理,是我们需要
的最重要的一个函数。
5.2实现EMF打印机
为实现EMF打印机,我们要在PrintDocumentOn—
PrintProcessor函数中执行几个步骤:
5.2.1获取正确的spool文件。
spool文件处于spool目录下。所有打印机都有一
个共同的默认spool目录,默认为系统目录下的
sDo0l\PRINTERS\,可以通过修改“打印服务器属性”一>
“高级”一>‘‘后台打印文件夹”更改该目录。每台打印机
也可以通过修改注册表来个性化自己的spool目录。
通过查询注册表值可以获取正确的spool目录。
默认spool目录在注册表中的位置:
HKEY LOCAL MACHINEkSYSTEM\CurrentControlSet\
・
156・ 福建电脑l 2ol3年第6期
依据NT EMF文件的结构,解析出EMF内容,按
指定的命名规则或者获取用户输入的文件名称把它
保存下来。
若要让用户自定义如EMF文件保存目录、命名
规则等,可以另写一个uI动态链接库,或者增加一 个
插件式UI(可以参考DDK例子)。
6.其它相关问题
6.1 EMF打印机的安装。
由于processor在spooler组件中的位置以及其功
能特性,只要把这个processor安装到操作系统上,把
它挂在任何现有的打印机上都可以使之失去原来的
打印功能而变为EMF打印机。
要制作独立的EMF打印机,可重新写一个inf文
件。驱动文件使用unidrv.dll,设置文件使用unidrvui.
dll,加上processor段,即可。
6.2使用的特别事项。
由于此打印机是在processor中提取spool文件的
内容,所以要获取全部打印文档的内容,必须等整个
打印文档spool完成后才能启动processor。因此,打印
机的设置必须为:“使用后台打印,以便程序更快的结
束打印”并且“在后台处理完最后一页时开始打印”。
使用inf来安装打印机时,可能要手动设置此项。也可
以通过制作打印机安装程序自动设置此项。
7.结束语
本文通过分析Windows打印机驱动的架构以及
打印缓冲文件.spl的格式,以定制spooler组件的pro—
cessor
的方式,实现了简单、快速的EMF虚拟打印机。
参考文献:
1]Microsoft Corporation.MSDN Library for Visual Studio 2005
l 2 j Microsoft Corporation.DDK Documentation.
版权声明:本文标题:EMF虚拟打印机的实现 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/shuma/1718618680a702417.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论