Documenti con più pagine
Questo articolo descrive il protocollo di stampa di Windows e spiega come stampare documenti contenenti più pagine. L'articolo illustra gli argomenti seguenti:
Protocollo di stampa
Per stampare un documento a più pagine, il framework e la visualizzazione interagiscono nel modo seguente. Prima di tutto, il framework visualizza la finestra di dialogo Stampa , crea un contesto di dispositivo per la stampante e chiama la funzione membro StartDoc dell'oggetto CDC . Quindi, per ogni pagina del documento, il framework chiama la funzione membro StartPage dell'oggetto CDC
, indica all'oggetto visualizzazione di stampare la pagina e chiama la funzione membro EndPage . Se la modalità stampante deve essere modificata prima di avviare una determinata pagina, la visualizzazione chiama ResetDC, che aggiorna la struttura DEVMODE contenente le informazioni sulla nuova modalità stampante. Quando l'intero documento è stato stampato, il framework chiama la funzione membro EndDoc .
Override delle funzioni della classe di visualizzazione
La classe CView definisce diverse funzioni membro chiamate dal framework durante la stampa. Eseguendo l'override di queste funzioni nella classe di visualizzazione, è possibile fornire le connessioni tra la logica di stampa del framework e la logica di stampa della classe di visualizzazione. Nella tabella seguente sono elencate queste funzioni membro.
Funzioni sostituibili di CView per la stampa
Nome | Motivo dell'override |
---|---|
OnPreparePrinting | Per inserire valori nella finestra di dialogo Stampa, in particolare la lunghezza del documento |
OnBeginPrinting | Per allocare tipi di carattere o altre risorse GDI |
Onpreparedc | Per modificare gli attributi del contesto di dispositivo per una determinata pagina o per eseguire l'impaginazione in fase di stampa |
Onprint | Per stampare una determinata pagina |
OnEndPrinting | Per deallocare le risorse GDI |
È possibile eseguire anche l'elaborazione correlata alla stampa in altre funzioni, ma queste funzioni sono quelle che determinano il processo di stampa.
La figura seguente illustra i passaggi coinvolti nel processo di stampa e mostra dove vengono chiamate le funzioni membro di stampa di ognuno.CView
Il resto di questo articolo illustra la maggior parte di questi passaggi in modo più dettagliato. Altre parti del processo di stampa sono descritte nell'articolo Allocazione di risorse GDI.
Ciclo di stampa
Impaginazione
Il framework archivia gran parte delle informazioni su un processo di stampa in una struttura CPrintInfo . Diversi valori relativi CPrintInfo
alla paginazione. Questi valori sono accessibili come illustrato nella tabella seguente.
Informazioni sul numero di pagina archiviate in CPrintInfo
Variabile membro o nomi di funzione |
Numero di pagina a cui si fa riferimento |
---|---|
GetMinPage /SetMinPage |
Prima pagina del documento |
GetMaxPage /SetMaxPage |
Ultima pagina del documento |
GetFromPage |
Prima pagina da stampare |
GetToPage |
Ultima pagina da stampare |
m_nCurPage |
Pagina attualmente stampata |
I numeri di pagina iniziano da 1, ovvero la prima pagina è numerata 1, non 0. Per altre informazioni su questi e altri membri di CPrintInfo, vedere le informazioni di riferimento su MFC.
All'inizio del processo di stampa, il framework chiama la funzione membro OnPreparePrinting della visualizzazione, passando un puntatore a una CPrintInfo
struttura. La Creazione guidata applicazione fornisce un'implementazione di OnPreparePrinting
che chiama DoPreparePrinting, un'altra funzione membro di CView
. DoPreparePrinting
è la funzione che visualizza la finestra di dialogo Stampa e crea un contesto di dispositivo della stampante.
A questo punto l'applicazione non conosce il numero di pagine nel documento. Usa i valori predefiniti 1 e 0xFFFF per i numeri della prima e dell'ultima pagina del documento. Se si conosce il numero di pagine del documento, eseguire l'override OnPreparePrinting
e chiamare [SetMaxPage]--brokenlink--(reference/cprintinfo-class.md#setmaxpage) per la CPrintInfo
struttura prima di inviarla a DoPreparePrinting
. In questo modo è possibile specificare la lunghezza del documento.
DoPreparePrinting
visualizza quindi la finestra di dialogo Stampa. Quando viene restituito, la CPrintInfo
struttura contiene i valori specificati dall'utente. Se l'utente desidera stampare solo un intervallo selezionato di pagine, può specificare i numeri di pagina iniziale e finale nella finestra di dialogo Stampa. Il framework recupera questi valori usando le GetFromPage
funzioni e GetToPage
di CPrintInfo. Se l'utente non specifica un intervallo di pagine, il framework chiama GetMinPage
e GetMaxPage
usa i valori restituiti per stampare l'intero documento.
Per ogni pagina di un documento da stampare, il framework chiama due funzioni membro nella classe di visualizzazione, OnPrepareDC e OnPrint e passa ogni funzione due parametri: un puntatore a un oggetto CDC e un puntatore a una CPrintInfo
struttura. Ogni volta che il framework chiama OnPrepareDC
e OnPrint
, passa un valore diverso nel membro m_nCurPage della CPrintInfo
struttura. In questo modo il framework indica alla visualizzazione quale pagina deve essere stampata.
La funzione membro OnPrepareDC viene usata anche per la visualizzazione dello schermo. Apporta modifiche al contesto del dispositivo prima che il disegno venga eseguito. OnPrepareDC
svolge un ruolo simile nella stampa, ma esistono alcune differenze: per prima cosa, l'oggetto CDC
rappresenta un contesto di dispositivo della stampante anziché un contesto di dispositivo dello schermo e il secondo, un CPrintInfo
oggetto viene passato come secondo parametro. Questo parametro è NULL quando OnPrepareDC
viene chiamato per la visualizzazione dello schermo. Eseguire l'override OnPrepareDC
per apportare modifiche al contesto di dispositivo in base alla pagina da stampare. Ad esempio, è possibile spostare l'origine del riquadro di visualizzazione e l'area di ritaglio per assicurarsi che venga stampata la parte appropriata del documento.
La funzione membro OnPrint esegue la stampa effettiva della pagina. L'articolo Come viene eseguita la stampa predefinita mostra come il framework chiama OnDraw con un contesto di dispositivo della stampante per eseguire la stampa. Più precisamente, il framework chiama OnPrint
con una CPrintInfo
struttura e un contesto di dispositivo e OnPrint
passa il contesto del dispositivo a OnDraw
. Eseguire l'override OnPrint
per eseguire qualsiasi rendering che deve essere eseguito solo durante la stampa e non per la visualizzazione dello schermo. Ad esempio, per stampare intestazioni o piè di pagina (vedere l'articolo Intestazioni e piè di pagina per altre informazioni). Chiamare OnDraw
quindi dall'override di OnPrint
per eseguire il rendering comune sia alla visualizzazione dello schermo che alla stampa.
Il fatto che esegue il rendering sia per la visualizzazione dello schermo che OnDraw
per la stampa significa che l'applicazione è WYSIWYG: "Quello che vedi è quello che ottieni". Si supponga tuttavia di non scrivere un'applicazione WYSIWYG. Si consideri, ad esempio, un editor di testo che usa un carattere in grassetto per la stampa, ma visualizza i codici di controllo per indicare il testo in grassetto sullo schermo. In una situazione di questo tipo, si usa OnDraw
rigorosamente per la visualizzazione dello schermo. Quando si esegue l'override OnPrint
di , sostituire la chiamata a OnDraw
con una chiamata a una funzione di disegno separata. Tale funzione disegna il documento nel modo in cui viene visualizzato su carta, usando gli attributi che non vengono visualizzati sullo schermo.
Pagine stampanti e pagine documento
Quando si fa riferimento ai numeri di pagina, a volte è necessario distinguere tra il concetto della stampante di una pagina e il concetto di pagina di un documento. Dal punto di vista della stampante, una pagina è un foglio di carta. Tuttavia, un foglio di carta non è necessariamente uguale a una pagina del documento. Ad esempio, se stai stampando una newsletter, in cui i fogli devono essere piegati, un foglio di carta potrebbe contenere sia la prima che l'ultima pagina del documento, affiancata. Analogamente, se si stampa un foglio di calcolo, il documento non è costituito affatto da pagine. Al contrario, un foglio di carta potrebbe contenere righe da 1 a 20, colonne da 6 a 10.
Tutti i numeri di pagina nella struttura CPrintInfo fanno riferimento alle pagine della stampante. Il framework chiama OnPrepareDC
e OnPrint
una volta per ogni foglio di carta che passerà attraverso la stampante. Quando si esegue l'override della funzione OnPreparePrinting per specificare la lunghezza del documento, è necessario utilizzare le pagine della stampante. Se esiste una corrispondenza uno-a-uno (ovvero una pagina della stampante è uguale a una pagina del documento), è facile. Se, d'altra parte, le pagine del documento e le pagine della stampante non corrispondono direttamente, è necessario traslare tra di esse. Si consideri ad esempio la stampa di un foglio di calcolo. Quando si esegue l'override OnPreparePrinting
di , è necessario calcolare il numero di fogli di carta necessari per stampare l'intero foglio di calcolo e quindi utilizzare tale valore quando si chiama la SetMaxPage
funzione membro di CPrintInfo
. Analogamente, quando si esegue l'override OnPrepareDC
di , è necessario convertire m_nCurPage nell'intervallo di righe e colonne che verranno visualizzate in quel foglio specifico e quindi modificare di conseguenza l'origine del riquadro di visualizzazione.
Impaginazione in fase di stampa
In alcune situazioni, la classe di visualizzazione potrebbe non sapere in anticipo per quanto tempo il documento è fino a quando non viene effettivamente stampato. Si supponga, ad esempio, che l'applicazione non sia WYSIWYG, quindi la lunghezza di un documento sullo schermo non corrisponde alla lunghezza durante la stampa.
Questo causa un problema quando si esegue l'override di OnPreparePrinting per la classe di visualizzazione: non è possibile passare un valore alla SetMaxPage
funzione della struttura CPrintInfo , perché non si conosce la lunghezza di un documento. Se l'utente non specifica un numero di pagina da interrompere utilizzando la finestra di dialogo Stampa, il framework non sa quando arrestare il ciclo di stampa. L'unico modo per determinare quando arrestare il ciclo di stampa consiste nel stampare il documento e vedere quando termina. La classe di visualizzazione deve verificare la fine del documento durante la stampa e quindi informare il framework quando viene raggiunta la fine.
Il framework si basa sulla funzione OnPrepareDC della classe di visualizzazione per indicare quando arrestarlo. Dopo ogni chiamata a OnPrepareDC
, il framework controlla un membro della CPrintInfo
struttura denominata m_bContinuePrinting. Il valore predefinito è TRUE. Finché rimane così, il framework continua il ciclo di stampa. Se è impostato su FAL edizione Standard, il framework si arresta. Per eseguire l'impaginazione in fase di stampa, eseguire l'override OnPrepareDC
per verificare se è stata raggiunta la fine del documento e impostare m_bContinuePrinting su FAL edizione Standard quando è presente.
L'implementazione predefinita di OnPrepareDC
imposta m_bContinuePrinting su FAL edizione Standard se la pagina corrente è maggiore di 1. Ciò significa che se la lunghezza del documento non è stata specificata, il framework presuppone che il documento sia lungo una pagina. Una conseguenza di questo è che è necessario prestare attenzione se si chiama la versione della classe base di OnPrepareDC
. Non presupporre che m_bContinuePrinting sarà TRUE dopo aver chiamato la versione della classe di base.