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.

Printing loop process.
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 OnPrintdi , 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 OnPreparePrintingdi , è 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 OnPrepareDCdi , è 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.

Cosa vuoi sapere di più su

Vedi anche

Stampa
Classe CView
Classe CDC