Mehrseitige Dokumente
In diesem Artikel wird das Windows-Druckprotokoll beschrieben und erläutert, wie Dokumente gedruckt werden, die mehr als eine Seite enthalten. Der Artikel behandelt die folgenden Themen:
Das Druckprotokoll
Zum Drucken eines mehrseitigen Dokuments interagieren das Framework und die Ansicht wie folgt. Zuerst zeigt das Framework das Dialogfeld "Drucken " an, erstellt einen Gerätekontext für den Drucker und ruft die StartDoc-Memberfunktion des CDC-Objekts auf. Anschließend ruft das Framework für jede Seite des Dokuments die StartPage-Memberfunktion des CDC
Objekts auf, weist das Ansichtsobjekt an, die Seite zu drucken, und ruft die EndPage-Memberfunktion auf. Wenn der Druckermodus vor dem Starten einer bestimmten Seite geändert werden muss, ruft die Ansicht ResetDC auf, wodurch die DEVMODE-Struktur aktualisiert wird, die die informationen zum neuen Druckermodus enthält. Wenn das gesamte Dokument gedruckt wurde, ruft das Framework die EndDoc-Memberfunktion auf.
Überschreiben von Ansichtsklassenfunktionen
Die CView-Klasse definiert mehrere Memberfunktionen, die beim Drucken vom Framework aufgerufen werden. Indem Sie diese Funktionen in Ihrer Ansichtsklasse überschreiben, stellen Sie die Verbindungen zwischen der Drucklogik des Frameworks und der Drucklogik Der Ansichtsklasse bereit. In der folgenden Tabelle sind diese Memberfunktionen aufgeführt.
Überschreibbare Funktionen von CView für den Druck
Name | Grund für die Außerkraftsetzung |
---|---|
OnPreparePrinting | So fügen Sie Werte in das Dialogfeld "Drucken" ein, insbesondere die Länge des Dokuments |
OnBeginPrinting | So weisen Sie Schriftarten oder andere GDI-Ressourcen zu |
OnPrepareDC | So passen Sie Attribute des Gerätekontexts für eine bestimmte Seite an, oder zum Ausführen der Seitenauslagerung |
OnPrint | So drucken Sie eine bestimmte Seite |
OnEndPrinting | So behandeln Sie GDI-Ressourcen |
Sie können auch druckbezogene Verarbeitung in anderen Funktionen ausführen, aber diese Funktionen sind die Funktionen, die den Druckprozess vorantreiben.
In der folgenden Abbildung sind die Schritte dargestellt, die am Druckprozess beteiligt sind, und zeigt, wo die einzelnen CView
Druckelementfunktionen aufgerufen werden. Im restlichen Artikel werden die meisten dieser Schritte ausführlicher erläutert. Weitere Teile des Druckvorgangs werden im Artikel "Allocating GDI Resources" beschrieben.
Druckschleife
Paginierung
Das Framework speichert einen Großteil der Informationen zu einem Druckauftrag in einer CPrintInfo-Struktur . Mehrere der Werte im CPrintInfo
Zusammenhang mit der Paginierung. Auf diese Werte kann zugegriffen werden, wie in der folgenden Tabelle dargestellt.
In CPrintInfo gespeicherte Seitenzahleninformationen
Membervariable oder Funktionsname(n) |
Seitenzahl, auf die verwiesen wird |
---|---|
GetMinPage /SetMinPage |
Erste Seite des Dokuments |
GetMaxPage /SetMaxPage |
Letzte Seite des Dokuments |
GetFromPage |
Erste Seite, die gedruckt werden soll |
GetToPage |
Letzte Seite, die gedruckt werden soll |
m_nCurPage |
Aktuell gedruckte Seite |
Seitenzahlen beginnen bei 1, d. h. die erste Seite ist 1 nummeriert, nicht 0. Weitere Informationen zu diesen und anderen Mitgliedern von CPrintInfo finden Sie in der MFC-Referenz.
Am Anfang des Druckvorgangs ruft das Framework die OnPreparePrinting-Memberfunktion der Ansicht auf und übergibt einen Zeiger auf eine CPrintInfo
Struktur. Der Anwendungs-Assistent stellt eine Implementierung dieses OnPreparePrinting
Aufrufs von DoPreparePrinting, einer anderen Memberfunktion von CView
. DoPreparePrinting
ist die Funktion, die das Dialogfeld "Drucken" anzeigt und einen Druckergerätekontext erstellt.
An diesem Punkt weiß die Anwendung nicht, wie viele Seiten im Dokument vorhanden sind. Sie verwendet die Standardwerte 1 und 0xFFFF für die Zahlen der ersten und letzten Seite des Dokuments. Wenn Sie wissen, wie viele Seiten Ihr Dokument enthält, überschreiben OnPreparePrinting
Sie es, und rufen Sie [SetMaxPage]---brokenlink--(reference/cprintinfo-class.md#setmaxpage) für die CPrintInfo
Struktur auf, bevor Sie es an DoPreparePrinting
senden. Auf diese Weise können Sie die Länge Ihres Dokuments angeben.
DoPreparePrinting
zeigt dann das Dialogfeld "Drucken" an. Wenn sie zurückgegeben wird, enthält die CPrintInfo
Struktur die vom Benutzer angegebenen Werte. Wenn der Benutzer nur einen ausgewählten Seitenbereich drucken möchte, kann er im Dialogfeld "Drucken" die Anfangs- und Endseitenzahlen angeben. Das Framework ruft diese Werte mithilfe der GetFromPage
CPrintInfo-Funktionen GetToPage
ab. Wenn der Benutzer keinen Seitenbereich angibt, ruft GetMinPage
das Framework die zurückgegebenen Werte auf, GetMaxPage
um das gesamte Dokument zu drucken.
Für jede zu druckende Seite eines Dokuments ruft das Framework zwei Memberfunktionen in Der Ansichtsklasse OnPrepareDC und OnPrint auf und übergibt jede Funktion zwei Parameter: einen Zeiger auf ein CDC-Objekt und einen Zeiger auf eine CPrintInfo
Struktur. Jedes Mal, wenn das Framework aufruft OnPrepareDC
und OnPrint
, wird ein anderer Wert im m_nCurPage Element der CPrintInfo
Struktur übergeben. Auf diese Weise teilt das Framework der Ansicht mit, welche Seite gedruckt werden soll.
Die OnPrepareDC-Memberfunktion wird auch für die Bildschirmanzeige verwendet. Es nimmt Anpassungen am Gerätekontext vor dem Zeichnen vor. OnPrepareDC
dient einer ähnlichen Rolle beim Drucken, aber es gibt einige Unterschiede: Zuerst stellt das CDC
Objekt einen Druckergerätekontext anstelle eines Bildschirmgerätekontexts dar, und zweitens wird ein CPrintInfo
Objekt als zweiter Parameter übergeben. (Dieser Parameter ist NULL , wenn OnPrepareDC
für die Bildschirmanzeige aufgerufen wird.) Überschreiben OnPrepareDC
Sie, um Anpassungen am Gerätekontext vorzunehmen, basierend auf der Seite, die gedruckt wird. Sie können beispielsweise den Viewportursprung und den Clippingbereich verschieben, um sicherzustellen, dass der entsprechende Teil des Dokuments gedruckt wird.
Die OnPrint-Memberfunktion führt den tatsächlichen Druck der Seite aus. Der Artikel How Default Printing Is Done zeigt, wie das Framework OnDraw mit einem Druckergerätekontext aufruft, um das Drucken durchzuführen. Genauer gesagt ruft das Framework eine CPrintInfo
Struktur und einen Gerätekontext auf OnPrint
und OnPrint
übergibt den Gerätekontext an OnDraw
. Überschreiben OnPrint
Sie das Rendern, das nur beim Drucken und nicht für die Bildschirmanzeige ausgeführt werden soll. Wenn Sie beispielsweise Kopf- oder Fußzeilen drucken möchten (weitere Informationen finden Sie im Artikel "Kopf- und Fußzeilen "). Rufen Sie dann die Außerkraftsetzung OnDraw
auf OnPrint
, um das Rendering zu erledigen, das sowohl für die Bildschirmanzeige als auch für den Druck verwendet wird.
Die Tatsache, dass das OnDraw
Rendering sowohl für die Bildschirmanzeige als auch für den Druck bedeutet, dass Ihre Anwendung WYSIWYG ist: "Was Sie sehen, ist, was Sie erhalten." Angenommen, Sie schreiben keine WYSIWYG-Anwendung. Betrachten Sie z. B. einen Texteditor, der eine fett formatierte Schriftart zum Drucken verwendet, jedoch Steuerelementcodes anzeigt, um fett formatierten Text auf dem Bildschirm anzuzeigen. In einer solchen Situation verwenden OnDraw
Sie ausschließlich für die Bildschirmanzeige. Wenn Sie außer Kraft setzen OnPrint
, ersetzen Sie den Aufruf OnDraw
durch einen Aufruf einer separaten Zeichnungsfunktion. Diese Funktion zeichnet das Dokument so, wie es auf Papier angezeigt wird, mit den Attributen, die Sie nicht auf dem Bildschirm anzeigen.
Druckerseiten im Vergleich zu Dokumentseiten
Wenn Sie auf Seitenzahlen verweisen, ist es manchmal erforderlich, zwischen dem Konzept des Druckers einer Seite und dem Konzept eines Dokuments einer Seite zu unterscheiden. Aus Sicht des Druckers ist eine Seite ein Blatt Papier. Ein Blatt Papier entspricht jedoch nicht unbedingt einer Seite des Dokuments. Wenn Sie beispielsweise einen Newsletter drucken, bei dem die Blätter gefaltet werden sollen, kann ein Blatt Papier sowohl die ersten als auch die letzten Seiten des Dokuments nebeneinander enthalten. Wenn Sie eine Kalkulationstabelle drucken, besteht das Dokument nicht aus Seiten. Stattdessen enthält ein Blatt Papier möglicherweise Zeilen 1 bis 20, Spalten 6 bis 10.
Alle Seitenzahlen in der CPrintInfo-Struktur beziehen sich auf Druckerseiten. Das Framework ruft OnPrepareDC
und OnPrint
einmal für jedes Blatt Papier auf, das den Drucker durchläuft. Wenn Sie die OnPreparePrinting-Funktion außer Kraft setzen, um die Länge des Dokuments anzugeben, müssen Sie Druckerseiten verwenden. Wenn eine 1:1-Korrespondenz vorhanden ist (d. h. eine Druckerseite entspricht einer Dokumentseite), ist dies einfach. Wenn dokumentseitige Seiten und Druckerseiten dagegen nicht direkt übereinstimmen, müssen Sie zwischen ihnen übersetzen. Ziehen Sie z. B. das Drucken einer Kalkulationstabelle in Betracht. Beim Überschreiben OnPreparePrinting
müssen Sie berechnen, wie viele Blätter Papier benötigt werden, um die gesamte Kalkulationstabelle zu drucken und diesen Wert dann beim Aufrufen der SetMaxPage
Memberfunktion zu CPrintInfo
verwenden. Ebenso müssen Sie beim Überschreiben OnPrepareDC
m_nCurPage in den Bereich von Zeilen und Spalten übersetzen, die auf diesem bestimmten Blatt angezeigt werden, und dann den Viewportursprung entsprechend anpassen.
Druckzeit-Paginierung
In manchen Situationen kann Ihre Ansichtsklasse im Voraus nicht wissen, wie lange das Dokument ist, bis es tatsächlich gedruckt wurde. Angenommen, Ihre Anwendung ist nicht WYSIWYG, sodass die Länge eines Dokuments auf dem Bildschirm nicht der Länge entspricht, wenn sie gedruckt wird.
Dies führt zu einem Problem, wenn Sie OnPreparePrinting für Ihre Ansichtsklasse außer Kraft setzen: Sie können keinen Wert an die SetMaxPage
Funktion der CPrintInfo-Struktur übergeben, da Sie die Länge eines Dokuments nicht kennen. Wenn der Benutzer keine Seitenzahl angibt, die mit der Verwendung des Dialogfelds "Drucken" beendet werden soll, weiß das Framework nicht, wann die Druckschleife beendet werden soll. Die einzige Möglichkeit, zu bestimmen, wann die Druckschleife beendet werden soll, besteht darin, das Dokument auszudrucken und zu sehen, wann sie endet. Ihre Ansichtsklasse muss das Ende des Dokuments überprüfen, während es gedruckt wird, und dann das Framework informieren, wenn das Ende erreicht ist.
Das Framework basiert auf der OnPrepareDC-Funktion Ihrer Ansichtsklasse, um sie mitzuteilen, wann sie beendet werden soll. Nach jedem Aufruf OnPrepareDC
überprüft das Framework ein Element der Struktur, die CPrintInfo
m_bContinuePrinting genannt wird. Der Standardwert ist TRUE. Solange es wieder Standard ist, setzt das Framework die Druckschleife fort. Wenn sie auf FALSE festgelegt ist, wird das Framework beendet. Wenn Sie die Seitenauslagerung während der Druckzeit ausführen möchten, überschreiben OnPrepareDC
Sie, ob das Ende des Dokuments erreicht wurde, und legen Sie m_bContinuePrinting auf FALSE fest, wenn es vorhanden ist.
Die Standardimplementierung von OnPrepareDC
Sätzen m_bContinuePrinting auf FALSE , wenn die aktuelle Seite größer als 1 ist. Wenn die Länge des Dokuments nicht angegeben wurde, geht das Framework davon aus, dass das Dokument eine Seite lang ist. Eine Folge davon ist, dass Sie vorsichtig sein müssen, wenn Sie die Basisklassenversion von OnPrepareDC
. Gehen Sie nicht davon aus, dass m_bContinuePrinting nach dem Aufrufen der Basisklassenversion WAHR ist.