测试:
经前天的测试,最终还是没有明显的定夺到底是驱动的问题,还是打印机的问题。但是按照可能性来排查,最明显的一点就是其他测试环境不变的情况下增加一张图片,就可以打印出表格线,我始终觉得这里是突破点,但是一时又没了思路。
于是想看一下word中存在表格的时候会不会有同样的问题,遗憾的是没有,为此我暂定为是Office的Bug,上google搜索关键字,office excel can not print gridlines,幸运的似乎看到了相同的问题:http://209.116.186.218/#newwindow=1&q=office+excel+can+not+print+gridlines
前面有部分看的迷迷糊糊,中间有这么一句:In the Excel 2010 document, Print Preview and Print>Printer Properties>Advanced>Document Options>Print Optimizations: change setting to Disable. Save the file.
根据上面的描述我去查看了打印机属性高级设置中的打印优化,默认是启用的,我改成禁用,然后打印测试还是没有表格线。
虽然还是没有表格线,但是这里给了我一个启示:打印机的设置项里存在是否优化的选项,这个选项肯定是驱动里的一些开关,而我前面发现了有图片的时候打印就没有问题,所以很有可能是有图片的时候和没有图片的时候执行渲染的时候走了不同的路线导致的不同结果。那么这里很有可能就是因为这个选项导致的啊,是不是其他选项也需要改改。
于是我又尝试去更改其他选项,主要是下面那个“图形模式”的选项,但是也没有效果啊。
这时候我突然想到,我在看到这个帖子之前,看了微软对表格线打印的描述,里面有介绍如果打印不出表格线,需要关掉页面设置里的“按草稿方式”。
我之前做测试的时候不小心把这里勾上了,没有取消掉,于是我取消掉再去打印测试,惊奇的打印出了表格线。赶紧还原之前所更改的无关设置,发现确实就是打印优化这一项引起的没有表格线啊。
解决:
好吧,到了这里基本上算是解决了,稍微总结下整个过程中注意的地方:
1、测试的时候尽量不要一次性有多个变动因子,并且测试没有效果之后要记得还原回默认的设置啊(上面我要是没有想起“按草稿方式”这里,我不知道还要花多长时间去找这个问题了)。
2、不要小看打印驱动的GPD文件啊,这里面那么多设置项,有很多默认的选项参数是很重要的。
3、对于虚拟打印机来说,完全没必要存在这么个“打印优化”选项,去GPD里面去掉这个选项,同时要确保默认的是禁用。
补充:
之前没注意自己在做测试的时候把我的虚拟打印机使用的GPD文件改成了使用别人的,而实际我的打印机属性高级设置中没有“打印优化”这个选项。。 好吧,本来认为只要轻易的找到“打印优化”这个选项,然后将默认值改成“已禁用”就妥妥的解决了。
然后经历了整个下午的时间去找这个选项,始终没有找到。最后想了个蛮办法,就是从unires.dll中去找出对应的String=”打印优化“的项,然后逆向查找对应的ID,最后转到GPD文件中找到底是哪一项,搜了个resxplorer来找unires.dll中的”打印优化“,发现好像好多string都是???或者乱码。看来是中文支持不好,于是又去下了个英文的unires.dll,也没找到print optimize。
至此基本可以断定这个内容不是通过GPD直接指定的,可能是unidrv通过某些选项,间接的加上了这么个选项。那问题就转变成了到底是哪些内容间接的加上了这个选项呢?
好吧,从MSDN上GPD相关介绍,我的GPD文件和STDNAME.GPD中分别搜索关键字optimize,都没有搜索到。又花了好长时间啊,没办法了,蛮办法,用别人的GPD和自己的GPD进行对比,逐个排查出到底是哪个选项引起的。
经过反复的排查,以及查看MSDN说明,最终发现是我的GPD文件中,“*FontFormat: H_BYTE”这个设置,导致的不仅没有打印优化这个选项,而且无法打印出表格,查看MSDN说明:
根本没有H_BYTE这么个常量值,好吧,看来是写错了导致的异常。于是尝试使用列举的常量去测试,发现确实能出现“打印优化”这么个选项了。但是问题是每次重启后,这个打印优化选项默认又变成启用了,也就是说*FontFormat这个选项只是间接显示出了“打印优化”这么个选项,但是这个选项的默认值并不是它决定的,这下又麻烦了,到了这里又断了思路。
实在是想不出什么办法直接从GPD文件里面去找出什么东西了,折腾来折腾去,只能去看驱动插件的代码了。找了WDK的C:\WinDDK\7600.16385.1\src\print\oemdll\uniuirep示例(之前一直看的就是这个示例的GPD),去追踪它显示出来的print optimization是从哪里来的,默认值”失败“又是从哪里获取的,结论是:原来Unidrv本身还存在一些设置选项,比如这个print optimization就是从选项”%TextAsGraphics“得来的,本地MSDN无法找到这个,就去在线MSDN查看:http://msdn.microsoft.com/en-us/library/windows/hardware/ff563550(v=vs.85).aspx
这里解释的意思其实很明显根本与我那出现的现象无关,但是目前也没有其他的线索,就继续看驱动插件代码吧。
IPrintCoreHelper::GetOption和SetOption分别用户从驱动获取到这个选项原来的值和更改设置后的值。调试发现获取到的默认值就是Fase,也就是关闭的。那为什么我的虚拟打印机中没有这个驱动插件的时候,默认确实开启的呢?看来这个默认值还是跟GPD中的相关设置有关啊。
我想到了在在线MSDN中搜索”print optimization“关键字,在http://msdn.microsoft.com/en-us/library/windows/hardware/ff561836(v=vs.85).aspx下有这么段内容:
意思是如果关闭了打印优化,那么”pseudovector graphics feature“功能就是禁用的,下面描述了这个功能会拦截驱动调用DrvLineTo等函数,很明显这是画线的,难道在我的GPD里面开启了这个功能?所以在我的虚拟打印机里默认打印优化是开启的,而WDK示例中默认是关闭的,这也解释了为什么关闭了打印优化就能打印出表格线。那如何禁用这个呢?上面也提到了CmdRectBlackFill能开启这个功能,那我去掉这个就应该可以了。
赶紧去找我的GPD文件中CmdRectBlackFill相关指令,全部清除掉,进行测试,果然好了,虽然打印优化默认还是开启的,但是也能打印出表格线了。总算最终解决了问题。
再次总结:
1、本地MSDN帮助文档没有在线的那种关键字查找功能(也可能有,但是我不会用),如果我早早的去在线MSDN上搜索”print optimization“关键字,应该会少走很少弯路。
2、GPD选项控制打印的东西特别的多,一方面本身我就没有全部看过,另一方面我老是使用本地MSDN,没有树形菜单查看结构,脑子里就没有清晰的思路去理解GPD,以后还是多用在线MSDN的好。
3、问题算告一段落了,但是经此发现我的虚拟打印机高级属性中有很多重复的选项,趁着对GPD熟悉一些,尽快去掉。