4.6でサポートされた新機能を使うことで、子ウィンドウを透明にできる。本稿ではその方法を解説する。「子ウィンドウ」といっても、WPFのウィンドウ(System.Windows名前空間のWindowクラス)のことではない。APIの、すなわちWindowsが直接管理している生粋のウィンドウの話である。以降では「ウィンドウ(WPF)」「ウィンドウ(Win32)」と表記して区別する。TIPS:WPF:ウィンドウを透明にするには?[C#/VB]」参照)。WPFで作った子ウィンドウ(Win32)は、これまで透明にできなかったのである。4.6以降の組み合わせで可能になった。本稿ではその方法を説明する。子ウィンドウ(Win32)が必要な場面いろいろな場面が想定できるが、Win32と相互運用する場面でWPFのUIコントロールを最前面に表示しようとすると子ウィンドウ(Win32)が必須になる。WebBrowserコントロール(System.Windows.Controls名前空間)の手前にWPFのUIコントロールを配置したいような場合だ。相互運用性」には「HwndHostは、同じトップレベルウィンドウの他のWPF要素の上に表示」されると記述されている。その意味するところは、WebBrowserコントロール(これはHwndHostの一つ)が必ず最前面に表示されるので、その他のWPFのUIコントロールはWebBrowserコントロールの手前に表示できないということである。HwndHostには、WindowsフォームのUIコントロールをWPFで利用するためのWindowsFormsHostコントロール(System.Windows.Forms.Integration名前空間)も含まれる。以前からWPFに取り組んできた開発者には、この問題に遭遇した人も多いのではないだろうか。実際に問題を確認してみよう。WPFのプロジェクトを作り、次のようなXAMLコードを記述する。Padding="8,0"/></Grid></Window>WebBrowserコントロールの手前に他のコントロールを配置する(XAML)WebBrowserコントロールの手前にBorderコントロールとGridコントロール(名前「footPrint」)を配置した。XAMLコードの記述順に奥から手前へと配置されるのだが、さらにZIndexプロパティも指定してある(数字の大きい方が手前に表示される)。ウィンドウ(WPF)のトップレベルのGridコントロールには「rootGrid」という名前が付けてある。ButtonコントロールのClickイベントハンドラー「Button_Click」をコードビハインドに生成しておいてほしい(メソッド内は空のままでよい)。後に説明するコードビハインドでは、「rootGrid」の子要素になっている「footPrint」を、その親から切り離して子ウィンドウ(Win32)に移動させる。2015のXAMLエディターは、次の画像のようになる。Studioで記述したところ(XAMLエディター)WebBrowserコントロールは濃いめの灰色の部分だ。その内側の手前に緑色のBorderコントロールが配置されている。手前にGridコントロール「footPrint」がある(青色の四角形と茶色の足跡の画像)。このようにXAMLエディター上では、XAMLコードに記述した順序で表示されている。ところが実行してみると、次の画像のようにWebBrowserコントロールが最も手前に表示されてしまうのだ。10)WebBrowserコントロールには、Sourceプロパティに指定したWebページが表示されている。WebBrowserコントロールの手前に配置されるはずの緑色のBorderコントロールは完全に隠されてしまった。Gridコントロール「footPrint」(青色の四角形と茶色の足跡の画像)も、WebBrowserコントロールの下になっている。コントロールに指定したZIndexプロパティも無視されてしまった。これは、WebBrowserコントロールがHwndHostであり、ウィンドウ(WPF)とは独立した子ウィンドウ(Win32)になっているためだ。親ウィンドウ(WPF)の一部であるWPFのUIコントロールは、子ウィンドウ(Win32)の手前にくることはできないのである。これを解決するには、子ウィンドウ(Win32)に勝てるのは子ウィンドウ(Win32)だけであるから、WPFのプログラム中で子ウィンドウ(Win32)を作成し、そこにWPFのコントロールを配置すればよい。それは従来から可能であった。子ウィンドウ(Win32)を透明にする手段は提供されていなかったのである。子ウィンドウ(Win32)を透明にするには?正確には、「WPFのコントロールを配置できる子ウィンドウ(Win32)を透明にするには?」と言うべきであろう。それは、今まではサポートされていなかったのである。4.6以降の組み合わせで可能になった。8.0より以前のバージョンでは動作しないので、ご注意願いたい。2015を使用する*1。Packを利用すれば開発できるはずである(筆者は確認していない)。既存のプロジェクトの場合は、プロジェクトのプロパティの[アプリケーション]タブで[対象のフレームワーク]を切り替える。Frameworkのバージョンを設定する(次の画像)。Frameworkのバージョンを指定するダイアログ上部のドロップダウンで切り替える(赤枠内)。8.0以降である」と宣言する。ファイル]を指定し、ファイル名は「app.manifest」のまま、[追加]ボタンをクリックする(次の画像)。ファイル]を選択し、ファイル名は「app.manifest」のままにして、[追加]ボタンをクリックする。8に関する<supportedOS>タグがコメントアウトされているので、そのコメントを外す(次の画像)。8に関する<supportedOS>タグがある(赤枠内)。この行のコメントを外す。<supportedOS>タグを含むセクションが存在しない場合は、次のコードのようにマニフェストファイルの末尾に追記する。--></assembly>マニフェストファイルに追加するコード(XML)マニフェストファイルに<supportedOS>タグを含むセクションが存在しない場合は、ファイル末尾の</assembly>閉じタグのすぐ上にこのように追記する。最後にコードビハインドを編集する。ここではボタンのクリックイベントハンドラーから呼び出すようにした。透明な子ウィンドウ(Win32)を作り、そこにWPFのコントロールを配置するのだ(次のコード)。4.6でHwndSourceParametersオブジェクト(System.Windows.Interop名前空間)に追加されたUsesPerPixelTransparencyプロパティ(太字の部分)にtrueをセットしている部分だけである。それだけで、作成された子ウィンドウ(Win32)は透明になる。このコードに登場するUIコントロールについては、前掲したXAMLコードをご覧いただきたい。このコードでは、XAMLコードで定義したUIコントロールを子ウィンドウ(Win32)に移すという手段を採ったが、C#/VBのコードで直に生成したUIコントロールを子ウィンドウ(Win32)にセットしても構わない。これで実行してみると次の画像のようになる。WebBrowserコントロールの手前に、半透明のコントロールが表示できた。10)最初の画像ではWebBrowserコントロールに隠されていたGridコントロール「footPrint」(青色の四角形と茶色の足跡の画像)が、今度はちゃんと手前に表示されている。子ウィンドウ(Win32)は親ウィンドウ(WPF)とは独立した存在なので、親ウィンドウ(WPF)をリサイズしても子ウィンドウ(Win32)のサイズは変わらない。今回の例で言うと、親ウィンドウ(WPF)をリサイズしても「footPrint」(青色の四角形と茶色の足跡の画像)の位置は変わらないのである。4.6でHwndSourceParametersオブジェクトに追加されたUsesPerPixelTransparencyプロパティをtrueに設定すればよい。8.0以降である」という宣言が必要である。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。