[win8] スタート画面のタイルを動的に作成する(前哨戦)

途中なのですが、windows 8 のスタート画面のタイルを動的に作成することができたので、報告。
通常は、TileTemplateType あたりを使ってテンプレートを使ってタイルを作るのですが、これだと microsoft 社が提供するタイルしか作れません。まあ、標準的なタイルを作る場合にはこれでも良いのですが、どうせならばオリジナルのタイルが作りたいですよね、というのが発端です。

TileTemplateType enumeration (Preliminary)
http://msdn.microsoft.com/en-us/library/windows.ui.notifications.tiletemplatetype.aspx

テンプレートを使ったタイルの制限としては、

  • 標準的なフォーマットに従うために、画像位置やフォントが変更できない。

があります。これを、画像テンプレートの を使って動的に作成してしまおうという作戦です。画像を自前で作成できるので、自由な画像の配置、自由なフォントを使えるハズです。

ひとまず、こんな風に「HGP明朝E」のフォントを使ってタイルができました。いまのところ文字しか書いていませんが、背景に画像を貼り付けるできる予定です。左下に小さいアイコンがでてるのですが、これを消したいんですけどね~。TileSquareImage テンプレートが自動で表示しているので、どうすればよいのか?と思案中です。

普通にタイルだけを変更する場合は、あらかじめタイルを画像で作っておけば良いのですが、これを動的に作成する(時刻の表示や、ネットに接続してメッセージを出すとか)を考えると、(今のところは)動的に画像ファイルを作成しないといけないという状況です。ええ、タイル用のオリジナル XAML を設定できるようにしてくれればいいだけなんですけどね。将来的にはできるようになって欲しいなぁと。

■技術的な準備

さて、この動的なタイルを実現させるためには、いくつかクリアしないといけない技術的な問題…と言いますかクリアしないといけない壁があって、

  • DirectX で画像ファイルを作成する
  • C++/CX の metro からタイルの更新 TileUpdateManager を呼び出す
  • そもそも C++/CX で metro アプリを作らないと駄目?かも
  • C# から C++/CX のライブラリを呼び出せばOK?

というところです。metro アプリの場合、画像の切り出しやファイル保存の機能は WriteableBitmap class あたりで用意されています。この BitmapSouce になる WriteableBitmapを使えば、画像の加工もできるので、動的に画像を作ること、ちょっと頑張れば色相を変更させたり、一定の色で塗りつぶすことはできます。
が、.NET 4.5 では、画像加工の方法はいくらでも出てくるのですが、metro version になるとメソッドがグッと減っています。単純な加工ぐらいならば使えないことはないのですが、指定フォントで表示したり楕円を書いたり、透明度を設定したりということができません。まぁ、ピクセル単位で頑張ればできないこともないのですが、頑張るのは無駄かと。

そこで、画像作成はいきおい DirectX を使うようになります。DirectX で適当なビットマップを作って、それに描画しておき、そこからタイル用の png 形式のファイルに書き出せばよいわけです。

という訳で、画像ファイルを作成するためには DirectX を使うことになるのですが、これが C++/CX からしか扱えない(多分)らしいのですよね。おそらく、DirectX 関係のヘッダファイルを読み込んで適当な構造体を定義しないといけないので、見た感じでは C# や VB では無理です。

まぁ、C++/CX で metro アプリケーションを作れるようになったので、C++/CX だけで作っても良いのですがもうちょっと .NET Framework 寄りにしたいですよね。と言いますか、C++/CX からは .NET Framework を扱えないので、適当な画面は C# あたりで作る方が便利なのです。

なので、作成方法としては、

  • DirectX を扱う部分を C++/CX でライブラリとして作成
  • metro 画面自体は、C# で作成して、ライブラリにパラメータを渡す

な方式がベターかなと。

■暫定的なソースコードを公開

C++/CX だけで作ったものですが、一応 github に載せておきます。

win8/ChangeTileCppCx
https://github.com/moonmile/win8/tree/master/ChangeTileCppCx

作ったときの手順をざっと書いておくと

  1. c++/cx metro アプリケーションを作成
  2. ダミープロジェクトで direct2D のアプリケーションを作成。
  3. ダミープロジェクトから DirectXBase.* 関係のファイルをコピー。
  4. pch.h に DirectX 関係のヘッダを入れ込み
  5. c++/cx metro プロジェクトの DirectX 関係のライブラリを入れ込み
  6. 画像ファイルを動的に作成する DirectXLib.cpp を作成
  7. 上記のファイルに適当な namespace を付ける
  8. BlankPage.xml.cpp から、DirectXLib のクラスを呼び出し

ってな具合です。難関はいくつかあるのですが、

  • DirectX の扱いがそもそもよく分からん(c++から使う DirectX とは微妙に違うので、サンプルが少ない…つーか、まるでない)
  • ファイル書き出すは DirectX の関数からは直接できないので、メモリストリームを使って WinRT 経由で出力
  • ファイル書き出しが非同期なので、Task<>を使って書く必要あり。

なところですね。このあたりはぼちぼちと解説を書いていきます。

まあ、C++/CX で DirectX+metro の組み合わせでいけると「楽しい」かもしれません。metro の C#/VB では画像関係がチープになっているので、ちょっと小細工をした画像を作ろうとすると DirectX を直接触る必要があるので、C++/CX で画像関係のコンポーネントを作っておいて C#/VB から扱う、というスタイルが標準的になるような気がします。

カテゴリー: C++/CX, windows 8 パーマリンク