Imprimir mediante programación
OLE proporcionó los medios para identificar documentos persistentes (GetClassFile
) de manera única y cargarlos en su código asociado (CoCreateInstance
, QueryInterface(IID_IPersistFile)
, QueryInterface(IID_IPersistStorage)
, IPersistFile::Load
y IPersistStorage::Load
). Para habilitar aún más la impresión de documentos, la contención de documentos activa (con un diseño OLE existente no incluido originalmente con OLE 2.0) introduce una interfaz de impresión estándar base, IPrint
, disponible con carácter general a través de cualquier objeto que pueda cargar el estado persistente del tipo de documento. Cada vista de un documento activo puede admitir opcionalmente la interfaz IPrint
para proporcionar estas funcionalidades.
La IPrint
interfaz se define de la siguiente manera:
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);
};
Los clientes y contenedores simplemente usan IPrint::Print
para indicar al documento que se imprima una vez que se carga ese documento, especificando marcas de control de impresión, el dispositivo de destino, las páginas que se van a imprimir y opciones adicionales. El cliente también puede controlar la continuación de la impresión a través de la interfaz IContinueCallback
(consulte a continuación).
Además, IPrint::SetInitialPageNum
admite la capacidad numerar páginas sin problemas para imprimir una serie de documentos como si fueran un solo documento. Esta es una clara ventaja para los contenedores de documentos activos como Office Binder. IPrint::GetPageInfo
simplifica la visualización de la información de paginación al permitir que el autor de llamada recupere el número de la página inicial que anteriormente se pasó a SetInitialPageNum
(o el número de página inicial predeterminado interno del documento) y el número de páginas del documento.
Los objetos que admiten IPrint
se marcan en el Registro con la clave "Printable" almacenada en el CLSID del objeto:
HKEY_CLASSES_ROOT\CLSID\{...}\Printable
IPrint
se suele implementar en el mismo objeto que admite IPersistFile
o IPersistStorage
. Los autores de llamada notan la capacidad de imprimir mediante programación el estado persistente de alguna clase si se busca la clave "Printable" en el Registro. Actualmente, "Printable" indica la compatibilidad al menos con IPrint
; otras interfaces se pueden definir en el futuro, las que después estarían disponibles a través de QueryInterface
, donde IPrint
representa simplemente el nivel base de compatibilidad.
Durante un procedimiento de impresión, es posible que quiera que el cliente o el contenedor que inició la impresión controlen si esta debe continuar o no. Por ejemplo, el contenedor puede admitir un comando "Stop Print" que debería finalizar el trabajo de impresión lo antes posible. Para admitir esta funcionalidad, el cliente de un objeto imprimible puede implementar un objeto receptor de notificaciones pequeño con la interfaz IContinueCallback
:
interface IContinueCallback : IUnknown
{
HRESULT FContinue(void);
HRESULT FContinuePrinting(
[in] LONG cPagesPrinted,
[in] LONG nCurrentPage,
[in] LPOLESTR pszPrintStatus);
};
Esta interfaz está diseñada para ser útil como una función de devolución de llamada de continuación genérica que toma el lugar de los distintos procedimientos de continuación en la API Win32 (como AbortProc
para la impresión y EnumMetafileProc
para la enumeración del metarchivo). Por lo tanto, este diseño de interfaz resulta útil en una amplia variedad de procesos lentos.
En los casos más genéricos, cualquier proceso largo llama periódicamente a la función IContinueCallback::FContinue
. El objeto receptor devuelve S_OK para continuar la operación y S_FALSE detener el procedimiento lo antes posible.
Sin embargo, FContinue
no se usa en el contexto de IPrint::Print
; en su lugar, la impresión usa IContinueCallback::FContinuePrint
. Cualquier objeto de impresión debe llamar periódicamente a FContinuePrinting
y pasar el número de páginas que han estado imprimiendo, el número de la página que se está imprimiendo y una cadena adicional que describa el estado de impresión que el cliente puede elegir mostrar al usuario (por ejemplo, "Página 5 de 19").