Gewusst wie: Erweitern des Druckschemas und Erstellen von neuen Drucksystemklassen

Wenn die Anwendung spezielle Druckgeräte mit Merkmalen handhaben muss, die von der bestehenden PrintSystemObject-Klasse, der PrintQueue-Klasse, der PrintCapabilities-Klasse und der PrintTicket-Klasse nicht widergespiegelt werden, empfiehlt es sich, durch Vererbung neue Klassen abzuleiten, erweiterte Versionen der PrintCapabilities-Klasse und der PrintTicket-Klasse zu erstellen sowie möglicherweise auch das Print Schema zu erweitern.In diesem Artikel werden die wesentlichen Teile solch eines Projekts beschrieben. Allerdings wird nur eine von vielen Möglichkeiten zur Erweiterung der relevanten verwalteten Klassen erläutert.

Es wird empfohlen, diesen Artikel in Verbindung mit der umfangreichen Dokumentation für das Print Schema zu lesen.In diesem Artikel wird vorausgesetzt, dass Sie zumindest in Grundzügen wissen, worum es sich bei dem Schema handelt und was PrintTicket-Dokumente und PrintCapabilities-Dokumente sind.

Dieser Artikel enthält die folgenden Abschnitte.

  • Ableiten einer neuen Klasse durch Vererbung

  • Bestimmen, ob die Features des Geräts bereits im Druckschema definiert sind

  • Erstellen von Typen zur Darstellung von Gerätefeatures

  • Erweitern der PrintCapabilities-Klasse und der PrintTicket-Klasse

    • Erweitern der PrintTicket-Klasse

    • Erweitern der PrintCapabilities-Klasse

  • Lesen und Schreiben von PrintCapabilities-XML-Streams und PrintTicket-XML-Streams

  • Überladen und Erweitern von Eigenschaften und Methoden

  • Erweitern von in Schemas definierten Features

  • Erweitern des System.Printing.IndexedProperties-Namespaces

Beispiel

Das in diesem Artikel dargestellte Beispielprojekt stellt nicht alle der zum Kompilieren und Ausführen einer Anwendung erforderlichen Details bereit.Es soll Ihnen nur die wesentlichen Schritte verdeutlichen, die zur Erweiterung der Funktionalität des System.Printing-Namespaces und des System.Printing.IndexedProperties-Namespaces auf Druckgeräte mit nicht explizit in diesen Namespaces unterstützten Features erforderlich sind.Codebeispiele werden nur an den Stellen bereitgestellt, an denen konkrete Details erforderlich sind.

Die Codebeispiele enthalten zudem nicht unbedingt gute Programmiertechniken oder sicheren Code.Auf Aspekte, die nicht unmittelbar für den Gegenstand dieses Artikels relevant sind, wird nicht eingegangen.

Ferner richtet sich dieser Artikel in erster Linie an Anwendungsentwickler und weniger an Entwickler von Gerätetreibern.Aus dem Grund liegt die Betonung auf dem Schreiben von PrintTicket-Objekten statt von PrintCapabilities-Objekten.

Ableiten einer neuen Klasse durch Vererbung

Sie beginnen mit der Ableitung einer Klasse zur Darstellung des Geräts von der PrintQueue-Klasse.Im Codebeispiel unten wird eine BrailleEmbosser-Klasse abgeleitet.Braille ist eine von Blinden lesbare Sprache, weil die Symbole aus "Punkten" bestehen, die an der Papieroberfläche etwas erhöht sind und so mit den Fingerspitzen ertastet werden können.Bei einem Braille-Drucker handelt es sich ganz einfach um einen Drucker, mit dem sich Braille-Schrift drucken lässt.Einige Treiber für Braille-Drucker können die reguläre Braille-Schrift in Braille Grade 3 (gelegentlich auch Braille 3 genannt) übersetzen. Dies ist eine Platz sparende Braille-Version mit vielen Zusammenziehungen und Abkürzungen.Im Beispiel wird eine Eigenschaft zur Darstellung dieses Features bereitgestellt.

Oft müssen Sie auch einige geerbte Eigenschaften und Methoden überladen.Weitere Einzelheiten finden Sie weiter unten unter Überladen und Erweitern von Eigenschaften und Methoden.

class BrailleEmbosser : PrintQueue
{
   public BrailleEmbosser(PrintServer ps, String s, PrintSystemDesiredAccess access) : base(ps, s, access)
   {
      // Optionally, include here code to set non-inherited fields.}

   // other constructor declarations omitted

   private Boolean isBraille3Enabled;

   public Boolean IsBraile3Enabled
   {
      get { return isBraille3Enabled; }
      set { isBraille3Enabled = value; }
   }

   // remainder of class definition omitted
}

Bestimmen, ob die Features des Geräts bereits im Druckschema definiert sind

Die PrintTicket-Klasse und die PrintCapabilities-Klasse verfügen über Eigenschaften, mit denen die gängigsten Druckerfeatures dargestellt werden. In der Spezifikation Print Schema Public Keywords sind jedoch noch viel mehr Features definiert, die in diesen Klassen nicht explizit widergespiegelt werden.(Eine Liste der allgemeinen Features finden Sie in den Eigenschaften der PrintCapabilities-Klasse.) Sie sollten die Spezifikation lesen, um zu bestimmen, ob die speziellen Features des Geräts darin definiert sind.Für alle Features, die in der Spezifikation enthalten sind, erweist sich die Verwendung des Spezifikationsmodells als sehr vorteilhaft: Dank eines gemeinsamen Modells und einer gemeinsamen Terminologie können PrintTicket-XML-Dokumente für ein Gerät erstellt werden, die dann von einem anderen Gerät verwendet werden können.(Das zweite Gerät könnte von einem anderen Hersteller stammen und tatsächlich erst nach der ersten Erstellung des PrintTicket-Dokuments entwickelt worden sein.) Es können Drucktickets in die Dokumente selbst eingebettet werden, sodass die Druck- und Formatierungswünsche des Autors bei der Verteilung des Dokuments an Personen mit anderen Druckern mitgeliefert werden können.

Im verbleibenden Teil dieses Artikels werden Features, die von der PrintTicket-Klasse und der PrintCapabilities-Klasse explizit unterstützt werden, als "allgemeine Features" bezeichnet. Diejenigen Features, die von den beiden Klassen nicht explizit unterstützt werden, wenngleich sie in der Spezifikation Print Schema Public Keywords definiert sind, werden als "definierte Features" bezeichnet. Features, die nicht in der Spezifikation für öffentliche Schlüsselwörter definiert sind, werden als "neue Features" bezeichnet.

Es ist auch möglich, dass das Gerät ein fast mit einem definierten Feature identisches Feature aufweist, dabei aber über eine oder mehrere zusätzliche Optionen verfügt, die in der Spezifikation Print Schema Public Keywords nicht erkannt werden.Das Print Schema kann so erweitert werden, dass diese Features auf eine Art und Weise gehandhabt werden, bei der möglichst viele Anteile der bestehenden Definition genutzt werden.Weitere Informationen zum Arbeiten mit solchen Features finden Sie weiter unten im Abschnitt Erweitern von in Schemas definierten Features.

Erstellen von Typen zur Darstellung von Gerätefeatures

Die Eigenschaften von PrintTicket und PrintCapabilities, die den Druckerfeatures entsprechen, übernehmen bestimmte Typen. Gewöhnlich sind dies Enumerationen, die ein Feature und seine möglichen Werte darstellen.Die Collation-Enumeration ist z. B. der Typ für die PrintTicket.Collation-Eigenschaft.Dabei handelt es sich auch um den Typ der Member der Auflistung, die wiederum der Typ der PrintCapabilities.CollationCapability-Eigenschaft ist.

Erstellen Sie Klassen für die definierten und neuen Features des Geräts. Verwenden Sie dabei diese vorhandenen Klassen als Modelle.Im Codebeispiel unten wird eine BrailleGrade3-Enumeration deklariert.Sie wird für das Modell der Collation-Enumeration erstellt, weil die Übersetzung in Braille Grade 3 analog zur Sortierung stattfindet: Jeder Drucker müsste mindestens eine Art von Ausgabe (sortiert oder unsortiert) unterstützen, da sie gegenseitig alle Möglichkeiten umfassen müssen.Einige Drucker unterstützen beide Ausgaben.(Drucker, die nur die sortierte Ausgabe unterstützen, sind zwar selten, dennoch muss diese Möglichkeit berücksichtigt werden.) Entsprechend kann es also auch Braille-Drucker geben, die nur die unübersetzte Braille-Ausgabe, nur die übersetzte Ausgabe (unwahrscheinlich, aber möglich) oder beide Ausgaben unterstützen.Die BrailleGrade3-Enumeration umfasst aus demselben Grund wie Collation einen Unknown-Wert: Er dient zur Behandlung von Situationen, in denen das Sortierfeature einer Anwendung zum Erstellen von PrintTicket-Dokumenten auf einen Wert festgelegt wurde, der in der Print Schema Public Keywords-Spezifikation nicht erkannt wird.Falls die Anwendung mit einem Dokument dieses Typs ein PrintTicket-Objekt erstellt, wird die PrintTicket.Collation-Eigenschaft auf den Unknown-Wert festgelegt.(Der Unknown-Wert wird nie von PrintCapabilities-Objekten verwendet.)

public enum BrailleGrade3 { Translated, Untranslated, Unknown } 

Enumerationen sind nicht immer die beste Möglichkeit zur Darstellung eines Features.In einigen Fällen stellt eine Referenztypklasse die bessere Wahl dar.Dies trifft vor allem zu, wenn das Feature eine geschachtelte Struktur untergeordneter Teilelemente aufweist, die jeweils einen eigenen Wert besitzen.Die PageMediaSize-Klasse verfügt z. B. über die Height-Eigenschaft und die Width-Eigenschaft.PageMediaSize ist der Typ der PrintTicket.PageMediaSize-Eigenschaft.Dabei handelt es sich auch um den Typ der Member der Auflistung, die wiederum der Typ der PrintCapabilities.PageMediaSizeCapability-Eigenschaft ist.

Erweitern der PrintCapabilities-Klasse und der PrintTicket-Klasse

Obwohl die PrintTicket-Klasse und die PrintCapabilities-Klasse nicht geerbt werden können, ist durch eine entsprechende Print Schema-Erweiterung dennoch eine Erkennung definierter und neuer Features möglich.

Erweitern der PrintTicket-Klasse

Um die PrintTicket-Klasse mit dem erweiterten System von Features zu verwenden, müssen Sie die folgenden Schritte ausführen.Weiter unten finden Sie einige Details.

Abstrahierende Beschreibung der Erweiterung der PrintTicket-Klasse

  1. Wenn das Gerät neue Features besitzt, erstellen Sie eine neue Klasse, um die neuen Features zu kapseln.(Unter Vorgehensweise zum Erstellen einer NewFeaturesPrintTicket-Klasse finden Sie einige Details.)

  2. Wenn das Gerät über definierte Features verfügt, erstellen Sie eine Klasse, um die definierten Features zu kapseln.(Unter Vorgehensweise zum Erstellen einer DefinedFeaturesPrintTicket-Klasse finden Sie einige Details.)

  3. Erstellen Sie eine Klasse, um ein vollständiges Druckticket darzustellen.Diese Klasse spielt in der Anwendung die Rolle, die die PrintTicket-Klasse spielen würde, wenn das Gerät keine definierten oder neuen Features aufwiese.(Unter Vorgehensweise zum Erstellen einer WholePrintTicket-Klasse finden Sie einige Details.)

Vorgehensweise zum Erstellen einer NewFeaturesPrintTicket-Klasse

  1. Wenn das Gerät neue Features besitzt, deklarieren Sie eine Klasse, um diese Features zu kapseln.Diese Klasse wird hier NewFeaturesPrintTicket genannt.

  2. Fügen Sie der neuen Klasse Eigenschaften zur Darstellung der neuen Features des Geräts hinzu.Im Normalfall weist jede Eigenschaft den von Ihnen erstellten Typ auf, gewöhnlich eine Enumeration.Siehe weiter oben unter Erstellen von Typen zur Darstellung von Gerätefeatures.

  3. Fügen Sie der neuen Klasse eine zusätzliche Eigenschaft mit einem Verweis auf den privaten XML-Namespace hinzu, der die neuen Features des Geräts definiert. Diese Eigenschaft wird hier PrivateNamespace genannt.Sie benötigen diese Zeichenfolge beim Schreiben von XML-Markup in PrintCapabilities-Dokumenten und PrintTicket-Dokumenten.Weitere Informationen finden Sie weiter unten unter Lesen und Schreiben von PrintCapabilities-XML-Streams und PrintTicket-XML-Streams.

  4. Fügen Sie der Klasse zwei Konstruktoren hinzu.Die Konstruktoren sollten basierend auf den beiden Konstruktoren für PrintTicket erstellt werden.Ein Konstruktor übernimmt keine Parameter, der andere übernimmt ein Stream-Objekt mit XML-Inhalt.Der XML-Stream ist ein PrintTicket-Dokument, das keine allgemeinen, sondern neue Features definiert.(Siehe Print Schema-Related Technologies und PrintTicket Schema and Document Construction.) Die Konstruktoren mit dem Parameter sollten für das Muster des Konstruktors der PrintTicket-Klasse, der einen Parameter aufweist, Ausnahmen auslösen.

  5. Erstellen Sie eine GetXmlStream-Methode und eine SaveTo-Methode für die Klasse.Verwenden Sie für beide Methoden das Zugriffsschlüsselwort "internal". Sie sollen der Funktionalität der PrintTicket-Methoden dieser Namen entsprechen – mit der Ausnahme, dass sie PrintTicket-Dokumente verarbeiten, die neue Features anstelle von allgemeinen Features definieren.Durch diese Methoden muss gewährleistet werden, dass die von ihnen erstellten Streams im öffnenden <PrintTicket … >-Element über eine zusätzliche Namespacedeklaration (Wert der PrivateNamespace-Eigenschaft) verfügen.Weitere Informationen finden Sie weiter unten unter Lesen und Schreiben von PrintCapabilities-XML-Streams und PrintTicket-XML-Streams.

Vorgehensweise zum Erstellen einer DefinedFeaturesPrintTicket-Klasse

  • Wenn das Gerät definierte Features besitzt, deklarieren Sie eine Klasse, um diese neuen Features zu kapseln.Diese Klasse wird hier DefinedFeaturesPrintTicket genannt.Abgesehen von den folgenden Ausnahmen sollte sie auf dieselbe Weise erstellt werden, wie Sie weiter oben NewFeaturesPrintTicket erstellt haben.

    • Die Eigenschaften der Klasse müssen Namen haben, die mit dem entsprechenden Featurenamen in der Print Schema Public Keywords-Spezifikation übereinstimmen.

    • Erstellen Sie keine PrivateNamespace-Eigenschaft.Der Namespace für definierte Features ist mit dem für allgemeine Features identisch.Weitere Informationen finden Sie weiter unten unter Lesen und Schreiben von PrintCapabilities-XML-Streams und PrintTicket-XML-Streams.

    • Die GetXmlStream-Methode und die SaveTo-Methode erzeugen keine Streams mit zusätzlicher Namespacedeklaration.

Vorgehensweise zum Erstellen einer WholePrintTicket-Klasse

  1. Deklarieren Sie eine Klasse, die ein vollständiges Druckticket darstellt und somit in der Anwendung die Rolle spielt, die die PrintTicket-Klasse gespielt hätte, wenn das Gerät keine definierten oder neuen Features aufwiese.Diese Klasse wird hier WholePrintTicket genannt.

  2. Fügen Sie WholePrintTicket eine Eigenschaft vom Typ PrintTicket hinzu, die hier CommonFeatures genannt wird.

  3. Fügen Sie WholePrintTicket eine oder beide der folgenden zusätzlichen Eigenschaften hinzu, je nachdem, ob sie über neue, definierte oder beide Features verfügt.

    • NewFeatures vom Typ NewFeaturesPrintTicket.

    • DefinedFeatures vom Typ DefinedFeaturesPrintTicket.

  4. Fügen Sie WholePrintTicket zwei Konstruktoren hinzu:einen, der keine Parameter übernimmt, und einen, der ein Stream-Objekt mit XML-Inhalt übernimmt.Der Konstruktor mit einem Parameter führt die folgenden Aktionen aus.

    1. Er übergibt Stream an den Konstruktor für das PrintTicket-Objekt, auf das durch die CommonFeatures-Eigenschaft verwiesen wird.Dieser Konstruktor ignoriert jedes Markup in Stream, das für allgemeine Features nicht relevant ist.

    2. Er übergibt Stream an den Konstruktor des NewFeaturesPrintTicket-Objekts, auf das durch die NewFeatures-Eigenschaft verwiesen wird.Dieser Konstruktor ignoriert jedes Markup in Stream, das für neue Features nicht relevant ist.Falls Markup für neue Features vorhanden ist, beginnt Stream mit <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1" xmlns:namespace-abbreviation=full-namespace-name>, wobei full-namespace-name die URL ist, die zur Identifikation des Schemas verwendet wird, das neue Features definiert, und namespace-abbreviation die entsprechende Abkürzung ist.(Weitere Informationen finden Sie weiter unten unter Lesen und Schreiben von PrintCapabilities-XML-Streams und PrintTicket-XML-Streams.)

    3. Er übergibt Stream an den Konstruktor des DefinedFeaturesPrintTicket-Objekts, auf das durch die DefinedFeatures-Eigenschaft verwiesen wird.Dieser Konstruktor ignoriert jedes Markup in Stream, das für definierte Features nicht relevant ist.

  5. Erstellen Sie eine GetXmlStream-Methode und eine SaveTo-Methode für die Klasse.Diese sollen der Funktionalität der PrintTicket-Methoden dieser Namen entsprechen.Sie sollten die folgenden Eigenschaften aufweisen.

    • Jede dieser Methoden sollte die entsprechende Methode mit demselben Namen in den Objekten aufrufen, auf die durch die CommonFeatures-Eigenschaft, die DefinedFeatures-Eigenschaft (falls vorhanden) und die NewFeatures-Eigenschaft (falls vorhanden) verwiesen wird.

    • Jede Methode sollte die von den im vorherigen Aufzählungspunkt beschriebenen Aufrufen erzeugten Streams verketten.Alle Endtags bis auf das letzte </PrintTicket>-Endtag und alle Starttags bis auf das erste <PrintTicket … >-Starttag sollten natürlich gelöscht werden.Außer wenn keine neuen Features vorhanden sind, sollte das Starttag eine zusätzliche Namespacedeklaration aufweisen.(Siehe Schritt 4b.) Aus diesem Grund empfiehlt es sich, den Stream neuer Features (falls vorhanden) im verketteten Stream immer als ersten Stream zu definieren, da er im <PrintTicket … >-Starttag bereits über diese Deklaration verfügt.

    • Für die Verkettung müssen die GetXmlStream-Methode und die SaveTo-Methode von WholePrintTicket zunächst intern in einem temporären Stream ausgeführt werden.Insbesondere serialisieren ihre drei verschiedenen Klassen ihren Inhalt jeweils im temporären Stream, führen die Verkettungsschritte (sowie die im nächsten Aufzählungspunkt beschriebenen Bereinigungsschritte) aus und geben anschließend das Verkettungsergebnis im endgültigen Ausgabestream aus.

    • Nach der Verkettung müssen die GetXmlStream-Methode und die SaveTo-Methode von WholePrintTicket auch doppelte und dreifache Elementkopien aus dem Stream entfernen, bevor der endgültige Stream zurückgegeben wird.Diese doppelten und dreifachen Einträge im Stream sind darauf zurückzuführen, dass jedes der drei Objekte PrintTicket, NewFeaturesPrintTicket und DefinedFeaturesPrintTicket den gesamten Inhalt des ursprünglichen PrintTicket-Dokuments beibehält, mit dem es erstellt wurde, obwohl jedes Objekt in den zugehörigen Eigenschaften nur eine Teilmenge des Dokuments verfügbar macht.

    • Sie können den im vorherigen Aufzählungspunkt beschriebenen Bereinigungsschritt vermeiden, wenn der WholePrintTicket(Stream)-Konstruktor (siehe oben) den eingehenden Stream durch Erstellen separater Streams für die allgemeinen, neuen und definierten Markupelemente in drei Teile unterteilt.Jeder dieser kleineren Streams wird dann an den entsprechenden Konstruktor der drei Eigenschaften von WholePrintTicket übergeben.Bei dieser Technik müssten Sie jedem der drei Streams ein schließendes </PrintTicket>-Tag hinzufügen.Dem Stream für die CommonFeatures-Eigenschaft und die DefinedFeatures-Eigenschaft fügen Sie ein Starttag mit folgendem Format hinzu: <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">.Diesem würde das Starttag für den Konstruktor der NewFeatures-Eigenschaft einen zusätzlichen privaten Namespace mit folgendem Format hinzufügen: <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1" xmlns:namespace-abbreviation=full-namespace-name>, wobei full-namespace-name die URL ist, die zur Identifikation des Schemas verwendet wird, das neue Features definiert, und namespace-abbreviation die entsprechende Abkürzung ist.

Im folgenden Codebeispiel wird ein Teil des Ergebnisses dieser Prozedur bei Anwendung auf das Beispiel des Braille-Druckers veranschaulicht.(Aus Platzgründen und zur Vereinfachung wurde ein Großteil des Ergebnisses weggelassen.) Beachten Sie, dass es sich bei der BrailleGrade3-Eigenschaft um einen Nullable<T>-Typ handelt.Sie entspricht dem Muster der Eigenschaften von PrintTicket, z. B. Collation.Im Beispiel wird davon ausgegangen, dass sowohl neue als auch definierte Features vorhanden sind. Es werden aber keine bestimmten definierten Features angegeben.

class NewFeaturesPrintTicket
{
    public NewFeaturesPrintTicket()
    {
        // Optionally, initialize fields.For example:
        privateNamespace = "http://www.AjaxEmbossers.com/schemas/deluxemodels/v.1.0";
    }

    public NewFeaturesPrintTicket(Stream printTicketDocument)
    {
    // Parse the stream and initialize fields representing features here.// Optionally, initialize other fields.For example:
    privateNamespace = "http://www.AjaxEmbossers.com/schemas/deluxemodels/v.1.0";
    }

    private Nullable<BrailleGrade3> brailleGrade3;
    public Nullable<BrailleGrade3> BrailleGrade3
    {
        get { return brailleGrade3; }
        set { brailleGrade3 = value;}
    }

    private String privateNamespace;
    public String PrivateNamespace
    {
        get { return privateNamespace; }
        set { privateNamespace = value; }
    }
}

class DefinedFeaturesPrintTicket
{
  // Details omitted.Use the NewFeaturesPrintTicket
  // as a model, but leave out the privateNamespace field
  // and property.}

class WholePrintTicket
{
    public WholePrintTicket()
    {
        commonFeatures = new PrintTicket();
        newFeatures = new NewFeaturesPrintTicket();
        definedFeatures = new DefinedFeaturesPrintTicket();
    }

    public WholePrintTicket(Stream wholePrintTicket)
    {
         // Method 1: Pass the stream to the three constructors.// Be sure to reset the read-write position of the stream
         // to the beginning of the stream after each call to a 
         // constructor.// commonFeatures = new PrintTicket(wholePrintTicket);
              // reset read-write head here
        // newFeatures = new NewFeaturesPrintTicket(wholePrintTicket);
              // reset read-write head here
        // definedFeatures = new DefinedFeaturesPrintTicket(wholePrintTicket);
              // reset read-write head here

        // Method 2: Parse the stream and split it into three streams.// Then pass them to the constructors of the three properties.// commonFeatures = new PrintTicket(commonFeaturesPrintTicketDocument);
        // newFeatures = new NewFeaturesPrintTicket(newFeaturesPrintTicketDocument);
        // definedFeatures = new DefinedFeaturesPrintTicket(definedFeaturesPrintTicketDocument);
    }

    private PrintTicket commonFeatures;
    public PrintTicket CommonFeatures
    {
        get { return commonFeatures; }
        set { commonFeatures = value;}
    }

    private PrintTicket newFeatures;
    public PrintTicket NewFeatures
    {   // Details omitted.See CommonFeatures above.}

    private PrintTicket definedFeatures;
    public PrintTicket DefinedFeatures
    {   // Details omitted.See CommonFeatures above.}
}

Erweitern der PrintCapabilities-Klasse

Wenn Sie die PrintCapabilities-Klasse mit dem Gerät verwenden möchten, müssen Sie sie erweitern. Diese Erweiterung muss parallel zur bereits vorgenommenen Erweiterung der PrintTicket-Klasse erfolgen.Da Sie die Erweiterung von PrintTicket als Modell verwenden können, wird hier nur ein kurzer Überblick gegeben.

  • Erstellen Sie drei neue Klassen: eine zum Kapseln neuer Features (NewFeaturesPrintCapabilities), eine zum Kapseln definierter Features (DefinedFeaturesPrintCapabilities) und eine zur Darstellung eines vollständigen PrintCapabilities-Dokuments (WholePrintCapabilities).

  • Die Eigenschaften der ersten beiden neuen Klassen sind gewöhnlich vom Typ ReadOnlyCollection<T>.Verwenden Sie die vorhandenen Eigenschaften von PrintCapabilities als Modelle, z. B. CollationCapability.

  • Entsprechend dem Muster der vorhandenen PrintCapabilities-Klasse sollten die Eigenschaftennamen am Ende ebenfalls "Capability" enthalten, z. B. BrailleGrade3Capability.

  • Die NewFeaturesPrintCapabilities-Klasse verfügt über eine PrivateNamespace-Eigenschaft, die mit der für NewFeaturesPrintTicket erstellten Eigenschaft identisch ist.

  • Alle Klassen verfügen nur über die von der Object-Klasse geerbten Methoden.

  • Jede Klasse verfügt über einen einzelnen Konstruktor, der einen Stream-Parameter übernimmt.Bei Stream handelt es sich um ein PrintCapabilities-Dokument.

  • Der DefinedFeaturesPrintCapabilities-Konstruktor muss überprüfen, ob der an ihn übergebene Stream dem Print Schema Framework entspricht, bevor er mit dem Stream Eigenschaften initialisiert.(Dies lässt sich z. B. einfach erreichen, indem Stream zuerst an den PrintCapabilities-Konstruktor übergeben wird.Falls dieser keine Ausnahmen auslöst, ist der Stream gültig.)

  • Der NewFeaturesPrintCapabilities-Konstruktor muss überprüfen, ob der an ihn übergebene Stream dem privaten Namespace entspricht, bevor er mit dem Stream Eigenschaften initialisiert.

  • Sowohl der DefinedFeaturesPrintCapabilities-Konstruktor als auch der NewFeaturesPrintCapabilities-Konstruktor lösen für das Muster des bestehenden PrintCapabilities-Konstruktors Ausnahmen aus.

  • Die WholePrintCapabilities-Klasse verfügt über die CommonFeatures-Eigenschaft, die DefinedFeatures-Eigenschaft und die NewFeatures-Eigenschaft.Diese Eigenschaften sind gewöhnlich vom Typ PrintCapabilities, DefinedFeaturesPrintCapabilities bzw. NewFeaturesPrintCapabilties.Jede Eigenschaft wird für das Muster der Eigenschaften von WholePrintTicket erstellt.

  • Der Konstruktor für die WholePrintCapabilities-Klasse übernimmt einen einzelnen Stream-Parameter, der ein vollständiges PrintCapabilities-Dokument darstellt.Der Konstruktor sollte den gesamten Eingabe-Stream an alle drei Konstruktoren für die zugehörigen Membereigenschaften übergeben.Da die WholePrintCapabilities-Klasse über keine Methoden für den Export der Einstellungen im XML-Format verfügt (wie die GetXmlStream-Methode und die SaveTo-Methode von WholePrintTicket), ist es unerheblich, dass sich in den drei Eigenschaften doppeltes oder dreifaches Markup befindet.

Weitere Informationen finden Sie unter PrintCapabilities Schema and Document Construction.

Lesen und Schreiben von PrintCapabilities-XML-Streams und PrintTicket-XML-Streams

Die Konstruktoren und Methoden der bestehenden PrintTicket-Klasse und der PrintCapabilities-Klasse sowie der neuen Klassen, die Sie weiter oben im Abschnitt Erweitern der PrintCapabilities-Klasse und der PrintTicket-Klasse erstellt haben, besitzen im Wesentlichen die Funktion, Stream-Objekte mit einem PrintTicket-Dokument oder einem PrintCapabilities-Dokument als Inhalt zu lesen, zu analysieren, zu schreiben und gelegentlich auch zu überprüfen.Sie sollten mit Grundlegende Datei-E/A und den Methoden dieser Klassen vertraut sein.Da diese Streams XML-Code enthalten, sollten Sie sich auch gründlicher mit dem unter XML-Verarbeitungsoptionen in .NET Framework erläuterten Support zum Lesen und Schreiben von XML befassen.Falls die Anwendung XML Paper Specification (XPS)-Dokumente verarbeitet, enthalten der System.Windows.Xps-Namespace, der System.Windows.Xps.Packaging-Namespace und der System.Windows.Xps.Serialization-Namespace eine API zum Lesen von XPS-Dokumenten und zum Schreiben in diese Dokumente. Hierzu zählen auch das Lesen und Schreiben von PrintTicket-Elementen.Weitere Informationen zum Hinzufügen einer Beziehung zu einem PrintTicket in einem Paket finden Sie unter PackageRelationship.

Vollständige Beispiele für ein PrintTicket-Dokument und ein PrintCapabilities-Dokument finden Sie unter PrintTicket Example und PrintCapabilities Document Example.

Es folgt ein einfaches Beispiel für ein PrintCapabilities-Dokument, in dem alle bis auf ein Feature des Geräts weggelassen wurden.Bei dem dargestellten Feature handelt es sich um DocumentCollate. Dies ist das Feature, das durch die PrintCapabilities.CollationCapability-Eigenschaft und die PrintTicket.Collation-Eigenschaft dargestellt wird.

<psf:PrintCapabilities xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">

   <!-- other features omitted --> 
   
   <psf:Feature name="psk:DocumentCollate">
        <psf:Property name="psf:SelectionType">
            <psf:Value xsi:type="xsd:QName">psk:PickOne</psf:Value>
        </psf:Property>
        <psf:Property name="psk:DisplayName">
            <psf:Value xsi:type="xsd:string">Collate Copies</psf:Value>
        </psf:Property>
        <psf:Option name="psk:Collated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">Yes</psf:Value>
            </psf:Property>
        </psf:Option>
        <psf:Option name="psk:Uncollated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">No</psf:Value>
            </psf:Property>
        </psf:Option>
    </psf:Feature>
                   
   <!-- other features omitted --> 
   
</PrintCapabilities>

Beachten Sie, dass jede mögliche Option des Features (sortiert und unsortiert) aufgeführt und der Status jeder Option (d. h., ob sie eingeschränkt ist oder nicht) angegeben ist.In einem vollständigen PrintCapabilities-Dokument wird der Status jeder Option für jedes Feature angegeben. Somit stellt das Dokument eine Art Momentaufnahme der Konfiguration des Geräts dar.

Es folgt ein einfaches Beispiel für ein PrintTicket-Dokument, das nur ein einzelnes Feature aufweist.

<psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">
  
  <!-- other features omitted -->
  
  <psf:Feature name="psk:DocumentCollate">
    <psf:Option name="psk:Collated" />
  </psf:Feature>  
    
  <!-- other features omitted -->
  
</PrintTicket>

Beachten Sie, dass die Struktur etwas einfacher sein kann, weil der Status jeder Option bei einem PrintTicket-Dokument nicht explizit angegeben werden muss.Nur die angeforderte Option muss identifiziert werden.

Die Syntax und Struktur des Features werden durch das Print Schema Framework und Print Schema Public Keywords bei DocumentCollate definiert.Bei der Arbeit mit neuen Features haben Sie es mit Features zu tun, die in einem privaten XML-Namespace definiert sind, der wiederum in einem ergänzenden Schema definiert ist.Dieses wird gewöhnlich vom Hersteller des Geräts, von einer Handelsvertretung, einer Berufsorganisation oder einer gemeinnützigen Standardorganisation bereitgestellt. Sie können es aber auch selbst erstellen.Verwenden Sie das bestehende Print Schema Framework und die Print Schema Public Keywords, um die erforderliche Syntax zu erlernen und Modelle zu finden, auf denen Ihre Definitionen basieren können.Microsoft hat selbst einen neuen Namespace erstellt, um das System von PrintCapabilities und PrintTicket auf den neuen Treiber für Microsoft XPS Document Writer (MXDW) zu erweitern.Details finden Sie in MXDW-Konfigurationseinstellungen.

Angenommen, in einem erfundenen Unternehmen namens Ajax Embosser's, das Braille-Drucker herstellt, erfolgte die Definition des BrailleGrade3-Übersetzungsfeatures parallel zur Microsoft-Definition des Sortierfeatures für Dokumente. In diesem Fall wird ersichtlich, wie die Einträge des PrintCapabilities-Dokuments und des PrintTicket-Dokuments für das Feature aussähen.Beachten Sie, dass der Namespace, in dem das Feature definiert ist, im <PrintCapabilities … >-Starttag und im <PrintTicket … >-Starttag definiert sein muss.

Markup des PrintCapabilities-Dokuments

<psf:PrintCapabilities xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           xmlns:ajax="http://www.AjaxEmbossers.com/schemas/deluxemodels" version="1">

   <!-- other features omitted --> 
   
   <psf:Feature name="ajax:BrailleGrade3Translation">
        <psf:Property name="psf:SelectionType">
            <psf:Value xsi:type="xsd:QName">psk:PickOne</psf:Value>
        </psf:Property>
        <psf:Property name="psk:DisplayName">
            <psf:Value xsi:type="xsd:string">Braille3 translation</psf:Value>
        </psf:Property>
        <psf:Option name="ajax:Translated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">Yes</psf:Value>
            </psf:Property>
        </psf:Option>
        <psf:Option name="ajax:Untranslated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">No</psf:Value>
            </psf:Property>
        </psf:Option>
    </psf:Feature>
                   
   <!-- other features omitted --> 
   
</PrintCapabilities>

Markup des PrintTicket-Dokuments

<psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           xmlns:ajax="http://www.AjaxEmbossers.com/schemas/deluxemodels" version="1">
  
  <!-- other features omitted -->
  
  <psf:Feature name="ajax:BrailleGrade3Translation">
    <psf:Option name="ajax:Translated" />
  </psf:Feature>  
    
  <!-- other features omitted -->
  
</PrintTicket>

Weitere Informationen zum Schreiben von PrintTicket-Dokumenten, die neue Features verarbeiten, finden Sie unter Creating a Device-Specific PrintTicket.Eine ausführliche Dokumentation zum Erstellen von PrintTicket-Dokumenten und PrintCapabilities-Dokumenten finden Sie in den Abschnitten PrintCapabilities Schema and Document Construction und PrintTicket Schema and Document Construction der Dokumentation zum Druckschema.

Überladen und Erweitern von Eigenschaften und Methoden

Jede Methode einer beliebigen Klasse, die entweder einen PrintTicket-Parameter übernimmt oder ein PrintTicket zurückgibt und die Sie mit Ihrem System erweiterter Features verwenden möchten, muss durch eine Methode ersetzt werden, die WholePrintTicket anstelle von PrintTicket verwendet.Ähnlich müssen sämtliche Eigenschaften vom Typ PrintTicket, die Sie verwenden möchten, durch Eigenschaften vom Typ WholePrintTicket ersetzt werden.Dies gilt mit den entsprechenden Änderungen auch für PrintCapabilities und WholePrintCapabilities.

Wenn die Klasse, die die Methode oder Eigenschaft hostet, vererbbar ist, können Sie eine Klasse ableiten und die Methode oder Eigenschaft überladen, sodass sie WholePrintTicket anstelle von PrintTicket verwendet.

Falls die Hostingklasse nicht vererbbar ist, müssen Sie sie genau so erweitern, wie Sie oben PrintTicket und PrintCapabilities erweitert haben: Sie erstellen eine Klasse mit der Hostingklasse als Member.Fügen Sie der äußeren Klasse dann Methoden und Eigenschaften mit den Namen der entsprechenden Methoden zu, die über den PrintTicket-Parameter oder den PrintCapabilities-Parameter verfügen (bzw. diesen zurückgeben).In der Regel sollte die äußere Klasse im Hinblick auf die Funktionalität mit der inneren Klasse desselben Namens übereinstimmen. Allerdings verwendet sie den WholePrintTicket-Parameter bzw. den WholePrintCapabilities-Parameter anstelle des PrintTicket-Parameters oder des PrintCapabilities-Parameters.Erstellen Sie auch für Eigenschaften der inneren Klasse, die vom Typ PrintTicket oder PrintCapabilities sind, eine übereinstimmende Eigenschaft mit demselben Namen in der äußeren Klasse, die WholePrintTicket oder WholePrintCapabilities verwendet.

Die wichtigsten Methoden, die Sie zum Überladen benötigen, sind wahrscheinlich die beiden Versionen von MergeAndValidatePrintTicket. Für die BrailleEmbosser-Klasse (siehe Ableiten einer neuen Klasse durch Vererbung weiter oben) sind Ersetzungen erforderlich, bei denen WholePrintTicket-Parameter verwendet werden und Logik hinzugefügt wird, durch die Tickets mit neuen Features anhand des Schemas des privaten Namespaces überprüft werden.Sie können entweder die vorhandenen Methoden überladen oder neue Methoden mit dem Namen MergeAndValidateWholePrintTicket erstellen.

ConvertDevModeToPrintTicket und Clone sind zwei Methoden, die PrintTicket zurückgeben.In .NET Framework sind 15 weitere Methoden vorhanden (ohne Berücksichtigung von Überladungen), die einen PrintTicket-Parameter übernehmen, darüber hinaus 19 Eigenschaften vom Typ PrintTicket.Es ist jedoch nicht wahrscheinlich, dass eine bestimmte Anwendung mehr als eine kleine Anzahl davon verwendet. Daher ist die Arbeitslast geringer, als diese Zahlen auf den ersten Blick vermuten lassen.Glücklicherweise ist GetPrintCapabilities die einzige Methode, die ein PrintCapabilities-Objekt zurückgibt, und es sind keine Eigenschaften vom Typ PrintCapabilities vorhanden.

Erweitern von in Schemas definierten Features

Völlig neue Features stellen nicht die einzige Situation dar, in der eine Print Schema-Erweiterung notwendig werden könnte.Es ist auch möglich, dass ein Gerät neue, nicht definierte Optionen für ein bekanntes, definiertes Feature bietet.Da für die neuen undefinierten Optionen ebenso wie für ein völlig neues Feature ein privater Namespace verwendet werden muss, ist es wahrscheinlich einfacher, diese erweiterten Features wie völlig neue Features zu behandeln (dabei aber im Schema definierte Namen für das Feature und diejenigen Optionen zu verwenden, die bereits definiert sind): Nehmen Sie sie in NewFeaturesPrintTicket und NewFeaturesPrintCapabilities auf.Die Erläuterung aller Details, die für die Implementierung einer Schemaerweiterung dieser Art erforderlich sind, würde über den Rahmen dieses Artikels hinausgehen. Beachten Sie aber, dass die Verkettungsschritte, die von der WholePrintTicket.GetXmlStream-Methode und der WholePrintTicket.SaveAs-Methode durchgeführt werden müssen, etwas komplizierter werden müssten.

Erweitern des System.Printing.IndexedProperties-Namespaces

Wenn Sie die Vorteile der APIs im System.Printing.IndexedProperties-Namespace nutzen möchten, müssen Sie u. U. eine neue Klasse von PrintProperty ableiten.Dies wäre erforderlich, wenn eine Eigenschaft, die Sie für die Klasse erstellt haben, die Sie von PrintQueue abgeleitet haben, einen Typ aufweist, der von keiner der vorhandenen Klassen in System.Printing.IndexedProperties dargestellt wird.Beispiele für die Aktionen, die mit dem System.Printing.IndexedProperties-Namespace durchgeführt werden können, finden Sie unter Gewusst wie: Klonen eines Druckers und Gewusst wie: Abrufen von Drucksystemobjekt-Eigenschaften ohne Reflektion.

Für das Beispiel oben ist dies nicht nötig, weil der BrailleEmbosser-Klasse als einzige Eigenschaft IsBraile3Enabled hinzugefügt wurde. Sie ist vom Typ Boolean.Es ist bereits eine System.Printing.IndexedProperties.PrintBooleanProperty-Klasse vorhanden.

Siehe auch

Aufgaben

Gewusst wie: Klonen eines Druckers

Gewusst wie: Abrufen von Drucksystemobjekt-Eigenschaften ohne Reflektion

Referenz

System.Printing

System.Printing.IndexedProperties

System.Printing.Interop

System.Windows.Xps

System.Windows.Xps.Packaging

System.Windows.Xps.Serialization

GetPrintCapabilities

PackageRelationship

PrintCapabilities

PrintQueue

PrintSystemObject

PrintTicket

MXDW-Konfigurationseinstellungen

Konzepte

XML-Verarbeitungsoptionen in .NET Framework

Dokumente in WPF

Übersicht über das Drucken

Weitere Ressourcen

Print Schema

Druckschema-Framework

Erstellen eines gerätespezifischen PrintTicket

Druckschemabezogene Technologien

PrintTicket-Schema und Dokumentaufbau

PrintTicket-Beispiel

Beispiel für PrintCapabilities-Dokument

PrintCapabilities-Schema und Dokumentaufbau

Öffentliche Schlüsselwörter für Druckschema

Microsoft XPS-Dokument-Generator