17.5 打印文档(1)
现在分析如何打印草图。借助于Application Wizard和框架,在Sketcher程序中已经实现了基本的打印能力。File | Print、File | Print Setup和File | Print Preview菜单项都可以使用。选择File | Print Preview菜单项后将出现一个窗口,在一个页面上显示当前的Sketcher文档,如图17-4所示。

当前文档中的所有内容都按照当前视图比例显示在一页纸上。如果文档的范围超出了这页纸的边界,那么将不打印超出的部分。如果选择Print按钮,则这个页面将发送到打印机。
作为一种免费取得的基本能力,这非常令人难忘,但是它还不足以满足我们的要求。在Sketcher程序中,典型的文档很可能不能完全排在一个页面上,因此要么调整文档的比例,要么使用一种更方便的方法,在需要的多个页面上打印整个文档。可以添加自己的打印处理代码,扩展框架提供的功能,但是在实现这之前,首先需要了解打印在MFC中是如何实现的。
打印过程
打印文档是由当前视图控制的。这个过程肯定会有点麻烦,因为打印本来就是一个麻烦事,我们很可能需要在视图类中实现大量自己的继承函数。图17-5显示了这个过程的逻辑原理和有关的函数。此图也说明了框架如何控制事件的顺序,打印文档如何涉及调用视图类的5个继承成员,可能还需要重写这些成员。该图左边显示的CDC成员函数与打印机设备驱动程序进行通信,框架将自动调用它们。

在打印操作期间,当前视图中每个函数的典型作用由它们旁边的注释说明。调用它们的顺序由箭头上的数字标明。实际上,不必实现所有这些函数,而只需要实现满足特定打印要求的那些函数。通常,我们至少需要实现自己的OnPreparePrinting()、OnPrepareDC()和OnPrint()函数。本章稍后将介绍一个示例,说明如何在Sketcher程序的上下文中实现这些函数。
输出数据到打印机与输出数据到显示器的方式是一样的-- 通过设备上下文。用于输出文本或图形的GDI调用与设备无关,所以它们对打印机的应用和对显示器的应用一样,唯一的区别在于CDC对象应用的物理输出设备。
在图17-5中,CDC函数与打印机的设备驱动程序进行通信。如果要打印的文档需要多个的打印页,那么这个过程将为每个连续的新页面循环调用OnPrepareDC()函数,循环次数由EndPage()函数确定。指向CPrintInfo类型对象的指针将作为参数传递给打印过程中涉及的视图类中的所有函数。这种对象将在管理打印过程的所有函数之间提供链接,所以下面将详细地分析CPrintInfo类。
CPrintInfo类
因为CPrintInfo对象随时存储有关正在执行的打印工作及其状态细节的信息,所以它在打印过程中具有重要的作用。它还提供了访问和操作这些数据的函数。利用这个对象,可以在打印期间把信息从一个视图函数传递到另一个视图函数,而且可以在框架和视图函数之间传递信息。
每当选择File | Print或File | Print Preview菜单项时,即创建CPrintInfo类的对象。由当前视图中与打印过程有关的每个函数使用过以后,将在打印操作结束时自动删除它。