在Windows中打印时,以编程方式设置每张页数(N-Up)选项

时间:2010-08-10 23:34:35

标签: c++ windows mfc printing

打印时,我需要一种以编程方式设置每张页数设置的好方法。

我知道用户可以通过打印机设置对话框选择此选项,如果我愿意,我可以进行这样的对话框显示。但是在我正在研究的程序环境中,我需要通过软件本身选择它,而无需用户深入研究打印机设置。

虽然看起来我可以询问Windows是否打印机使用dmNup结构的DEVMODE成员支持此功能,但似乎没有任何官方方法可以为当前打印设置它工作

显然,一种解决方案是在我的软件中更改打印算法,以便在设备上下文中适当地布局页面,从而在结果输出中获得每张纸的多个页面。但是,我还没有看到任何简单的方法,它不需要在绘制到打印机设备上下文的所有代码中进行重大更改。出于各种原因,我宁愿避免大量的代码更改。

另一种解决方案是在Windows中安装多个打印机副本,同时将它们全部导向同一个打印机端口。打印机的每个副本都设置有不同的默认每页页数。然后,软件可以选择适当的打印机,最终结果就好像它已经以编程方式选择了每张纸的必要页面选项。但是,我遇到了这个方案的各种问题,所以我正在寻找一种不那么支持负担的替代方案。

This article提供了另一种可能的解决方案:在官方DEVMODE结构之后的私有驱动程序数据中操作适当的字节。问题是不能保证任何特定的打印机驱动程序实际使用相同的字节,我需要支持任何可以合理地在办公环境中使用的打印机。看起来我的软件需要一个配置,我可以为不使用默认值的驱动程序指定不同的字节偏移量。根据有多少打印机驱动程序决定使用不同的字节进行此设置,这可能是罕见的情况或常见的问题。

所以这是我的问题:

  • 有没有人使用最后一种操作私有驱动程序数据的技术有任何实际经验?在处理来自不同制造商的各种打印机时,它的表现如何?
  • 还有其他技术我忽略了吗?
  • 如果没有别的,那么有没有简单的方法来获取将文本,线条,图形等绘制到打印机设备上下文的代码,并以某种方式强制它进行缩放,移动和可能的旋转(每张2页)输出到设备上下文中的必要位置而不写入所有代码(并且不会丢失1像素宽的行)?

注意:对于它的价值,我正在使用的程序是使用C ++和MFC。但是,所有这些都应该同样适用于任何处理设备上下文和Windows API本身的程序。

3 个答案:

答案 0 :(得分:0)

好吧,自从我使用GDI和MFC以来已经有一段时间了,但过去我曾经使用过很多打印机。我倾向于说,因为GDI应该抽象你的程序,使其了解绘图上下文,但是你对于特定的API调用运气不好。然而,可能有一些方法可以做到这一点,而不是抨击结构的私有区域中的位。

我要做的第一件事是查看CDC :: Escape方法(或Escape Win32 API函数)。在最好的情况下,有一个标准的转义序列可将打印机设置为n-up模式。在最坏的情况下,您必须找到打印机的转义序列并将其原始发送。 (曾几何时,这是使打印机使用其奇特功能的唯一方法。)大多数打印机开始实施语言标准(PCL?HPGL?我忘了哪一个)。如果它们仍然实现标准语言,许多打印机可能会理解转义序列。

如果失败了,你可能不得不在上下文中手动实现你自己的n-up绘图,但是使用类似SetMapMode的东西来设置Twips中的单位(或任何有效的)并预先绘制它。

否则,尝试查看GDI对缩放的影响,看看是否有效。

答案 1 :(得分:0)

在Win XP及更高版本中实现XPS,如果您将源应用程序作为WPF / .NET应用程序,则可以使用PrintTicket作为设置NUp的机制。

http://msdn.microsoft.com/en-us/library/system.printing.printticket.pagespersheet.aspx 指定N-Up的属性。

理想情况下,如果绘图应用程序正在设置此项,然后调用打印驱动程序,则Windows 设置正确的NUp设置并将其传递给底层驱动程序(GDI或XPS)。但也许这只适用于那些已实现Print Ticket转换的驱动程序。

答案 2 :(得分:0)

我遇到了关于How to Print Multiple Pages on One Sheet的教程。

基本上,您需要使用Document的PageSize来缩放您的绘图,其中包含您希望每张纸显示的页数。

如果你想在每张纸上显示2个页面,你只需要绘制一半文档,并增加一个索引,这样你下一个循环的下一次迭代就会打印在下半部分。

我可以在我的问题中查看代码:PrintPage PrintPageEventHandler Is Printing Too Many Copies。事实证明我错误地设置了文档中的副本数量。