Freigeben über


Mehrseitige Dokumente

Hinweis

Die Microsoft Foundation Classes (MFC)-Bibliothek wird weiterhin unterstützt. Wir fügen jedoch keine Features mehr hinzu oder aktualisieren die Dokumentation.

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.

Override View Class-Funktionen

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 Ihrer Ansichtsklasse bereit. In der folgenden Tabelle sind diese Mitgliederfunktionen aufgeführt.

CViews überschreibbare Funktionen für den Druck

Name Grund für das Überschreiben
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 Um Attribute des Gerätekontexts für eine bestimmte Seite anzupassen oder um die Paginierung zur Druckzeit vorzunehmen
OnPrint So drucken Sie eine bestimmte Seite
OnEndPrinting Um GDI-Ressourcen freizugeben

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 am Druckprozess beteiligten Schritte dargestellt, und darüber hinaus wird gezeigt, 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.

Druckschleifenprozess.
Die Druckschleife

Paginierung

Das Framework speichert einen Großteil der Informationen zu einem Druckauftrag in einer CPrintInfo-Struktur . Mehrere der Werte in CPrintInfo betreffen die Paginierung; auf diese Werte kann, wie in der folgenden Tabelle dargestellt, zugegriffen werden.

In CPrintInfo gespeicherte Seitenzahleninformationen

Member-Variable 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 Seite wird derzeit gedruckt

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 von OnPreparePrinting bereit, die DoPreparePrinting, eine weitere Memberfunktion von CView, aufruft. 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 Sie OnPreparePrinting und rufen Sie [SetMaxPage]---brokenlink--(reference/cprintinfo-class.md#setmaxpage) für die CPrintInfo Struktur auf, bevor Sie es an die 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 Funktionen GetFromPage und GetToPage von CPrintInfo ab. Wenn der Benutzer keinen Seitenbereich angibt, ruft das Framework GetMinPage und GetMaxPage auf und verwendet die zurückgegebenen Werte, um das gesamte Dokument zu drucken.

Für jede zu druckende Seite eines Dokuments ruft das Framework zwei Memberfunktionen in Ihrer Ansichtsklasse OnPrepareDC und OnPrint auf und übergibt jeder 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 Sie OnPrepareDC, um Anpassungen am Gerätekontext vorzunehmen, basierend auf der Seite, die gedruckt wird. Sie können zum Beispiel den Ursprung des Viewports und den Clippingbereich verschieben, um sicherzustellen, dass der entsprechende Teil des Dokuments gedruckt wird.

Die Funktion OnPrint Member führt den eigentlichen Druck der Seite durch. 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 OnPrint mit einer CPrintInfo-Struktur und einem Gerätekontext auf und OnPrint übergibt den Gerätekontext an OnDraw. Überschreiben Sie diese Option, OnPrint um alle Renderings durchzuführen, die nur während des Druckens und nicht für die Bildschirmdarstellung durchgeführt werden sollten. Wenn Sie beispielsweise Kopf- oder Fußzeilen drucken möchten (weitere Informationen finden Sie im Artikel "Kopf- und Fußzeilen "). Rufen Sie dann OnDraw von der Überschreibung von OnPrint an, um das Rendering sowohl für die Bildschirmanzeige als auch für den Druck durchzuführen.

Die Tatsache, dass das OnDraw das Rendering sowohl für die Bildschirmanzeige als auch für den Druck übernimmt, bedeutet, dass Ihre Applikation WYSIWYG ist: "Was Sie sehen, ist, was Sie bekommen." 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 OnPrint überschreiben, ersetzen Sie den Aufruf von 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 sich auf Seitenzahlen beziehen, ist es manchmal notwendig, 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. Ähnlich verhält es sich, wenn Sie eine Kalkulationstabelle drucken; das Dokument besteht überhaupt 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 von OnPreparePrinting müssen Sie berechnen, wie viele Blätter Papier benötigt werden, um die gesamte Kalkulationstabelle zu drucken, und diesen Wert beim Aufrufen der SetMaxPage-Mitgliedsfunktion von CPrintInfo verwenden. In ähnlicher Weise müssen OnPrepareDCSie beim Überschreiben m_nCurPage in den Bereich der Zeilen und Spalten übersetzen, die auf diesem bestimmten Blatt angezeigt werden, und dann den Ursprung des Darstellungsbereichs entsprechend anpassen.

Druckzeit Seitennummerierung

In einigen Situationen weiß Ihre Ansichtsklasse möglicherweise nicht im Voraus, wie lange es dauert, bis das Dokument 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 von OnPrepareDC überprüft das Framework ein Element der CPrintInfo-Struktur, das m_bContinuePrinting genannt wird. Der Standardwert ist TRUE. Solange es so bleibt, setzt das Framework die Druckschleife fort. Wenn sie auf FALSE festgelegt ist, wird das Framework beendet. Um die Seitenauslagerung während der Druckzeit durchzuführen, überschreiben Sie OnPrepareDC, um zu überprüfen, ob das Ende des Dokuments erreicht wurde, und setzen Sie m_bContinuePrinting auf FALSE, wenn dies der Fall ist.

Die Standardimplementierung von OnPrepareDC setzt 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 darauf achten müssen, wenn Sie die Version der Basisklasse von OnPrepareDC aufrufen. Gehen Sie nicht davon aus, dass m_bContinuePrinting nach dem Aufrufen der Basisklassenversion true ist.

Was möchten Sie mehr über

Siehe auch

Drucken
CView-Klasse
CDC-Klasse