質問: WPFにはテーマというものがあることを知りました(ここでいうテーマというのは、リンク先のような`Aero.NormalColor.xaml`などのことを呼ぶこととします)。これらのテーマは、たぶんGithubにて公開されているものと思われます。 テーマに関して、参照先の記事は古いので現在は状況が異なるのかもしれませんが、質問です。 **Q1.** WPFの既定のテーマはどれですか?(リンク先にあるもの?それとも異なるもの?オープンソースではない?) **Q2.** 任意のWPFアプリケーションについて、機械的な手段で現在適用されているテーマを調べることは可能ですか?(たとえば、.exeや.dllから、使われているテーマ(.xamlファイル)を取得する、などをやれたらうれしい。dnSpyが使える??) 環境はWindows 10, .NET Core 3.0としておきますが、回答するためにさらに仮定が必要ならば追記可能です。 以上、よろしくお願いいたします。
回答: とりあえず達成する方法をみつけたので回答として報告しておきます。 **A1.** A2により調査した結果、結論としては、今回の環境では`Aero2.NormalColor.xaml`でした。 **A2.** いくつかの方法を試しました。 1. 手動でテーマを適用して、既定と同じ見た目のものが今のテーマである、と考えて、`Aero`,`Aero2`,`AeroLite`,`Classic`,`Luna`,`Royale`を全通り試しました。 `App.xaml`に次のような記述を追加してアプリを起動します(参考): ``` ``` この結果、`Aero2`のとき、見た目の変化がおきず、おそらくこれが既定のテーマであると予想できます。 2. dnSpyを用いる方法: 実際にロードされているDLLやリソース(.xamlなど)を具体的に知ることができれば、適用されているテーマを知ることができると考えました。 完全な調査をするためにブレークポイントを設置するべき箇所は実際にはもっとあるかもしれませんが、今回は次の箇所に設置して調査しました(export): 1. `RuntimeAssembly.InternalLoadAssemblyName`メソッド: * `Assembly.Load`などDLLを読み込むときに呼び出されるメソッドです。 * このメソッドの呼び出しを記録した結果、今回の環境では`PresentationFramework.Aero2.dll`がロードされていて、それ以外のテーマらしいDLLはロードされていませんでした。 * このメソッドの呼び出しのコールスタックに基づいて調べたところ、このDLLが選択されるのは、最終的にはWinAPIのGetCurrentThemeNameが返す値によるようです(cf. `UxThemeWrapper.GetThemeNameAndColor`)。より深く調査したい方はこのあたりの呼び出しを調べるとよいと思われます。 2. `Baml2006Reader.Initialize`メソッド: * XAMLファイルをロードするときに内部的に呼び出されるメソッドです。 * このメソッドの引数`settings`の`LocalAssembly`でそのXAMLリソースが格納されたDLL、`BaseUri`プロパティでロードしようとしているXAMLファイルの情報が取得できるようです。 * ただし、肝心のテーマファイル(`Aero2.NormalColor.xaml`)の読み込み時には、`LocalAssembly`は`PresentationFramework.Aero2`となっていたものの、`BaseUri`が`null`でした。これはUriからではなくリソースに対応するStreamから直接ロードしようとしているためだと思われます。 * ドキュメントが未整備なサードパーティライブラリなどの調査には使えるかもしれません。 3. `ResourceManager.GetObject(string, CultureInfo, bool)`メソッド: * DLLからリソース(.xaml,.bamlなど)を取得するときに呼び出されるメソッドです。publicなメソッドの内部で呼ばれます。 * 引数`name`によりリソース名、インスタンスの`MainAssembly`プロパティからは対応するDLLの情報が取得できるようです。 * `name`から`themes/aero2.normalcolor.baml`を見つけることができました。 これらの調査ではロードされているDLLやXAMLがわかるだけで、実際のWPFのTreeでどう適用されているかまでは確信を持てませんが、当初の目的は達成できたのでここまでとしました。 技術的な興味として、以上のような調査をReflection的に(つまりコードで)実施する方法について、引き続き回答を募りたいと思います。 なにか知見をお持ちの方がいらっしゃれば、ぜひお教えください。