印刷の概要

Microsoft .NET Framework では、Windows Presentation Foundation (WPF) を使用しているアプリケーション開発者は、充実した新しい印刷機能と印刷システム管理の APIs 群を使用できます。 Windows Vista では、これらの印刷システムの拡張機能の一部を、Windows Forms アプリケーションを作成している開発者、およびアンマネージ コードを使用している開発者も使用できます。 この新しい機能の中核となるのは、新しい XML Paper Specification (XPS) ファイル形式と XPS 印刷パスです。

このトピックは、次のセクションで構成されています。

  • XPS について

  • XPS 印刷パス

  • GDI 印刷パス

  • XPSDrv ドライバー モデル

  • 関連トピック

XPS について

XPS は、電子ドキュメント形式、スプール ファイル形式、およびページ記述言語です。 これは、XML、Open Packaging Conventions (OPC)、およびその他の業界標準を使用してクロス プラットフォーム ドキュメントを作成する、オープンなドキュメント形式です。 XPS は、デジタル ドキュメントの作成、共有、印刷、表示、およびアーカイブ時のプロセスを簡略化します。 XPS の詳細については、XPS Web サイト を参照してください。

WPF を使用して XPS ベースのコンテンツを印刷するためのいくつかの手法は、「方法 : XPS ファイルをプログラムにより印刷する」に示されています。 このトピックの解説内容を確認する過程で、これらのサンプルを参照すると役立つ場合があります (アンマネージ コードの開発者は、Microsoft XPS Document Converter プリンター エスケープのヘルプを参照してください。 Windows Formsの開発者は、System.Drawing.Printing 名前空間の API を使用する必要があります。この名前空間は XPS 印刷パスはサポートしませんが、ハイブリッドな GDI から XPS への印刷パスはサポートしています。 下記の「印刷パス アーキテクチャ」を参照してください)。

XPS 印刷パス

XML Paper Specification (XPS) 印刷パスは、Windows アプリケーションにおける印刷の処理方法を再定義する新しい Windows の機能です。 XPS はドキュメント表示言語 (RTF など)、印刷スプーラー形式 (WMF など)、およびページ記述言語 (PCL や Postscript など) を置き換えることができるため、新しい印刷パスは、アプリケーションの発行から印刷ドライバーまたはデバイスでの最終処理まで XPS 形式を維持します。

XPS 印刷パスは、XPS プリンター ドライバー モデル (XPSDrv) に基づいて構築されます。これによって、"what you see is what you get" (WYSIWYG) 印刷、色のサポートの向上、印刷パフォーマンスの大幅な向上など、開発者にとっての利点がいくつか得られます (XPSDrv の詳細については、Windows ドライバー開発キットを参照してください)。

XPS ドキュメントの印刷スプーラーの操作は、基本的に Windows の前のバージョンと変わりません。 ただし、既存の GDI 印刷パスに加えて XPS 印刷パスをサポートするように拡張されています。 新しい印刷パスは、XPS スプール ファイルをネイティブに使用します。 Windows の前のバージョン用に記述されたユーザー モードのプリンター ドライバーは引き続き機能しますが、XPS 印刷パスを使用するには XPS プリンター ドライバー (XPSDrv) が必要です。

XPS 印刷パスには、次のように多大な利点があります。

  • WYSIWYG 印刷のサポート。

  • 1 チャネルあたり 32 ビット (32 bpc)、CMYK、名前付きの色、n 色インク、および透明度とグラデーションのネイティブ サポートを含む、高度なカラー プロファイルのネイティブ サポート。

  • .NET Framework ベースのアプリケーションと Win32 ベースのアプリケーションの両方における印刷パフォーマンスの向上。

  • 業界標準の XPS 形式。

基本的な印刷シナリオ用としては、ユーザー インターフェイス、構成、およびジョブ送信に対する単一エントリ ポイントと共に、シンプルで直感的な API が用意されています。 高度なシナリオ用として、user interface (UI) のカスタマイズ (またはUI をまったく使用しない)、同期印刷または非同期印刷、およびバッチ印刷機能のサポートが追加されています。 いずれの場合も、完全信頼モードまたは部分信頼モードでの印刷がサポートされます。

XPS は、拡張性を考慮して設計されました。 拡張性フレームワークを採用することにより、機能をモジュール形式で XPS に追加できます。 拡張機能には、次のものが含まれます。

  • 印刷スキーマ。 パブリック スキーマは定期的に更新され、デバイス機能の高速拡張を可能にします。 (下記の「PrintTicket および PrintCapabilities」を参照してください)。

  • 拡張可能なフィルター パイプライン。 XPS プリンター ドライバー (XPSDrv) フィルター パイプラインは、XPS ドキュメントの直接印刷と拡張可能な印刷の両方を実現するように設計されました (Windows ドライバー開発キットの "XPSDrv" を参照してください)。

印刷パス アーキテクチャ

Win32 アプリケーションと .NET Framework アプリケーションは両方とも XPS をサポートしますが、Win32 アプリケーションと Windows Forms アプリケーションは、XPS プリンター ドライバー (XPSDrv) 用の XPS 形式のコンテンツを作成するために、GDI から XPS への変換を行います。 これらのアプリケーションは、XPS 印刷パスを使用する必要がなく、Enhanced Metafile (EMF) ベースの印刷を引き続き実行できます。 ただし、ほとんどの XPS の機能と拡張機能は、XPS 印刷パスを対象とするアプリケーションでのみ使用できます。

Win32 アプリケーションおよび Windows Forms アプリケーションで XPSDrv ベースのプリンターを使用できるようにするため、XPS プリンター ドライバー (XPSDrv) は GDI から XPS 形式への変換をサポートしています。XPSDrv モデルは、Win32 アプリケーションで XPS ドキュメントを印刷できるように、XPS から GDI 形式へのコンバーターも提供します。 WPF アプリケーションでは、書き込み操作の対象の印刷キューに XPSDrv ドライバーがない場合、常に XPS から GDI 形式への変換が XpsDocumentWriter クラスの Write および WriteAsync メソッドによって自動的に行われます (Windows Forms アプリケーションでは XPS ドキュメントを印刷できません)。

次の図は、印刷サブシステムを表し、Microsoft によって提供される部分と、ソフトウェアおよびハードウェアのベンダーによって定義される部分を明示しています。

XPS 印刷システム

基本的な XPS 印刷

WPF は、基本的および高度な API を両方定義します。 印刷の大幅なカスタマイズまたは完全な XPS 機能群の使用を必要としないアプリケーションの場合、基本的な印刷サポートを使用できます。 基本的な印刷サポートは、最小限の構成を必要とし、使い慣れた UI を特徴とする印刷ダイアログ コントロールを通じて公開されます。 多くの XPS 機能は、この簡略化された印刷モデルで使用できます。

PrintDialog

System.Windows.Controls.PrintDialog コントロールは、UI、構成、および XPS ジョブ送信のための単一エントリ ポイントを提供します。 コントロールをインスタンス化し、使用する方法の詳細については、「方法 : 印刷ダイアログ ボックスを呼び出す」を参照してください。

高度な XPS 印刷

すべての XPS 機能群にアクセスするには、高度な印刷 API を使用する必要があります。 いくつかの関連 API の詳細については、後で説明します。 XPS 印刷パス APIs の全一覧については、System.Windows.Xps および System.Printing 名前空間のリファレンスを参照してください。

PrintTicket および PrintCapabilities

PrintTicket クラスおよび PrintCapabilities クラスは、高度な XPS 機能の基盤です。 これらのオブジェクトは共に、印刷指向の機能 (部単位印刷、両面印刷、ステープル処理など) の XML 形式の構造です。 これらの構造は印刷スキーマによって定義されます。 PrintTicket は、プリンターに印刷ジョブの処理方法を指示します。 PrintCapabilities クラスはプリンターの機能を定義します。 プリンターの機能を照会することによって、プリンターでサポートされている機能を最大限に利用する PrintTicket を作成できます。 同様に、サポートされていない機能を回避できます。

コードを使用してプリンターの PrintCapabilities を照会し、PrintTicket を作成する方法を次の例に示します。

' ---------------------- 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()
// ---------------------- 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>
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()

PrintServer および PrintQueue

PrintServer クラスはネットワーク印刷サーバーを表し、PrintQueue クラスはプリンターとそのプリンターに関連付けられた出力ジョブ キューを表します。 これらの APIs を合わせて、サーバーの印刷ジョブの高度な管理を行うことができます。 PrintServer、またはこのクラスの派生クラスのいずれかは、PrintQueue を管理するために使用されます。 AddJob メソッドは、キューに新しい印刷ジョブを挿入するために使用されます。

コードを使用して LocalPrintServer を作成し、その既定の PrintQueue にアクセスする方法を次の例に示します。

        ' -------------------- 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()
// -------------------- 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()

XpsDocumentWriter

XpsDocumentWriter は、そのさまざまな Write メソッドおよび WriteAsync メソッドと共に、XPS ドキュメントを PrintQueue に書き込むために使用されます。 たとえば、Write(FixedPage, PrintTicket) メソッドは、XPS ドキュメントと PrintTicket を同期的に出力するために使用されます。 WriteAsync(FixedDocument, PrintTicket) メソッドは、XPS ドキュメントと PrintTicket を非同期的に出力するために使用されます。

コードを使用して XpsDocumentWriter を作成する方法を次の例に示します。

        ' -------------------- 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()
// -------------------- 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()

AddJob メソッドを使用しても印刷することができます。 詳細については、「方法 : XPS ファイルをプログラムにより印刷する」 を参照してください。

GDI 印刷パス

WPF アプリケーションは XPS 印刷パスをネイティブにサポートしますが、Win32 アプリケーションおよび Windows Forms アプリケーションも一部の XPS 機能を利用できます。 XPS プリンター ドライバー (XPSDrv) は GDI ベースの出力を XPS 形式に変換できます。 高度なシナリオでは、コンテンツのカスタム変換が Microsoft XPS Document Converter プリンター エスケープを使用してサポートされます。 同様に、WPF アプリケーションも、XpsDocumentWriter クラスの Write メソッドまたは WriteAsync メソッドを呼び出し、非 XpsDrv プリンターを対象の印刷キューとして指定することによって、GDI 印刷パスに対して出力できます。

XPS の機能やサポートを必要としないアプリケーションのために、現在の GDI 印刷パスはそのままの形で維持されます。

XPSDrv ドライバー モデル

XPS 印刷パスは、XPS 対応のプリンターまたはドライバーへの印刷時のネイティブな印刷スプール形式として XPS を使用することによって、スプーラーの効率を向上します。 簡略化されたスプール処理によって、ドキュメントがスプールされる前に EMF データ ファイルなどの中間スプール ファイルを生成する必要がなくなります。 以前よりスプール ファイルのサイズを小さくすることによって、XPS 印刷パスはネットワーク トラフィックを軽減し、印刷パフォーマンスを向上します。

EMF は、アプリケーションの出力をレンダリング サービスの GDI への一連の呼び出しとして表す閉じられた形式です。 EMF とは異なり、XPS スプール形式は、XPS ベースのプリンター ドライバー (XPSDrv) への出力時に、詳細な解釈を必要とすることなく実際のドキュメントを表します。 ドライバーは、この形式のデータを直接処理できます。 この機能により、EMF ファイルと GDI ベースの印刷ドライバーを使用するときに必要となる、データと色空間の変換が不要になります。

通常、スプール ファイルのサイズは、XPS プリンター ドライバー (XPSDrv) を対象とする XPS ドキュメントを使用する際には、EMF の同等の機能を使用した場合に比べて縮小されますが、例外があります。

  • 非常に複雑であるか、複数の層で構成されているか、または効率的に記述されていないベクター グラフィックスは、同じグラフィックスのビットマップ形式のバージョンよりもサイズが大きくなる可能性があります。

  • 画面の表示の目的で、XPS ファイルは、デバイス フォントとコンピューター ベースのフォントを埋め込みますが、GDI スプール ファイルはデバイス フォントを埋め込みません。 ただし、これらの種類のフォントは両方ともサブセット化されており (以下を参照)、プリンター ドライバーはファイルをプリンターに転送する前にデバイス フォントを削除できます。

スプール サイズの縮小は、いくつかの機構を通じて実行されます。

  • フォントのサブセット化。 実際のドキュメント内で使用されている文字のみが XPS ファイルに格納されます。

  • 高度なグラフィックスのサポート。 透明度とグラデーションのプリミティブに対するネイティブ サポートでは、XPS ドキュメントのコンテンツのラスタライズが行われません。

  • 共通のリソースの識別。 複数回使用されるリソース (会社のロゴを表すイメージなど) は共有リソースとして扱われ、一度だけ読み込まれます。

  • ZIP 圧縮。 すべての XPS ドキュメントは ZIP 圧縮を使用します。

参照

参照

PrintDialog

XpsDocumentWriter

XpsDocument

PrintTicket

PrintCapabilities

PrintServer

PrintQueue

Microsoft XPS Document Converter プリンター エスケープ

概念

WPF のドキュメント

ドキュメントのシリアル化および保存

その他の技術情報

印刷に関する「方法」トピック

XPS