TN030: personalizzazione della stampa e dell'anteprima di stampa
Nota
La seguente nota tecnica non è stata aggiornata da quando è stata inclusa per la prima volta nella documentazione online. Di conseguenza, alcune procedure e argomenti potrebbero essere non aggiornati o errati. Per le informazioni più recenti, è consigliabile cercare l'argomento di interesse nell'indice della documentazione online.
Questa nota descrive il processo di personalizzazione della stampa e dell'anteprima di stampa e descrive gli scopi delle routine di callback usate in CView
e le routine di callback e le funzioni membro di CPreviewView
.
Problema
MFC offre una soluzione completa per la maggior parte delle esigenze di stampa e anteprima di stampa. Nella maggior parte dei casi, è necessario un piccolo codice aggiuntivo per avere una visualizzazione in grado di stampare e visualizzare in anteprima. Esistono tuttavia modi per ottimizzare la stampa che richiedono un impegno significativo da parte dello sviluppatore e alcune applicazioni devono aggiungere elementi dell'interfaccia utente specifici alla modalità di anteprima di stampa.
Stampa efficiente
Quando un'applicazione MFC viene stampata usando i metodi standard, Windows indirizza tutte le chiamate di output GDI (Graphics Device Interface) a un metafile in memoria. Quando EndPage
viene chiamato, Windows riproduce il metafile una volta per ogni banda fisica richiesta dalla stampante per stampare una pagina. Durante questo rendering, GDI esegue spesso una query sulla routine di interruzione per determinare se deve continuare. In genere, la procedura di interruzione consente l'elaborazione dei messaggi in modo che l'utente possa interrompere il processo di stampa usando una finestra di dialogo di stampa.
Sfortunatamente, questo può rallentare il processo di stampa. Se la stampa nell'applicazione deve essere più veloce di quanto possa essere ottenuta usando la tecnica standard, è necessario implementare il raggruppamento manuale.
Stampa a banda
Per eseguire manualmente la banda, è necessario implementare nuovamente il ciclo di stampa in modo che OnPrint
venga chiamato più volte per pagina (una volta per banda). Il ciclo di stampa viene implementato nella OnFilePrint
funzione in viewprnt.cpp. CView
Nella classe derivata da viene eseguito l'overload di questa funzione in modo che la voce della mappa messaggi per la gestione del comando di stampa chiami la funzione di stampa. Copiare la OnFilePrint
routine e modificare il ciclo di stampa per implementare il raggruppamento. Probabilmente si desidera anche passare il rettangolo di banda alle funzioni di stampa in modo da poter ottimizzare il disegno in base alla sezione della pagina da stampare.
In secondo luogo, è necessario chiamare QueryAbort
frequentemente durante il disegno della banda. In caso contrario, la routine di interruzione non verrà chiamata e l'utente non sarà in grado di annullare il processo di stampa.
Anteprima di stampa: carta elettronica con interfaccia utente
Anteprima di stampa, in sostanza, tenta di trasformare il display in un emulazione di una stampante. Per impostazione predefinita, l'area client della finestra principale viene usata per visualizzare una o due pagine completamente all'interno della finestra. L'utente è in grado di ingrandire un'area della pagina per visualizzarla in modo più dettagliato. Con supporto aggiuntivo, l'utente può anche essere autorizzato a modificare il documento in modalità di anteprima.
Personalizzazione dell'anteprima di stampa
Questa nota riguarda solo un aspetto della modifica dell'anteprima di stampa: aggiunta dell'interfaccia utente alla modalità di anteprima. Altre modifiche sono possibili, ma tali modifiche non rientrano nell'ambito di questa discussione.
Per aggiungere l'interfaccia utente alla modalità di anteprima
Derivare una classe di visualizzazione da
CPreviewView
.Aggiungere gestori di comandi per gli aspetti dell'interfaccia utente desiderati.
Se si aggiungono aspetti visivi alla visualizzazione, eseguire l'override
OnDraw
ed eseguire il disegno dopo aver chiamatoCPreviewView::OnDraw
.
OnFilePrintPreview
Questo è il gestore dei comandi per l'anteprima di stampa. L'implementazione predefinita è:
void CView::OnFilePrintPreview()
{
// In derived classes, implement special window handling here
// Be sure to Unhook Frame Window close if hooked.
// must not create this on the frame. Must outlive this function
CPrintPreviewState* pState = new CPrintPreviewState;
if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this,
RUNTIME_CLASS(CPreviewView), pState))
{
// In derived classes, reverse special window handling
// here for Preview failure case
TRACE0("Error: DoPrintPreview failed");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
delete pState; // preview failed to initialize, delete State now
}
}
DoPrintPreview
nasconderà il riquadro principale dell'applicazione. Le barre di controllo, ad esempio la barra di stato, possono essere mantenute specificandole nel membro pState-dwStates> (si tratta di una maschera di bit e i bit per le singole barre di controllo sono definiti da AFX_CONTROLBAR_MASK( AFX_IDW_MYBAR)). La finestra pState-nIDMainPane> è la finestra che verrà nascosta e visualizzata di nuovo automaticamente. DoPrintPreview
creerà quindi una barra dei pulsanti per l'interfaccia utente di anteprima standard. Se è necessaria una gestione speciale delle finestre, ad esempio per nascondere o mostrare altre finestre, è necessario eseguire questa operazione prima DoPrintPreview
di chiamare .
Per impostazione predefinita, al termine dell'anteprima di stampa, le barre di controllo vengono restituite agli stati originali e al riquadro principale per essere visibili. Se è necessaria una gestione speciale, deve essere eseguita in un override di EndPrintPreview
. In caso DoPrintPreview
di errore, fornire anche una gestione speciale.
DoPrintPreview viene chiamato con:
ID risorsa del modello di finestra di dialogo per la barra degli strumenti di anteprima.
Puntatore alla visualizzazione per eseguire la stampa per l'anteprima di stampa.
Classe di runtime della classe Preview View. Verrà creato in modo dinamico in DoPrintPreview.
Puntatore CPrintPreviewState. Si noti che la struttura CPrintPreviewState (o la struttura derivata se l'applicazione richiede più stato mantenuto) non deve essere creata nel frame. DoPrintPreview è modeless e questa struttura deve sopravvivere fino a quando non viene chiamato EndPrintPreview.
Nota
Se è necessaria una visualizzazione o una classe di visualizzazione separata per il supporto della stampa, un puntatore a tale oggetto deve essere passato come secondo parametro.
EndPrintPreview
Viene chiamato per terminare la modalità anteprima di stampa. Spesso è consigliabile passare alla pagina del documento che è stata visualizzata per l'ultima volta nell'anteprima di stampa. EndPrintPreview
è la possibilità dell'applicazione di farlo. Il membro pInfo-m_nCurPage> è la pagina che è stata visualizzata per l'ultima volta (all'estrema sinistra se sono state visualizzate due pagine) e il puntatore è un suggerimento sul punto in cui l'utente era interessato nella pagina. Poiché la struttura della visualizzazione dell'applicazione è sconosciuta al framework, è necessario fornire il codice per passare al punto scelto.
È consigliabile eseguire la maggior parte delle azioni prima di chiamare CView::EndPrintPreview
. Questa chiamata inverte gli effetti di DoPrintPreview
ed elimina pView, pDC e pInfo.
// Any further cleanup should be done here.
CView::EndPrintPreview(pDC, pInfo, point, pView);
CWinApp::OnFilePrintSetup
È necessario eseguire il mapping per la voce di menu Imposta stampa. Nella maggior parte dei casi, non è necessario eseguire l'override dell'implementazione.
Denominazione di pagine
Un altro problema è rappresentato dalla numerazione e dall'ordine delle pagine. Per semplici applicazioni di tipo word processor, si tratta di un problema semplice. La maggior parte dei sistemi di anteprima di stampa presuppone che ogni pagina stampata corrisponda a una pagina del documento.
Nel tentativo di fornire una soluzione generalizzata, è necessario considerare diversi aspetti. Si immagini un sistema CAD. L'utente ha un disegno che copre diversi fogli di dimensioni E. In un tracciatore di dimensioni E (o di dimensioni inferiori, ridimensionate), la numerazione delle pagine sarà come nel semplice caso. Ma su una stampante laser, stampando 16 pagine di dimensioni A per foglio, ciò che stampa l'anteprima considera una "pagina"
Come indicato nel paragrafo introduttivo, l'anteprima di stampa funge da stampante. Pertanto, l'utente vedrà cosa verrebbe fuori dalla stampante specifica selezionata. Spetta alla visualizzazione determinare l'immagine stampata in ogni pagina.
La stringa di descrizione della pagina nella CPrintInfo
struttura consente di visualizzare il numero di pagina all'utente se può essere rappresentato come un numero per pagina (come in "Pagina 1" o "Pagine 1-2"). Questa stringa viene usata dall'implementazione predefinita di CPreviewView::OnDisplayPageNumber
. Se è necessaria una visualizzazione diversa, è possibile eseguire l'override di questa funzione virtuale per fornire, ad esempio, "Sheet1, Sections A, B".