以编程方式打印
OLE 提供了唯一标识永久文档 (GetClassFile
) 并将它们加载到其相关代码(CoCreateInstance
、QueryInterface(IID_IPersistFile)
、QueryInterface(IID_IPersistStorage)
、IPersistFile::Load
和 IPersistStorage::Load
)中的方法。 为了进一步启用打印文档,活动文档包容(使用最初未随 OLE 2.0 一起提供的现有 OLE 设计)引入了一个基本标准的打印接口 IPrint
(通常可以通过任何能够加载文档类型的持久状态的对象获取)。 活动文档的每个视图都可选择性地支持 IPrint
接口来提供这些功能。
IPrint
接口定义如下:
interface IPrint : IUnknown
{
HRESULT SetInitialPageNum([in] LONG nFirstPage);
HRESULT GetPageInfo(
[out] LONG *pnFirstPage,
[out] LONG *pcPages);
HRESULT Print(
[in] DWORD grfFlags,
[in,out] DVTARGETDEVICE **pptd,
[in,out] PAGESET ** ppPageSet,
[in,out] STGMEDIUM **ppstgmOptions,
[in] IContinueCallback* pCallback,
[in] LONG nFirstPage,
[out] LONG *pcPagesPrinted,
[out] LONG *pnPageLast);
};
客户端和容器只需使用 IPrint::Print
来指示文档在加载后打印其自身,指定打印控件标志、目标设备、要打印的页面以及其他选项。 客户端还可以通过 IContinueCallback
接口来控制打印的继续(如下所示)。
此外,IPrint::SetInitialPageNum
支持通过对页面进行无缝编号来将一系列文档作为一个文档进行打印的功能,这对于 Office 活页夹之类的活动文档容器来说显然是一大优点。 IPrint::GetPageInfo
通过允许调用方检索之前传递给 SetInitialPageNum
的起始页码(或文档的内部默认起始页码)和文档中的页面数量,来简化分页信息的显示。
支持 IPrint
的对象在注册表中使用存储在该对象的 CLSID 下的“Printable”注册表项标记:
HKEY_CLASSES_ROOT\CLSID\{...}\Printable
通常在支持 IPrint
或 IPersistFile
的相同对象上实现 IPersistStorage
。 调用方通过查看注册表中的“Printable”注册表项,可以了解到以编程方式打印某些类的持久状态的能力。 目前,“Printable”指示至少支持 IPrint
;将来可能定义其他接口,这些接口可通过 QueryInterface
(其中的 IPrint
表示基本支持级别)提供。
在打印过程中,您可能希望启动打印的客户端或容器控制打印是否应继续。 例如,容器可以支持应尽快终止打印作业的“停止打印”命令。 若要支持此功能,可打印对象的客户端可以使用 IContinueCallback
接口实现一个小的通知接收器对象:
interface IContinueCallback : IUnknown
{
HRESULT FContinue(void);
HRESULT FContinuePrinting(
[in] LONG cPagesPrinted,
[in] LONG nCurrentPage,
[in] LPOLESTR pszPrintStatus);
};
此接口可用作一个有用的泛型继续回调函数,该函数将取代 Win32 API 中的各种继续过程(例如用于打印的 AbortProc
和用于图元文件枚举的 EnumMetafileProc
)。 因此,在各种耗时的过程中,此接口设计都非常有用。
在最常规的情况下,任何长时间的进程会定期调用 IContinueCallback::FContinue
函数。 接收器对象返回 S_OK 来表示继续操作,返回 S_FALSE 则表示尽快停止过程。
但是,在 IPrint::Print
的上下文中不使用 FContinue
;相反,打印将使用 IContinueCallback::FContinuePrint
。 所有打印对象都应定期调用 FContinuePrinting
,从而传递已打印的页数、将要打印的页码和一个附加字符串,该字符串描述客户端可能选择要显示给用户的打印状态(例如“第 5 页,共 19 页”)。