Windows を刷新するにあたり、私たちは、ユーザー エクスペリエンス、開発者プラットフォーム、広範にわたるデバイス エコシステムなど、印刷のあらゆる側面と、全体としてすばらしいエクスペリエンスを提供するためにそれらをどのように連携させるかについて、改めて検討することにしました。この記事では、Windows 8 での印刷のユーザー エクスペリエンスと開発者プラットフォームについて概説します。また、アプリの要件に合わせて印刷のユーザー エクスペリエンスを調整する方法についても説明します。

Windows 8 アプリからの印刷

まず、Windows 8 での印刷のしくみを見ていきましょう。その後、各種アプリで印刷がどのように処理されるかを説明します。

Windows 8 の印刷は、印刷をサポートするアプリのコンテキストに応じて動作します。アプリは、印刷コントラクトに登録することで、印刷をサポートします。アプリで印刷をサポートするかどうかは、開発者が判断します。すべてのアプリが印刷を使用するわけではありません。たとえば、ゲームを開発している場合であれば、印刷は必要ないと判断することもあります。しかし、航空会社向けのアプリを開発している場合は、航空券の印刷は、チェックイン プロセスの重要な項目の 1 つになるでしょう。アプリで印刷をサポートするかどうか、また印刷を提供するのはどのような場合であるかは、開発者が自由に決めることができますが、ユーザーの期待を考慮する必要があります。ユーザーによってアプリからの印刷が期待されている場合は、アプリで印刷をサポートすることをお勧めします。

Windows 8 で印刷をするには、画面の右端から内側に向かってスワイプし、チャームを表示します。アプリで印刷がサポートされている場合、デバイス チャームをタップすると、コンピューターにインストールされているすべてのプリンターが表示されます。印刷に使うプリンターを選択すると、次のような印刷ウィンドウが表示されます。

印刷のフロー

印刷のフロー

印刷ウィンドウには、印刷内容のプレビューと、よく使われるプリンターの設定が表示されます。私たちが印刷機能について計画している段階で、印刷内容を印刷前に確認したいという要望が多くの方から寄せられました。Windows 8 の印刷プラットフォームでは、印刷ウィンドウで印刷コンテンツのプレビューを表示できるようになっています。したがって、アプリから独自の方法でプレビューを表示する必要がありません。この印刷プラットフォームではプレビューの表示を更新することもでき、印刷ウィンドウでプリンターの設定を変えるごとに、印刷結果がどうなるかをユーザーが確認できます。

既定の印刷エクスペリエンスを効率的にするため、印刷ウィンドウには既定で [印刷部数]、[印刷の向き]、[カラー] の 3 種類のプリンター設定しか表示されません。私たちの調査によると、これらは、印刷時にユーザーが最もよく変更されるプリンター設定です。これらの設定を表示することで、ユーザーが印刷ジョブの構成中に、最もよく使う設定にすぐにアクセスできます。アプリの開発者は、アプリに最適なエクスペリエンスを提供するため、印刷ウィンドウに表示する設定を制御できます。また、各設定の既定値を定義することもできます。

すべての Windows 8 アプリで、コンテンツの印刷には同じエクスペリエンスを使用します。したがって、ユーザーはあるアプリでの印刷方法がわかれば、すべてのアプリから印刷することができます。つまり、ユーザーは印刷機能を探し回ることも、アプリごとに印刷方法を新たに覚える必要もありません。

印刷コントラクト

アプリは印刷コントラクトを使って、印刷プラットフォームと通信します。アプリは印刷するコンテンツを提供し、Windows は印刷エクスペリエンスと基盤のインフラストラクチャを提供します。アプリを印刷コントラクトに登録すると、デバイス チャームから印刷機能を利用できるようになるため、簡単に印刷機能にアクセスして使用できます。

すべての WinRT API など、印刷コントラクトは、任意の言語および UI フレームワークと連係できるように設計されています。したがって、HTML または XAML のいずれを使ってもコンテンツをレイアウトできます。アプリからのコンテンツ印刷の動作をさらに制御したい場合は、D2D や XPS テクノロジを使うこともできます。

アプリに印刷のサポートを追加する場合は、次の 2 つの側面について検討する必要があります。

  • 印刷するコンテンツの提供。
  • アプリに最適な印刷設定の決定。

では、それぞれの側面について、見ていきましょう。

印刷するコンテンツの提供

アプリの設計時に、印刷シナリオを十分に検討してください。ユーザーが外出先に持ち出すコンテンツにはどのようなものがあるでしょうか。印刷物として使うか、後で参照するために、紙のコピーを用意しておきたいコンテンツはなんでしょうか。たとえば、写真を撮影するアプリでは、写真を印刷して額に入れ、部屋に飾ることをユーザーが望む場合はあるでしょうか。アプリでのシナリオを十分に検討することで、アプリからの印刷が可能であることが必要なコンテンツを特定し、ユーザーにとって最適な印刷エクスペリエンスを設計できます。

印刷対象となるコンテンツを特定したら、印刷するコンテンツをどこから取得するかを考えます。最初に留意する必要があるのは、おそらく、画面上で適切に表示されるものが、紙面の上でも適切に印刷されるわけではないということです。画面と紙面のそれぞれに最適なコンテンツのフォーマット方法を真剣に考える必要があります。つまり、画面上のコンテンツであるアプリのメイン ビューと印刷する内容は異なることになります。これは、あらゆる種類のアプリに当てはまります。ニュース リーダーのようなシンプルなアプリであっても例外ではありません。画面上の列内では適切に表示されるコンテンツが、同じレイアウトを採用していても紙面では適切に表示されない可能性があります。これらの検討事項のすべてが、アプリの構築方法に影響します。設計の早い段階でこれらを検討しておいた方が、後の段階で前に戻って変更を行うよりも簡単です。

また、アプリのワークフローに印刷をどのように取り入れるかについても、検討するとよいでしょう。多くのアプリでは、印刷はメニュー項目の 1 つにすぎません。たとえば、ユーザーが表示している写真を印刷する場合を考えます。この場合、印刷を始めるためにユーザーに利用してもらうべきインターフェイスは、デバイス チャームです。つまり、アプリ内に印刷を開始するための手段を追加することは、適切なアプローチではありません。単純にチャームを使って印刷するようにします。一方、アプリの全体的なワークフローにおいて、印刷が重要な要素になる場合もあります。領収書を印刷するショッピング アプリを考えてみましょう。画面上の表示には、注文内容と利用を感謝する言葉の他に、印刷エクスペリエンスに直接移動できる [Print receipt] (領収書の印刷) ボタンが含まれると思われます。ユーザーが [Print receipt] (領収書の印刷) ボタンをタップすると、領収書のプレビューが表示された印刷ウィンドウが開き、プレビューの内容に従って領収書を直接印刷できます (下図参照)。

画面上の表示とは異なるコンテンツの印刷

画面上の表示とは異なるコンテンツの印刷

HTML/JavaScript アプリからの印刷

印刷のサポートは、以下のコードをアプリに追加するだけで、実装できます。

// Register for print contract
var printManager = Windows.Graphics.Printing.PrintManager.getForCurrentView();
printManager.onprinttaskrequested = onPrintTaskRequested;
function onPrintTaskRequested(printEvent) {
printEvent.request.createPrintTask("Print Sample", function (args) {
args.setSource(MSApp.getHtmlPrintDocumentSource(document));
});
}

上記のコードによって、印刷コントラクトにアプリが登録されます。ユーザーが印刷を実行すると、アプリは単純に現在のドキュメントのコンテンツ、つまり画面上に表示されている内容を印刷します。これで、デバイス チャームを使ってアプリから印刷できるようになりました。この場合、既定のプリンター設定に基づいた印刷エクスペリエンスが提供されます。改ページとプレビューの更新は、Windows 8 のレンダリング エンジンによって処理されます。

シナリオによっては、印刷対象と、印刷コンテンツのレイアウトを制御したい場合があります。たとえば、現在の DOM ではないコンテンツなど、現在画面に表示されていないコンテンツを印刷したい場合があります (先ほど例にした領収書の印刷など)。これを実現する最も簡単な方法は、次のように、印刷対象となる別のコンテンツを HTML の head 要素内に指定することです。

<! -- Add this to the head element of your html file -->
<link rel="alternate" href="http://go.microsoft.com/fwlink/?linkid=240076" media="print"/>

この処理を行うと、getHtmlPrintDocumentSource(document) への呼び出しによって、指定された印刷対象のコンテンツが適切に使用されます。

しかし、本当にクリエイティブな処理をしたい場合はどうでしょうか。ここで便利なのは、HTML ドキュメントを getHtmlPrintDocumentSource に渡す限り、ほぼどこからでも HTML を印刷できることです。ローカルで作成することや、Web から IFrame にダウンロードすることなど、任意の方法で印刷ドキュメントを作成できます。

また、段組レイアウト、水平スクロール、アイテムのグループ化など、複雑なレイアウト コントロールを使って、画面上のアプリ エクスペリエンスを構築することもあります。このようなレイアウトは、印刷用のレイアウトにうまく変換できません。印刷プラットフォームに送信する前にレイアウトを簡素化して、コンテンツの改ページとプレビューのレンダリングを容易にすることが非常に重要です。このために、CSS メディア ルールを使用できます。印刷メディア用の CSS ルールを定義すると、アプリのフローで表示されるレイアウトとは別のレイアウトを作成できます。CSS を使うと、コンテンツを非表示にすることや、要素のサイズを変更することに加えて、余白の調整、背景やスクロールバーなどの要素の削除、フォントや色の変更など、さまざまな処理が可能です。例を使って考えてみましょう。

好きな料理のレシピを印刷できるレシピ アプリについて考えます。このアプリは、グリッド アプリ テンプレート ([ファイル] -> [新しいプロジェクト] -> [<言語>] -> [Windows ストア] -> [Grid App] (グリッド アプリ)) を基に作成されています。

レシピ アプリ

レシピ アプリ

最初にするべきことは、本当に印刷する必要があるものは何かを考えることです。ここでは、レシピを印刷するユーザーは、レシピをレシピ ブックに追加するものとします。したがって、おそらく、評価やレビューは、この時点では気にされません。したがって、タイトル、画像、説明のテキスト、材料の一覧、作り方を印刷します。評価やレビューなど、その他のページ コンテンツは印刷しません。

以下に、画面にコンテンツを表示するための CSS ファイルの例を示します。

.itemdetailpage .content {
-ms-grid-row: 1;
-ms-grid-row-span: 2;
display: block;
height: 100%;
overflow-x: auto;
position: relative;
width: 100%;
z-index: 0;}

.itemdetailpage .content article {
/* Define a multi-column, horizontally scrolling article by default. */
column-fill: auto;
column-gap: 80px;
column-width: 480px;
height: calc(100% - 183px);
margin-left: 120px;
margin-top: 133px;
width: 480px;}

.itemdetailpage .content article header .item-title {
margin-bottom: 19px;}

.itemdetailpage .content article .item-image {
height: 240px;
width: 460px;}

.itemdetailpage .content article .item-rating {
height: 40px;
margin-top: 0px}

.itemdetailpage .content article .item-review {
height: 100px;
margin-top: 20px }

.itemdetailpage .content article .item-content p {
margin-top: 10px;
margin-bottom: 20px;
margin-right: 20px;}

以下は、印刷プレビューの表示例です。

コンテンツをフォーマットせずに印刷した場合

コンテンツをフォーマットせずに印刷した場合

この印刷プレビューには、いくつか問題があります。タイトルの横に戻るボタンがあり、スクロールバーも含まれています。しかも、表示されているのは最初のページのプレビューのみです。このために、プレビューが不適切になっています。

ここでは、アプリのコンテンツが画面に表示しきれない場合に隠れているコンテンツをスクロールして表示できるように、overflow プロパティによってスクロール バーが追加されています。このコンテンツを印刷のために送信するときも同じ動作が継承され、その結果、コンテンツが切り詰められます。印刷サーフェスでコンテンツを適切にレイアウトするには、CSS ルールを使ってコンテンツをフォーマットする必要があります。

印刷コンテンツをレイアウトするには、CSS ファイル (print.css) を作成し、これを html ファイルに追加します。

<link rel="stylesheet" type="text/css" href="/css/print.css" media="print" />
Print.css
/* Hide the back button */
.win-backbutton {
display: none;}

/* Remove the grid layout */
.fragment {
display: block;
height: auto;
width: 100%;
position: relative;
margin: 0px;
overflow: visible;}

/* Remove the header */
.fragment header[role=banner] {
display: none;}

/* Remove multicolumn layout */
/* Resize the content to take up available space*/
/* Remove scrolling behavior */
.itemdetailpage .content {
display: block;
height: 100%;
overflow: visible;
width: 100%;}

.itemdetailpage .content article {
height: 100%;
width: 100%;
margin: 0px;
overflow: visible;}

/* Adjust margins */
/* Increase font sizes */
.itemdetailpage .content article header .item-title {
margin-bottom: 29px;
font-size: 450%;}

.itemdetailpage .content article .item-image {
height: 480px;
width: 920px;
margin-top: 20px;
margin-bottom: 40px;}

/* Remove rating and review controls */
.itemdetailpage .content article .item-rating {
display: none;}
.itemdetailpage .content article .item-review {
display: none; }

.itemdetailpage .content article .item-content p {
height: auto;
width: 100%;}

これにより、印刷プレビューがレイアウトされ、次のような印刷結果になります。

コンテンツをフォーマットして印刷した場合

コンテンツをフォーマットして印刷した場合

前述の問題がどのように解消されているか、確認してみましょう。タイトルの横にあった戻るボタンはプレビューで表示されていません。また、スクロール バーもなくなっています。プレビューで次のページに移動すると、印刷コンテンツが適切に次のページに表示されます。CSS は、望みどおりに印刷コンテンツをレイアウトするための強力なツールとして利用できます。

HTML および JavaScript で作成されたアプリからの印刷の詳細については、「印刷 (JavaScript と HTML を使った Metro スタイル アプリ)」を参照してください。

XAML アプリからの印刷

XAML でアプリを記述している場合は、アプリで印刷以外の機能も処理する必要があります。アプリで印刷コンテンツをどのようにレイアウトするかを定義し、何を改ページとするかを決めることが必要です。これにより、各ページのコンテンツを制御して、アプリから印刷するコンテンツの内容を正確に定義できます。ご想像のとおり、XAML を使って画面に表示するコンテンツのレイアウトを定義する場合と同じように、XAML を使ってアプリの印刷コンテンツのレイアウトを定義します。

XAML は、画面上のコンテンツの表示を柔軟に制御できるすばらしい記述言語です。特に、アプリがさまざまな画面サイズに合わせて適切にサイズを調整する必要がある場合に便利です。しかし、画面上の表示には非常に便利な XAML の機能ですが、必ずしも紙面の上で最適なレイアウトを実現できるわけではありません。たとえば、XAML のレイアウト機能は、画面の縦横のピクセルに合わせて、フォントや写真を拡大または縮小します。これは画面上では有効ですが、印刷の場合、通常、出力の拡大縮小は好まれません。したがって、アプリの印刷コンテンツを紙面にどのように出力するかを考えたうえで、使用する XAML から、正確に意図したとおりの結果が得られるように処理する必要があります。

もう一度レシピ アプリを使って、XAML でコンテンツをレイアウトする方法を見ていきましょう。XAML の場合、目的のコンテンツは richTextColumns コントロールの ItemDetailPage に保持されています。印刷したい情報 (タイトル、画像、説明のテキスト、材料の一覧、作り方) を取得するには、リンク付きコンテナーの一覧として、レシピ ページを定義します。

<Grid VerticalAlignment="Center" x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="7*"/>
</Grid.RowDefinitions>

<RichTextBlock x:Name="txtContent" OverflowContentTarget="{Binding ElementName=link}" Grid.Row="0" Grid.Column="0">
<Paragraph TextAlignment="Center">
<Run x:Name="txtRecipe" Text="{Binding Title}" FontSize="30" Foreground="Black"></Run>
</Paragraph>
<Paragraph>
<InlineUIContainer>
<Image x:Name="imgRecipe" Stretch="Uniform" Source="{Binding Image}"/>
</InlineUIContainer>
</Paragraph>
<Paragraph>
<Run Text="Ingredients:" FontSize="30" Foreground="Black"/>
<Run x:Name="txtIngredients" Text="{Binding RecipeIngredients}" FontSize="20" Foreground="Black"/>
</Paragraph>
<Paragraph>
<Run Text="Details:" FontSize="30" Foreground="Black"/>
<Run x:Name="txtDetails" Text="{Binding Content}" FontSize="20" Foreground="Black"/>
</Paragraph>
</RichTextBlock>

<RichTextBlockOverflow x:Name="link" Grid.Row="1" Grid.Column="0"/>
</Grid>

レシピのコンテンツが印刷ページに収まらない場合は、収まりきらなかったコンテンツを収容する続きのページをアプリによって作成する必要があります。この場合、続くページには、単純に前のページのリッチ テキスト ブロック要素にリンクされた RichTextBlockOverlow 要素を含め、残りのテキストが新しいページに流し込まれるようにします。

<Grid x:Name="grid">
<RichTextBlockOverflow x:Name="link"/>
</Grid>

改ページに対応して、次のようなページ プロジェクション アルゴリズム定義できます。

void printDocument_Paginate(object sender, PaginateEventArgs e)
{
PrintDocument printDocument = (PrintDocument)sender;

// get printer page description
PrintPageDescription pageDesc = e.PrintTaskOptions.GetPageDescription(0);

// clear previous generated print content
pages.Clear();
printingRoot.Children.Clear();

RecipePage page = new RecipePage(pageDesc)
{
DataContext = flipView.SelectedItem
};

UIElement element = null;
RichTextBlockOverflow rtbo = page.Link;

do
{
// check if this is the first page
if (element != null)
{
var continuation = new ContinuationPage(rtbo, pageDesc);
element = continuation;
rtbo = continuation.Link;
}
else
{
element = page;
}

// add the page to the visual tree to forece content flow
printingRoot.Children.Add(element);
printingRoot.InvalidateMeasure();
printingRoot.UpdateLayout();

pages.Add(element);

} while (rtbo.HasOverflowContent);

// set the current number of pages
printDocument.SetPreviewPageCount(pages.Count, PreviewPageCountType.Intermediate);
}

XAML で記述されたアプリからの印刷の詳細については、「印刷 (C#/VB/C++ と XAML を使った Metro スタイル アプリ)」を参照してください。

アプリに最適な印刷設定の決定

アプリから印刷する必要があるコンテンツ、およびコンテンツの表示方法が決まったら、アプリが提供するユーザー エクスペリエンスについて検討します。

既定の 3 種類のプリンター設定を使ったエクスペリエンスでは、不十分だと判断される場合もあるでしょう。印刷ウィンドウにその他のプリンター設定も表示するか、独自のアプリ固有の設定を追加することが求められる場合もあります。このような場合は、ニーズに合わせて、印刷エクスペリエンスをカスタマイズできます。

ここで、例をいくつか使って考えてみましょう。

プリンター設定の追加

再びレシピ アプリを例に取ります。レシピは、容易に複数のページにわたることが考えられます。したがって、両面印刷のオプションを提供してもよいでしょう。そのためには、印刷ウィンドウに両面印刷設定を追加します。

これによって、印刷ウィンドウは、次のようになります。

他のプリンター設定を追加した印刷ウィンドウ

他のプリンター設定を追加した印刷ウィンドウ

次のコードは、JavaScript を使って両面印刷設定を追加する方法を示しています。

printTask.options.displayedOptions.append
(Windows.Graphics.Printing.StandardPrintTaskOptions.duplex);

次のコードは、C# を使って両面印刷設定を追加する方法を示しています。

printTask.options.displayedOptions.Add (Windows.Graphics.Printing.StandardPrintTaskOptions.Duplex);

両面印刷は、利用できるさまざまなプリンター設定の 1 つです。ただし、両面印刷設定を追加しただけでは、この設定は表示されない場合があります。プリンターが両面印刷をサポートしていない場合、Windows はこの設定をユーザーから隠します。プリンター設定の追加の詳細については、「印刷プレビュー UI の標準オプションを変更する方法」(HTML/JavaScript 向けの記事および XAML 向けの記事) を参照してください。

XAML アプリでのカスタム設定の追加

XAML アプリでは、その他にも可能なカスタマイズがあります。XAML アプリの場合、独自のカスタム設定を印刷ウィンドウに追加できます。例を使って考えてみましょう。

ルート案内を印刷できる地図アプリについて考えます。「地図を印刷すると、インクが高く、費用がかかるので、印刷する情報をユーザーが選べるようにする」ことを考え、ルート案内の種類などのカスタム設定を表示します。

カスタム設定を追加した印刷ウィンドウ

カスタム設定を追加した印刷ウィンドウ

この例では、[Map and text] (地図とテキスト)、[Map only] (地図のみ)、[Text only] (テキストのみ) の 3 つのオプションがある [Directions type] (ルート案内の種類) 設定が追加されています。これにより、ユーザーは地図をどのように印刷するかを指定できます。

次のコードは、このようなカスタム オプションを追加する方法を示しています。

PrintCustomItemListOptionDetails pageFormat = printDetailedOptions.CreateItemListOption 
("PageContent", "Pictures");
pageFormat.AddItem ("MapText", "Map and text");
pageFormat.AddItem ("MapOnly", "Map only");
pageFormat.AddItem ("TextOnly", "Text only");

// Add the custom option to the option list
displayedOptions.Add ("PageContent");

printDetailedOptions.OptionChanged += printDetailedOptions_OptionChanged;

この機能の詳細については、「印刷プレビュー UI にカスタム設定を追加する方法」を参照してください。

まとめ

印刷コントラクトによって、開発者はアプリから印刷する内容と印刷出力の状態を柔軟に定義でき、ユーザーは Windows 8 のどのアプリからも常に同じ方法で印刷を実行できます。開発者は、既定のエクスペリエンスを使って印刷することも、アプリのニーズに合わせて印刷エクスペリエンスをカスタマイズすることも可能であり、アプリで印刷する情報を常に柔軟に制御できます。

参照情報

リンク

種類

印刷コントラクトのサンプル

サンプル

HTML/JavaScript での印刷コントラクトへの登録 (英語)

ドキュメント

XAML での印刷コントラクトへの登録 (英語)

ドキュメント

Windows.Graphics.Printing 名前空間のリファレンス (英語)

ドキュメント

Windows.Graphics.Printing.OptionDetails 名前空間のリファレンス

ドキュメント

Windows Devices and Networking シニア プログラム マネージャー Sangeeta Ranjit

協力: Darren Davis、Daniel Alex Volcinschi、Saumya Jain、Travis Eby