Übersicht über das Drucken

Mit Microsoft .NET Framework verfügen Anwendungsentwickler, die Windows Presentation Foundation (WPF) verwenden, über eine Vielzahl neuer Druck- und Drucksystemverwaltungs-APIs. Mit Windows Vista stehen einige dieser Erweiterungen des Drucksystems auch Entwicklern zur Verfügung, die Windows Forms-Anwendungen erstellen, sowie Entwicklern, die nicht verwalteten Code verwenden. Das Herzstück dieser neuen Funktionalität ist das neue XML Paper Specification (XPS)-Dateiformat und der XPS-Druckpfad.

Dieses Thema enthält folgende Abschnitte:

Info über XPS

XPS ist ein Format für elektronische Dokumente, ein Format für Spooldateien und eine Seitenbeschreibungssprache. Es handelt sich um ein offenes Dokumentformat, das XML, Open Packaging Conventions (OPC) und andere Branchenstandards verwendet, um plattformübergreifend nutzbare Dokumente zu erstellen. XPS vereinfacht die Vorgänge beim Erstellen, Teilen, Drucken, Anzeigen und Archivieren von digitalen Dokumenten. Weitere Informationen zu XPS finden Sie unter XPS-Dokumente.

Verschiedene Techniken für das Drucken von XPS-basierten Inhalten mithilfe von WPF sind in Programmgesteuertes Drucken von XPS-Dateien dargestellt. Es kann sinnvoll sein, diese Beispiele beim Durcharbeiten der in diesem Thema enthaltenen Inhalte hinzuzuziehen. (Entwickler*innen von nicht verwaltetem Code sollten die Dokumentation für die MXDC_ESCAPE-Funktion lesen. Windows Forms-Entwickler*innen müssen die API im System.Drawing.Printing-Namespace verwenden, die zwar den vollständigen XPS-Druckpfad nicht unterstützt, aber einen hybriden GDI-to-XPS-Druckpfad. Siehe Druckpfadarchitektur unten.)

XPS-Druckpfad

Der XML Paper Specification (XPS)-Druckpfad ist eine neue Windows-Funktion, die den Umgang mit dem Drucken in Windows-Anwendungen neu definiert. Da XPS eine Sprache zur Dokumentdarstellung (wie etwa RTF), ein Druckerspoolerformat (wie etwa WMF) und eine Seitenbeschreibungssprache (wie etwa PCL oder Postscript) ersetzen kann, bleibt im neuen Druckpfad das XPS-Format von der Veröffentlichung der Anwendung bis zur abschließenden Verarbeitung im Druckertreiber oder -gerät erhalten.

Der XPS-Druckpfad baut auf dem XPS-Druckertreibermodell (XPSDrv) auf, das für Entwickler eine Reihe von Vorzügen bereithält, wie etwa „what you see is what you get“ (WYSIWYG)-Druck, verbesserte Farbunterstützung und erheblich gesteigerte Druckleistung. (Weitere Informationen zu XPSDrv finden Sie unter Dokumentation zum Windows-Treiberkit.)

Der Betrieb des Druckerspoolers ist für XPS-Dokumente im Wesentlichen gegenüber früheren Versionen von Windows unverändert. Er wurde jedoch verbessert und unterstützt nun über den vorhandenen GDI-Druckpfad hinaus auch den XPS-Druckpfad. Der neue Druckpfad nutzt systemeigen eine XPS-Spooldatei. Zwar funktionieren für frühere Versionen von Windows erstellte Druckertreiber für den Benutzermodus weiterhin, für den XPS-Druckpfad ist jedoch ein XPS-Druckertreiber (XPSDrv) erforderlich.

Die Vorzüge des XPS-Druckpfads sind erheblich und umfassen u.a.:

  • WYSIWYG-Druckunterstützung

  • Systemeigene Unterstützung für erweiterte Farbprofile, die auch 32 Bit pro Kanal (bpc), CMYK, benannte Farben, n-Tinten und systemeigene Unterstützung von Transparenz und Farbverläufen einschließen.

  • Verbesserte Druckleistung sowohl für .NET Framework- als auch für Win32-basierte Anwendungen.

  • XPS-Format nach Branchenstandard.

Für einfache Druckszenarien ist eine einfache und intuitiv bedienbare API mit einem einzelnen Einstiegspunkt für Benutzeroberfläche, Konfiguration und Auftragsübergabe verfügbar. Für erweiterte Szenarien steht jetzt zusätzlich Unterstützung für Benutzeroberflächen-Anpassung (oder Verzicht auf die Benutzeroberfläche), synchronen oder asynchronen Druck und Funktionen zum Druck von Batchaufträgen zur Verfügung. Beide Optionen bieten Druckunterstützung mit vollständigen oder eingeschränkten Vertrauensstellungen.

XPS wurde im Hinblick auf Erweiterbarkeit entwickelt. Mithilfe des Extensibility Frameworks können XPS auf modulare Weise Features und Funktionen hinzugefügt werden. Zu den Erweiterungsfunktionen gehören:

  • Druckschema. Das öffentliche Schema wird regelmäßig aktualisiert und ermöglicht die schnelle Erweiterung von Gerätefunktionen. (Siehe dazu PrintTicket und PrintCapabilities unten.)

  • Erweiterbare Filterpipeline. Die Filterpipeline des XPS-Druckertreibers (XPSDrv) wurde dafür ausgelegt, sowohl direkten als auch skalierbaren Druck von XPS-Dokumenten zu ermöglichen. Weitere Informationen finden Sie unter XPSDrv-Druckertreiber.

Während sowohl Win32- als auch .NET Framework-Anwendungen XPS unterstützen, verwenden Win32- und Windows Forms-Anwendungen eine GDI-zu XPS-Konvertierung, um XPS-formatierten Inhalt für den XPS-Druckertreiber (XPSDrv) zu erstellen. Diese Anwendungen müssen den XPS-Druckpfad nicht zwangsläufig verwenden und können weiterhin den Enhanced Metafile (EMF)-basierten Druck verwenden. Die meisten Features und Verbesserungen von XPS sind jedoch nur für Anwendungen verfügbar, die den XPS-Druckpfad zum Ziel haben.

Um die Verwendung von XPSDrv-basierten Druckern durch Win32- und Windows Forms-Anwendungen zu ermöglichen, unterstützt der XPS-Druckertreiber (XPSDrv) die Konvertierung von GDI in das XPS-Format. Das XPSDrv-Modell umfasst außerdem einen Konverter für das XPS-Format nach GDI, sodass Win32-Anwendungen XPS-Dokumente drucken können. Für WPF-Anwendungen erfolgt die Konvertierung von XPS in das GDI-Format automatisch durch die Methoden Write und WriteAsync der XpsDocumentWriter-Klasse, wenn die Druckerwarteschlange des Schreibvorgangsziels nicht über einen XPSDrv-Treiber verfügt. (Windows Forms-Anwendungen können keine XPS-Dokumente drucken.)

Die folgende Abbildung stellt das Drucksubsystem dar und definiert die von Microsoft bereitgestellten sowie die von Software- und Hardwareherstellern definierten Anteile:

Screenshot shows the XPS print system.

Einfacher XPS-Druck

WPF definiert sowohl eine einfache als auch eine erweiterte API. Für Anwendungen, die keine umfangreichen Druckanpassungen oder Zugriff auf die Gesamtmenge der XPS-Funktionen erfordern, ist eine Unterstützung für einfachen Druck verfügbar. Die einfache Druckunterstützung wird über ein Druckdialogfeld-Steuerelement verfügbar gemacht, das nur minimale Konfiguration erfordert und eine vertraute Benutzeroberfläche bietet. Viele XPS-Funktionen sind in diesem vereinfachten Druckmodell verfügbar.

PrintDialog

Das System.Windows.Controls.PrintDialog-Steuerelement stellt einen einheitlichen Einstiegspunkt für die Benutzeroberfläche, Konfiguration und XPS-Auftragsübermittlung bereit. Informationen zum Instanziieren und Verwenden des Steuerelements finden Sie unter Aufrufen eines Druckdialogfelds.

Erweiterter XPS-Druck

Für den Zugriff auf die Gesamtmenge der XPS-Funktionen muss die erweiterte Druck-API verwendet werden. Mehrere relevante APIs sind ausführlicher unten beschrieben. Eine vollständige Liste der APIs des XPS-Druckpfads finden Sie in den Verweisen zu den Namespaces System.Windows.Xps und System.Printing.

PrintTicket und PrintCapabilities

Die Klassen PrintTicket und PrintCapabilities bilden die Grundlage der erweiterten XPS-Funktionen. Beide Arten von Objekten sind XML-formatierte Strukturen von druckorientierten Funktionen wie Sortierung, zweiseitigem Drucken, Heften usw. Diese Strukturen werden durch das Druckschema definiert. Ein PrintTicket weist einen Drucker an, wie ein Druckauftrag verarbeitet werden muss. Die PrintCapabilities -Klasse definiert die Fähigkeiten eines Druckers. Durch Abfragen der Funktionen eines Druckers kann ein PrintTicket erstellt werden, das die von einem Drucker unterstützten Funktionen in vollem Umfang nutzt. Analog dazu können nicht unterstützte Funktionen vermieden werden.

Im folgenden Beispiel wird das Abfragen der PrintCapabilities eines Druckers und das Erstellen eines PrintTicket mithilfe von Code gezeigt.

// ---------------------- GetPrintTicketFromPrinter -----------------------
/// <summary>
///   Returns a PrintTicket based on the current default printer.</summary>
/// <returns>
///   A PrintTicket for the current local default printer.</returns>
PrintTicket^ GetPrintTicketFromPrinter () 
{
   PrintQueue^ printQueue = nullptr;

   LocalPrintServer^ localPrintServer = gcnew LocalPrintServer();

   // Retrieving collection of local printer on user machine
   PrintQueueCollection^ localPrinterCollection = localPrintServer->GetPrintQueues();

   System::Collections::IEnumerator^ localPrinterEnumerator = localPrinterCollection->GetEnumerator();

   if (localPrinterEnumerator->MoveNext())
   {
      // Get PrintQueue from first available printer
      printQueue = ((PrintQueue^)localPrinterEnumerator->Current);
   } else
   {
      return nullptr;
   }
   // Get default PrintTicket from printer
   PrintTicket^ printTicket = printQueue->DefaultPrintTicket;

   PrintCapabilities^ printCapabilites = printQueue->GetPrintCapabilities();

   // Modify PrintTicket
   if (printCapabilites->CollationCapability->Contains(Collation::Collated))
   {
      printTicket->Collation = Collation::Collated;
   }
   if (printCapabilites->DuplexingCapability->Contains(Duplexing::TwoSidedLongEdge))
   {
      printTicket->Duplexing = Duplexing::TwoSidedLongEdge;
   }
   if (printCapabilites->StaplingCapability->Contains(Stapling::StapleDualLeft))
   {
      printTicket->Stapling = Stapling::StapleDualLeft;
   }
   return printTicket;
};// end:GetPrintTicketFromPrinter()
// ---------------------- GetPrintTicketFromPrinter -----------------------
/// <summary>
///   Returns a PrintTicket based on the current default printer.</summary>
/// <returns>
///   A PrintTicket for the current local default printer.</returns>
private PrintTicket GetPrintTicketFromPrinter()
{
    PrintQueue printQueue = null;

    LocalPrintServer localPrintServer = new LocalPrintServer();

    // Retrieving collection of local printer on user machine
    PrintQueueCollection localPrinterCollection =
        localPrintServer.GetPrintQueues();

    System.Collections.IEnumerator localPrinterEnumerator =
        localPrinterCollection.GetEnumerator();

    if (localPrinterEnumerator.MoveNext())
    {
        // Get PrintQueue from first available printer
        printQueue = (PrintQueue)localPrinterEnumerator.Current;
    }
    else
    {
        // No printer exist, return null PrintTicket
        return null;
    }

    // Get default PrintTicket from printer
    PrintTicket printTicket = printQueue.DefaultPrintTicket;

    PrintCapabilities printCapabilites = printQueue.GetPrintCapabilities();

    // Modify PrintTicket
    if (printCapabilites.CollationCapability.Contains(Collation.Collated))
    {
        printTicket.Collation = Collation.Collated;
    }

    if ( printCapabilites.DuplexingCapability.Contains(
            Duplexing.TwoSidedLongEdge) )
    {
        printTicket.Duplexing = Duplexing.TwoSidedLongEdge;
    }

    if (printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft))
    {
        printTicket.Stapling = Stapling.StapleDualLeft;
    }

    return printTicket;
}// end:GetPrintTicketFromPrinter()
' ---------------------- GetPrintTicketFromPrinter -----------------------
''' <summary>
'''   Returns a PrintTicket based on the current default printer.</summary>
''' <returns>
'''   A PrintTicket for the current local default printer.</returns>
Private Function GetPrintTicketFromPrinter() As PrintTicket
    Dim printQueue As PrintQueue = Nothing

    Dim localPrintServer As New LocalPrintServer()

    ' Retrieving collection of local printer on user machine
    Dim localPrinterCollection As PrintQueueCollection = localPrintServer.GetPrintQueues()

    Dim localPrinterEnumerator As System.Collections.IEnumerator = localPrinterCollection.GetEnumerator()

    If localPrinterEnumerator.MoveNext() Then
        ' Get PrintQueue from first available printer
        printQueue = CType(localPrinterEnumerator.Current, PrintQueue)
    Else
        ' No printer exist, return null PrintTicket
        Return Nothing
    End If

    ' Get default PrintTicket from printer
    Dim printTicket As PrintTicket = printQueue.DefaultPrintTicket

    Dim printCapabilites As PrintCapabilities = printQueue.GetPrintCapabilities()

    ' Modify PrintTicket
    If printCapabilites.CollationCapability.Contains(Collation.Collated) Then
        printTicket.Collation = Collation.Collated
    End If

    If printCapabilites.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge) Then
        printTicket.Duplexing = Duplexing.TwoSidedLongEdge
    End If

    If printCapabilites.StaplingCapability.Contains(Stapling.StapleDualLeft) Then
        printTicket.Stapling = Stapling.StapleDualLeft
    End If

    Return printTicket
End Function ' end:GetPrintTicketFromPrinter()

PrintServer und PrintQueue

Die PrintServer-Klasse stellt einen Netzwerkdruckerserver und die PrintQueue-Klasse einen Drucker mit zugeordneter Auftragswarteschlange dar. In Kombination ermöglichen diese APIs die erweiterte Verwaltung der Druckaufträge von Servern. Ein PrintServer oder eine davon abgeleitete Klasse wird verwendet, um eine PrintQueue zu verwalten. Die AddJob-Methode wird verwendet, um einen neuen Druckauftrag in die Warteschlange einzustellen.

Das folgende Beispiel zeigt, wie ein LocalPrintServer erstellt und mithilfe von Code auf seine Standard-PrintQueue zugegriffen wird.

// -------------------- GetPrintXpsDocumentWriter() -------------------
/// <summary>
///   Returns an XpsDocumentWriter for the default print queue.</summary>
/// <returns>
///   An XpsDocumentWriter for the default print queue.</returns>
private XpsDocumentWriter GetPrintXpsDocumentWriter()
{
    // Create a local print server
    LocalPrintServer ps = new LocalPrintServer();

    // Get the default print queue
    PrintQueue pq = ps.DefaultPrintQueue;

    // Get an XpsDocumentWriter for the default print queue
    XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq);
    return xpsdw;
}// end:GetPrintXpsDocumentWriter()
' -------------------- GetPrintXpsDocumentWriter() -------------------
''' <summary>
'''   Returns an XpsDocumentWriter for the default print queue.</summary>
''' <returns>
'''   An XpsDocumentWriter for the default print queue.</returns>
Private Function GetPrintXpsDocumentWriter() As XpsDocumentWriter
    ' Create a local print server
    Dim ps As New LocalPrintServer()

    ' Get the default print queue
    Dim pq As PrintQueue = ps.DefaultPrintQueue

    ' Get an XpsDocumentWriter for the default print queue
    Dim xpsdw As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(pq)
    Return xpsdw
End Function ' end:GetPrintXpsDocumentWriter()

XpsDocumentWriter

Ein XpsDocumentWriter mit seinen vielen Write- und WriteAsync-Methoden wird zum Schreiben von XPS-Dokumenten in eine PrintQueue verwendet. So wird z. B. die Methode Write(FixedPage, PrintTicket) verwendet, um ein XPS-Dokument und ein PrintTicket synchron auszugeben. Die Methode WriteAsync(FixedDocument, PrintTicket) wird verwendet, um ein XPS-Dokument und ein PrintTicket asynchron auszugeben.

Im folgenden Beispiel wird veranschaulicht, wie ein XpsDocumentWriter mithilfe von Code erstellt wird.

// -------------------- GetPrintXpsDocumentWriter() -------------------
/// <summary>
///   Returns an XpsDocumentWriter for the default print queue.</summary>
/// <returns>
///   An XpsDocumentWriter for the default print queue.</returns>
private XpsDocumentWriter GetPrintXpsDocumentWriter()
{
    // Create a local print server
    LocalPrintServer ps = new LocalPrintServer();

    // Get the default print queue
    PrintQueue pq = ps.DefaultPrintQueue;

    // Get an XpsDocumentWriter for the default print queue
    XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq);
    return xpsdw;
}// end:GetPrintXpsDocumentWriter()
' -------------------- GetPrintXpsDocumentWriter() -------------------
''' <summary>
'''   Returns an XpsDocumentWriter for the default print queue.</summary>
''' <returns>
'''   An XpsDocumentWriter for the default print queue.</returns>
Private Function GetPrintXpsDocumentWriter() As XpsDocumentWriter
    ' Create a local print server
    Dim ps As New LocalPrintServer()

    ' Get the default print queue
    Dim pq As PrintQueue = ps.DefaultPrintQueue

    ' Get an XpsDocumentWriter for the default print queue
    Dim xpsdw As XpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(pq)
    Return xpsdw
End Function ' end:GetPrintXpsDocumentWriter()

Die AddJob-Methoden stellen ebenfalls Druckmöglichkeiten bereit. Weitere Informationen finden Sie unter Programmgesteuertes Drucken von XPS-Dateien. .

GDI-Druckpfad

Während WPF-Anwendungen den XPS-Druckpfad nativ unterstützen, können Win32 und Windows Forms-Anwendungen ebenfalls einige der XPS-Funktionen nutzen. Der XPS-Druckertreiber (XPSDrv) kann GDI-basierte Ausgaben in das XPS-Format konvertieren. Für erweiterte Szenarios wird die benutzerdefinierte Konvertierung von Inhalten mithilfe von Microsoft XPS Document Converter (MXDC) unterstützt. In ähnlicher Weise können WPF-Anwendungen durch Aufrufen einer der Methoden Write oder WriteAsync der XpsDocumentWriter-Klasse und Zuweisen eines XpsDrv-fremden Druckers als Zieldruckerwarteschlange ebenfalls Ausgaben an den GDI-Druckpfad vornehmen.

Für Anwendungen, die keine XPS-Funktion oder -Unterstützung benötigen, bleibt der aktuelle GDI-Druckpfad unverändert.

XPSDrv-Treibermodell

Der XPS-Druckpfad verbessert die Effizienz des Spoolings durch Verwendung von XPS als systemeigenem Druckerspoolerformat beim Drucken auf XPS-fähigen Druckern oder Treibern. Das vereinfachte Spooling beseitigt die Notwendigkeit, vor dem Spoolen des Dokuments eine temporäre Spoolingdatei, wie etwa eine EMF-Datendatei, zu generieren. Durch geringere Größe der Spooldateien kann der XPS-Druckpfad den Netzwerkdatenverkehr verringern und die Druckleistung verbessern.

EMF ist ein geschlossenes Format, das Anwendungsausgaben als Abfolge von Aufrufen an GDI für Renderingdienste darstellt. Im Gegensatz zu ENF stellt das XPS-Spoolingformat das tatsächliche Dokument dar, ohne bei der Ausgabe an einen XPS-basierten Druckertreiber (XPSDrv) weitere Interpretation zu erfordern. Die Treiber können direkt mit den Daten im vorliegenden Format arbeiten. Durch diese Fähigkeit entfallen die Daten- und Farbraumkonvertierungen, die bei der Verwendung von EMF-Dateien und GDI-basierten Druckertreibern erforderlich sind.

Normalerweise verringert sich die Größe von Spooldateien, wenn XPS-Dokumente verwendet werden, die einen XPS-Druckertreiber (XPSDrv) zum Ziel haben, gegenüber ihren EMF-Entsprechungen; allerdings gibt es Ausnahmen:

  • Eine Vektorgrafik, die sehr komplex ist, viele Ebenen aufweist oder ineffizient geschrieben wurde, kann größer als die Bitmapversion der gleichen Grafik sein.

  • Zum Zweck der Anzeige am Bildschirm werden in XPS-Dateien Geräteschriftarten sowie computerbasierte Schriftarten eingebettet, während in GDI-Spooldateien keine Geräteschriftarten eingebettet sind. Beide Schriftarten sind jedoch in Teilmengen gegliedert (siehe unten), und Druckertreiber können die Geräteschriftarten vor der Übertragung der Datei an den Drucker entfernen.

Die Reduzierung der Spoolgröße erfolgt mithilfe mehrerer Mechanismen:

  • Unterklassen von Schriftarten. Nur Zeichen, die im Dokument verwendet werden, werden in der XPS-Datei gespeichert.

  • Erweiterte Grafikunterstützung. Durch die systemeigene Unterstützung von Transparenz und Farbverlaufsprimitiven wird die Rasterung von Inhalten im XPS-Dokument vermieden.

  • Erkennung gemeinsamer Ressourcen. Ressourcen, die mehrfach verwendet werden (wie etwa ein Bild, das ein Firmenlogo darstellt) werden als freigegebene Ressourcen behandelt und nur einmal geladen.

  • ZIP-Komprimierung. Alle XPS-Dokumente verwenden ZIP-Komprimierung.

Siehe auch