更新 : 2007 年 11 月
既存の PrintSystemObject、PrintQueue, PrintCapabilities、PrintTicket の各クラスでは表現できない特性を持つ専門的な印刷デバイスをアプリケーションで扱う必要がある場合は、継承によって新しいクラスを派生し、PrintCapabilities クラスと PrintTicket クラスの拡張バージョンを作成できます。また、Print Schemaを拡張することもできます。ここでは、そのようなプロジェクトの主要部分について説明します。関連するマネージ クラスを拡張する方法は多数ありますが、そのうちの 1 つを説明します。
この記事と併せて、Print Schemaに関して広範に記述されたドキュメントも参照することをお勧めします。この記事では、スキーマ、PrintTicket ドキュメント、および PrintCapabilities ドキュメントに関して、少なくとも基礎的な知識があることを前提にしています。
この記事は、次のセクションで構成されています。
継承によって新しいクラスを派生させる
デバイスの機能が印刷スキーマに既に定義されているかどうかを確認する
デバイスの機能を表す型を作成する
PrintCapabilities クラスと PrintTicket クラスの拡張
PrintTicket クラスの拡張
PrintCapabilities クラスの拡張
PrintCapabilities と PrintTicket の XML ストリームの読み取りと書き込み
プロパティとメソッドのオーバーロードと拡張
スキーマで定義された機能の拡張
System.Printing.IndexedProperties 名前空間の拡張
使用例
ここに示すプロジェクト例では、アプリケーションをコンパイルして実行するために必要な詳細のすべては説明しません。これは、System.Printing 名前空間および System.Printing.IndexedProperties 名前空間で明示的にサポートされていない機能を持つ印刷デバイスに関して、これらの名前空間を拡張するために必要な手順の概要のみを提示するものです。コード例は、具体的な説明が必要な場合にのみ示します。
また、コード例には、優れたプログラミング方法やセキュリティで保護されたコードに関する手法が含まれているとは限りません。記事の主題に直接関係のない事項は、省略されています。
最後に、この記事は、デバイス ドライバの開発者ではなくアプリケーションの開発者を主な対象としています。そのため、PrintCapabilities オブジェクトよりも PrintTicket オブジェクトの記述に重点を置いています。
継承によって新しいクラスを派生させる
最初に、デバイスを表すクラスを PrintQueue クラスから派生させます。次のコード例では、BrailleEmbosser クラスを派生させます。Braille (点字) は、視覚障害者が判読できる言語です。その記号は紙面上に隆起した複数の "点" から成り、指先で読み取ることができます。Braille embosser (Braille エンボス加工装置) とは、Braille を印刷するプリンタと言えます。Braille embosser 用の一部のドライバは、標準 Braille を Braille Grade 3 (Braille 3 とも呼ばれる) に変換できます。Braille Grade 3 は Braille の省スペース バージョンで、短縮や省略を多用します。例では、この機能を表すプロパティを提供します。
多くの場合、継承されたプロパティやメソッドの一部をオーバーロードする必要も生じます。詳細については、後の「プロパティとメソッドのオーバーロードと拡張」を参照してください。
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
}
デバイスの機能が印刷スキーマに既に定義されているかどうかを確認する
PrintTicket クラスおよび PrintCapabilities クラスには、ごく一般的なプリンタ機能を表すプロパティがありますが、Print Schema Public Keywordsの仕様には、これらのクラスには明示的に反映されない多くの機能が定義されています (一般的な機能の一覧については、PrintCapabilities クラスのプロパティを参照してください)。この仕様を読んで、デバイスの特別な機能が仕様内に定義されているかどうかを確認する必要があります。機能が仕様内に含まれていた場合、仕様のモデルを使用できることは大きな利点です。共通のモデルと用語の使用により、あるデバイス用に作成した PrintTicket XML ドキュメントを別のデバイスで使用することができます (2 番目のデバイスは、製造元が異なっていても、PrintTicket ドキュメントが最初に作成された後に設計されたものであってもかまいません)。さまざまなプリンタを使用するユーザーにドキュメントを配布するときは、印刷と書式設定に関する作成者の意図を実現できるように、印刷チケットをドキュメント自体に埋め込むことができます。
以降では、PrintTicket クラスと PrintCapabilities クラスで明示的にサポートされている機能を "一般機能" と呼びます。Print Schema Public Keywordsの仕様に定義されていても、これら 2 つのクラスで明示的にサポートされていない機能は、"定義された機能" と呼びます。パブリック キーワードの仕様に定義されていない機能は、"新しい機能" と呼びます。
デバイスの機能が、定義された機能のいずれかにほぼ完全一致するものの、Print Schema Public Keywordsの仕様で認識されないオプションが 1 つ以上存在する場合もあります。Print Schemaを拡張すると、既存の定義をできるだけ利用する形で、そのような機能を処理することができます。そのような機能の処理方法の詳細については、後の「スキーマで定義された機能の拡張」を参照してください。
デバイスの機能を表す型を作成する
プリンタ機能に対応する PrintTicket および PrintCapabilities のプロパティは、特別な型を取ります。通常は、機能とそれに使用可能な値を表す列挙体です。たとえば Collation 列挙体は PrintTicket.Collation プロパティ用の型です。これは、PrintCapabilities.CollationCapability プロパティの型であるコレクションのメンバの型でもあります。
これらの既存のクラスをモデルとして使用することにより、デバイスの定義された機能と新しい機能に対してクラスを作成します。次のコード例では、BrailleGrade3 列挙型を宣言しています。Grade 3 変換は部単位印刷に似ているため、Collation 列挙体をモデルとして構築します。どのプリンタも最低 1 種類の印刷 (部単位での印刷または部単位でない印刷) をサポートする必要があります。すべての印刷は、この 2 種類のいずれかであるためです。プリンタによっては両方をサポートします (部単位での印刷だけをサポートするプリンタはまれですが、可能性として考慮する必要があります)。同様に、エンボス加工装置にも、変換されない Braille 出力だけをサポートするもの、変換された出力だけをサポートするもの (可能性は小さいながらもあり得る)、または両方をサポートするものがあります。BrailleGrade3 列挙体に Unknown 値を含めるのは、Collation の場合と同じ理由からです。つまり、PrintTicket ドキュメント生成アプリケーションによって設定された部単位印刷機能の値が、Print Schema Public Keywordsの仕様で認識されない値である状況に対応するためです。アプリケーションでそのようなドキュメントを使用して PrintTicket オブジェクトが作成された場合、PrintTicket.Collation プロパティは値 Unknown を受け取ります (PrintCapabilities オブジェクトによって Unknown 値が使用されることはありません)。
public enum BrailleGrade3 { Translated, Untranslated, Unknown }
機能を表す方法として、常に列挙が最適であるとは限りません。参照型クラスの方が適切な場合もあります。これは特に、下位部分が入れ子になった構造を持つ機能で、下位部分がそれぞれ独自の値を持つ場合に当てはまります。たとえば、PageMediaSize クラスには Height と Width のプロパティがあります。PageMediaSize は PrintTicket.PageMediaSize プロパティの型です。PrintCapabilities.PageMediaSizeCapability プロパティの型であるコレクションのメンバの型でもあります。
PrintCapabilities クラスと PrintTicket クラスの拡張
PrintTicket クラスと PrintCapabilities クラスは継承できませんが、Print Schemaを拡張して、定義された機能と新しい機能を認識することができます。
PrintTicket クラスの拡張
拡張された機能システムで PrintTicket クラスを使用するには、次の手順に従います。詳細は次のとおりです。
PrintTicket クラスを拡張する手順の概略
新しい機能がデバイスにある場合は、その機能をカプセル化する新しいクラスを作成します (詳細については、「NewFeaturesPrintTicket クラスを作成する」を参照)。
定義された機能がデバイスにある場合は、その機能をカプセル化するクラスを作成します (詳細については、「DefinedFeaturesPrintTicket クラスを作成する」を参照)。
印刷チケット全体を表すクラスを作成します。このクラスがアプリケーションで果たす役割は、定義された機能も新しい機能も持たないデバイスの場合に PrintTicket クラスが果たす役割と同じです (詳細については、「WholePrintTicket クラスを作成する」を参照)。
NewFeaturesPrintTicket クラスを作成する手順
新しい機能がデバイスにある場合は、その機能をカプセル化するクラスを宣言します。これを NewFeaturesPrintTicket と呼ぶことにします。
新しいクラスに、デバイスの新しい機能を表すプロパティを与えます。通常、各プロパティの型はここで作成する型で、一般的には列挙体です。上記の「デバイスの機能を表す型を作成する」を参照してください。
新しいクラスに、追加のプロパティを与えます。これを PrivateNamespace と呼ぶことにします。これは、デバイスの新しい機能を定義するプライベート XML 名前空間への参照を保持します。この文字列は、PrintCapabilities ドキュメントと PrintTicket ドキュメントに XML マークアップを記述するときに必要です。後の「PrintCapabilities と PrintTicket の XML ストリームの読み取りと書き込み」を参照してください。
クラスに、2 つのコンストラクタを与えます。これらのコンストラクタは、PrintTicket の 2 つのコンストラクタに基づく必要があります。1 つはパラメータを取らず、もう 1 つは XML コンテンツを持つ Stream オブジェクトを取ります。XML ストリームが、一般機能ではなく新しい機能を定義する PrintTicket ドキュメントとなります (「Print Schema-Related Technologies」および「PrintTicket Schema and Document Construction」を参照してください)。このパラメータを持つコンストラクタは、PrintTicket クラスの 1 つのパラメータのコンストラクタのパターンで例外をスローする必要があります。
GetXmlStream および SaveTo メソッドをクラスに作成します。両方に対してアクセス キーワード "internal" を使用します。これらは、同名の PrintTicket メソッドの機能と一致するように意図されていますが、一般機能ではなく新しい機能を定義する PrintTicket ドキュメントを処理する点が異なります。これらのメソッドでは、生成するストリームの <PrintTicket c > 要素の開始部分に、追加の名前空間宣言 (PrivateNamespace プロパティの値) を含める必要があります。後の「PrintCapabilities と PrintTicket の XML ストリームの読み取りと書き込み」を参照してください。
DefinedFeaturesPrintTicket クラスを作成する手順
定義された機能がデバイスにある場合は、その機能をカプセル化するクラスを宣言します。これを DefinedFeaturesPrintTicket と呼ぶことにします。上記の NewFeaturesPrintTicket の場合とほぼ同様に構築しますが、次の点が異なります。
クラスのプロパティの名前は、Print Schema Public Keywordsの仕様内の対応する機能名と一致する必要があります。
PrivateNamespace プロパティは作成しません。定義された機能の名前空間は、一般機能の場合と同じです。後の「PrintCapabilities と PrintTicket の XML ストリームの読み取りと書き込み」を参照してください。
GetXmlStream メソッドと SaveTo メソッドは、追加の名前空間宣言が含まれるストリームを生成しません。
WholePrintTicket クラスを作成する手順
印刷チケット全体を表すクラスを宣言します。このクラスがアプリケーションで果たす役割は、定義された機能も新しい機能も持たないデバイスの場合に PrintTicket クラスが果たす役割と同じです。これを WholePrintTicket と呼ぶことにします。
WholePrintTicket に、PrintTicket 型のプロパティを与えます。これを CommonFeatures と呼ぶことにします。
新しい機能を持つか、定義された機能を持つか、またはその両方を持つかに応じて、WholePrintTicket に次の追加プロパティのいずれか、または両方を与えます。
NewFeaturesPrintTicket 型の NewFeatures。
DefinedFeaturesPrintTicket 型の DefinedFeatures。
WholePrintTicket に、2 つのコンストラクタを与えます。1 つはパラメータを取らず、もう 1 つは XML コンテンツを持つ Stream オブジェクトを取ります。パラメータを取るコンストラクタは、次の処理を行います。
CommonFeatures プロパティによって参照される PrintTicket オブジェクトのコンストラクタに Stream を渡します。そのコンストラクタは、一般機能に無関係な Stream 内のマークアップは無視します。
NewFeatures プロパティによって参照される NewFeaturesPrintTicket オブジェクトのコンストラクタに Stream を渡します。そのコンストラクタは、新しい機能に無関係な Stream 内のマークアップは無視します。新しい機能のマークアップがある場合、Stream は <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> で始まります。ここで、full-namespace-name は新しい機能を定義するスキーマの識別に使用される URL、namespace-abbreviation はその省略形です (詳細については、後の「PrintCapabilities と PrintTicket の XML ストリームの読み取りと書き込み」を参照してください)。
DefinedFeatures プロパティによって参照される DefinedFeaturesPrintTicket オブジェクトのコンストラクタに Stream を渡します。そのコンストラクタは、定義された機能に無関係な Stream 内のマークアップは無視します。
GetXmlStream および SaveTo メソッドをクラスに作成します。これらは、同名の PrintTicket メソッドの機能と一致するように意図されています。次の特性を持つ必要があります。
各メソッドは、CommonFeatures プロパティ、DefinedFeatures プロパティ (存在する場合)、および NewFeatures プロパティ (存在する場合) によって参照されるオブジェクトにおいて、対応する同名のメソッドを呼び出す必要があります。
各メソッドは、前項に示した呼び出しによって生成される複数のストリームを連結する必要があります。その際、最後の 1 つ以外の </PrintTicket> 終了タグと、最初の 1 つ以外の <PrintTicket c > 開始タグは、削除する必要があります。新しい機能がまったくない場合を除いて、開始タグには追加の名前空間宣言が必要です (手順 4b. を参照)。この理由から、新しい機能のストリームが存在する場合は、連結されるストリームの先頭に常に配置するように考慮してください。このストリームの <PrintTicket … > 開始タグには、必要な宣言が既に含まれているためです。
連結を行うために、WholePrintTicket の GetXmlStream メソッドと SaveTo メソッドは、最初に、内部で一時的なストリームを処理する必要があります。具体的には、コンテンツを一時的なストリームにシリアル化する 3 つの異なるクラスを持ち、連結作業 (および余分なものを取り除く作業。次項を参照) を行った後、連結結果を最終的な出力ストリームに出力します。
連結後、最終的なストリームを返す前に、WholePrintTicket の GetXmlStream メソッドと SaveTo メソッドは、二重または三重に重複した要素コピーをストリームから削除する必要もあります。これらの二重または三重の重複エントリがストリームに存在するのは、PrintTicket、NewFeaturesPrintTicket、および DefinedFeaturesPrintTicket の 3 つのオブジェクトのそれぞれが、構築に使用された元の PrintTicket ドキュメント全体を保持するためです。ただし、各オブジェクトは、プロパティではドキュメントの一部しか公開しません。
WholePrintTicket(Stream) コンストラクタ (上記参照) が受信ストリームを 3 つの部分に分割して、一般マークアップ要素用、新しいマークアップ要素用、および定義されたマークアップ要素用に個別のストリームを作成する場合は、前項に示した重複を削除する手順を回避できます。これらの分割されたストリームは、WholePrintTicket の 3 つのプロパティの適切なコンストラクタに渡されます。この方法では、3 つのストリームのそれぞれに </PrintTicket> 終了タグを追加する必要があります。CommonFeatures プロパティと DefinedFeatures プロパティのストリームには、<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"> のように開始タグを追加します。NewFeatures プロパティのコンストラクタ用の開始タグには、これに加えて、<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> のようにプライベート名前空間を追加します。ここで、full-namespace-name は新しい機能を定義するスキーマの識別に使用される URL、namespace-abbreviation はその省略形です。
この手順を Braille embosser の例に適用した場合の結果の一部を、次のコード例に示します (スペースを節約して簡単に説明するために、多くの部分が省略されています)。BrailleGrade3 プロパティは Nullable<T> 型です。これは、PrintTicket のプロパティ (Collation など) のパターンに従います。この例は、新しい機能と定義された機能の両方が存在することを前提としています。ただし、特定の定義された機能を示してはいません。
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.}
}
PrintCapabilities クラスの拡張
デバイスで PrintCapabilities クラスを使用するには、PrintTicket クラスの場合と同様の方法で拡張する必要があります。PrintTicket の拡張をモデルとして使用できるため、ここでは概要のみを簡単に説明します。
新しいクラスを 3 つ作成します。新しい機能をカプセル化するクラス (NewFeaturesPrintCapabilities)、定義された機能をカプセル化するクラス (DefinedFeaturesPrintCapabilities)、および PrintCapabilities ドキュメント全体を表すクラス (WholePrintCapabilities) です。
最初の 2 つの新しいクラスでは、プロパティの型は通常 ReadOnlyCollection<T> です。CollationCapability など、PrintCapabilities の既存のプロパティをモデルとして使用します。
既存の PrintCapabilities クラスのパターンに従って、プロパティ名の最後に "Capability" を付ける必要があります (BrailleGrade3Capability など)。
NewFeaturesPrintCapabilities クラスは、NewFeaturesPrintTicket 用に作成したものと同じ PrivateNamespace プロパティを持つことになります。
どのクラスも、Object クラスから継承するメソッド以外のメソッドを持つことはありません。
各クラスは、Stream パラメータを取る単一のコンストラクタを持つことになります。Stream は PrintCapabilities ドキュメントです。
DefinedFeaturesPrintCapabilities コンストラクタでは、渡された Stream を使用してプロパティを初期化する前に、Stream がPrint Schema Frameworkに準拠していることを検証する必要があります。(これを簡単に行う 1 つの方法は、最初に Stream をPrintCapabilities コンストラクタに渡すことです。後者が例外をスローしなければ、ストリームは有効です)。
NewFeaturesPrintCapabilities コンストラクタでは、渡された Stream を使用してプロパティを初期化する前に、Stream がプライベート名前空間に準拠することを検証する必要があります。
DefinedFeaturesPrintCapabilities コンストラクタと NewFeaturesPrintCapabilities コンストラクタのどちらも、既存の PrintCapabilities コンストラクタのパターンに基づいて例外をスローします。
WholePrintCapabilities クラスは、CommonFeatures、DefinedFeatures、NewFeatures の各プロパティを持つことになります。これらのプロパティの型は、それぞれ PrintCapabilities、DefinedFeaturesPrintCapabilities、および NewFeaturesPrintCapabilties です。いずれも、 WholePrintTicket のプロパティのパターンに基づいて構築されます。
WholePrintCapabilities クラスのコンストラクタは、PrintCapabilities ドキュメント全体を表す単一の Stream パラメータを取ります。このコンストラクタは、そのメンバ プロパティの 3 つのコンストラクタすべてに対して、入力 Stream 全体を渡す必要があります。WholePrintCapabilities クラスは、設定を XML 形式でエクスポートするメソッド (WholePrintTicket の GetXmlStream や SaveTo などのメソッド) を持たないため、3 つのプロパティ内に二重または三重の重複マークアップが存在しても問題ありません。
詳細については、「PrintCapabilities Schema and Document Construction」を参照してください。
PrintCapabilities と PrintTicket の XML ストリームの読み取りと書き込み
既存の PrintTicket クラスと PrintCapabilities クラス、および前の「PrintCapabilities クラスと PrintTicket クラスの拡張」で作成した新しいクラスでは、コンストラクタとメソッドの主な機能は、PrintTicket ドキュメントまたは PrintCapabilities ドキュメントをコンテンツとする Stream オブジェクトの読み取り、解析、および書き込みと、場合によっては検証を行うことです。開発者は、基本のファイル I/O と、これらのクラスのメソッドに精通している必要があります。これらのストリームのコンテンツは XML であるため、「.NET Framework における XML 処理オプション」で説明している XML の読み取りと書き込みのサポートについても精通している必要があります。アプリケーションが XML Paper Specification (XPS) ドキュメントを使用する場合は、PrintTicket の読み書きを含む XPS ドキュメントの読み書き用に設計された System.Windows.Xps、System.Windows.Xps.Packaging、System.Windows.Xps.Serialization の各名前空間には、API があります。PrintTicket へのリレーションシップをパッケージに追加することについては、PackageRelationship も参照してください。
PrintTicket ドキュメントと PrintCapabilities ドキュメントのサンプル全体については、「PrintTicket Example」および「PrintCapabilities Document Example」を参照してください。
1 つだけを残してデバイスの機能を省略した、PrintCapabilities ドキュメントの簡単な例を次に示します。示されている機能は、PrintCapabilities.CollationCapability プロパティと PrintTicket.Collation プロパティによって表される DocumentCollate 機能です。
<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>
この機能で使用可能なすべてのオプションが示され (部単位での印刷と部単位でない印刷の両方)、それぞれの状態 (制約を受けるか受けないか) が識別されています。完全な PrintCapabilities ドキュメントでは、すべての機能のすべてのオプションの状態が識別されます。したがって、このドキュメントはデバイス構成のスナップショットのようなものと言えます。
1 つの機能だけを持つ PrintTicket ドキュメントの単純な例を次に示します。
<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>
PrintTicket ドキュメントでは各オプションの状態を明示的に指定する必要がないため、構造を多少単純にできます。識別する必要があるのは、要求されたオプションだけです。
機能の構文と構造は、Print Schema FrameworkおよびPrint Schema Public Keywordsによって、DocumentCollate に定義されています。新しい機能を使用する場合は、追加のスキーマに定義されたプライベート XML 名前空間で定義されている機能を使用することになります。通常これは、デバイスの製造元、業界団体、または非営利の標準化機構から提供されますが、自分で作成する場合もあります。既存のPrint Schema FrameworkとPrint Schema Public Keywordsを使用すると、必要な構文を理解したり、独自の定義の基となるモデルを見つけたりできます。Microsoft では、PrintCapabilities と PrintTicket のシステムを新しい Microsoft XPS Document Writer (MXDW) ドライバに拡張するために、新しい名前空間を作成しました。詳細については、「MXDW の構成設定」を参照してください。
Microsoft によるドキュメントの部単位印刷機能の定義と似た方法で、架空の Ajax Embosser の会社が BrailleGrade3 変換機能を定義したと仮定すると、PrintCapabilities ドキュメントと PrintTicket ドキュメントにおけるその機能のエントリは、次のようになります。機能が定義されている名前空間は、<PrintCapabilities … > と <PrintTicket … > の各開始タグ内で宣言する必要があります。
PrintCapabilities ドキュメント マークアップ
<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>
PrintTicket ドキュメント マークアップ
<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>
新しい機能を処理する PrintTicket ドキュメントを記述する方法の詳細については、「Creating a Device-Specific PrintTicket」を参照してください。PrintTicket ドキュメントと PrintCapabilities ドキュメントを作成する方法の詳細については、印刷スキーマのドキュメントの「PrintCapabilities Schema and Document Construction」および「PrintTicket Schema and Document Construction」を参照してください。
プロパティとメソッドのオーバーロードと拡張
あるクラスのメソッドが PrintTicket パラメータを取るか PrintTicket を返す場合、それを独自の拡張機能システムで使用するには、PrintTicket の代わりに WholePrintTicket を使用するメソッドでそのメソッドを置き換える必要があります。同様に、PrintTicket 型のプロパティを使用する場合は、WholePrintTicket 型のプロパティに置き換える必要があります。PrintCapabilities と WholePrintCapabilities に関しても、必要な点を読み替えた上で同じことが言えます。
メソッドやプロパティをホストするクラスが継承可能な場合は、クラスを派生させてから、PrintTicket の代わりに WholePrintTicket を使用するようにメソッドやプロパティをオーバーロードできます。
ホストするクラスが継承可能でない場合は、上記の PrintTicket および PrintCapabilities の場合と同じ方法で拡張する必要があります。つまり、ホストするクラスをメンバとして持つクラスを作成します。次に、外部クラスのメソッドとプロパティに対して、PrintTicket または PrintCapabilities のパラメータを持つ (または返す) 対応するメソッドと同じ名前を与えます。通常、外部クラスは、同名の内部クラスと同じ機能を持つ必要がありますが、PrintTicket または PrintCapabilities パラメータの代わりに、WholePrintTicket または WholePrintCapabilities パラメータを使用します。また、PrintTicket または PrintCapabilities 型の内部クラスのプロパティについては、WholePrintTicket または WholePrintCapabilities を使用する同名のプロパティを外部クラス内に作成します。
オーバーロードを必要とする特に重要なメソッドは、MergeAndValidatePrintTicket の 2 つのバージョンです。BrailleEmbosser クラス (上記の「継承によって新しいクラスを派生させる」を参照) は、WholePrintTicket パラメータを使用するクラス、および新しい機能を持つチケットをプライベート名前空間のスキーマに対して検証するロジックを追加するクラスへの置き換えが必要です。既存のメソッドをオーバーロードすることも、MergeAndValidateWholePrintTicket という名前の新しいメソッドを作成することもできます。
PrintTicket を返す 2 つのメソッドは、ConvertDevModeToPrintTicket と Clone です。.NET Framework には、PrintTicket パラメータを取るメソッドが他に 15 個 (オーバーロードは含まない) あり、PrintTicket 型のプロパティは 19 個あります。しかし、ほとんどの場合、特定のアプリケーションで使用されるのはこれらのうちの少数にすぎないため、作業負荷はその数から想像するほど大きくありません。また、PrintCapabilities オブジェクトを返すメソッドは GetPrintCapabilities だけであり、PrintCapabilities 型のプロパティは存在しません。
スキーマで定義された機能の拡張
Print Schemaを拡張する必要が生じる可能性があるのは、まったく新しい機能を使用する場合だけではありません。デバイスの使い慣れている定義された機能に、新しい未定義のオプションが提供されることもあります。新しい未定義のオプションに対しても、完全に新しい機能の場合と同様にプライベート名前空間を使用する必要があるため、そのような拡張機能も、完全に新しい機能の場合と同様に扱う方が通常は簡単です (ただし、機能とその定義済みのオプションには、スキーマで定義されている名前を使用します)。つまり、それらを NewFeaturesPrintTicket と NewFeaturesPrintCapabilities に格納します。この種のスキーマ拡張の実装に必要なすべての詳細をここで説明することはしませんが、WholePrintTicket.GetXmlStream メソッドと WholePrintTicket.SaveAs メソッドで行う必要がある連結作業が多少複雑になることに注意してください。
System.Printing.IndexedProperties 名前空間の拡張
System.Printing.IndexedProperties 名前空間内の API を利用する場合は、PrintProperty から新しいクラスを派生させる必要が生じることがあります。これが必要になるのは、PrintQueue から派生させたクラス用に作成したプロパティに、System.Printing.IndexedProperties の既存のクラスによって表されない型がある場合です。System.Printing.IndexedProperties 名前空間で可能な操作の例については、「方法 : プリンタを複製する」および「方法 : リフレクションを使用せずに印刷システム オブジェクトのプロパティを取得する」を参照してください。
これは上記の例では不要です。BrailleEmbosser クラスに追加したプロパティが、Boolean の IsBraile3Enabled のみであるためです。System.Printing.IndexedProperties.PrintBooleanProperty クラスが既に存在します。
参照
処理手順
方法 : リフレクションを使用せずに印刷システム オブジェクトのプロパティを取得する
概念
.NET Framework における XML 処理オプション
Windows Presentation Foundation のドキュメント
参照
System.Printing.IndexedProperties
System.Windows.Xps.Serialization