モノトーンの伝説日記

Apex Legends, Splatoon, Programming, and so on...

System Menu のテーマ切り替えに不具合? (1909/2004 のみで確認済み; 回避策掲載済み)

1. 特定の AppMode 切り替えの場合,正常に AppMode が切り替わらない。

 これは RS6 1903 以降の環境に有効な内容です。

enum PreferredAppMode
{
  APPMODE_DEFAULT = 0,
  APPMODE_ALLOWDARK = 1,
  APPMODE_FORCEDARK = 2,
  APPMODE_FORCELIGHT = 3,
  APPMODE_MAX = 4
}

[DllImport("uxtheme.dll", EntryPoint = "#104")]
static extern void RefreshImmersiveColorPolicyState();

[DllImport("uxtheme.dll", EntryPoint = "#135")]
static extern PreferredAppMode SetPreferredAppMode(PreferredAppMode appMode); // RS6 1903

という関数があるのですが,これの挙動がおかしいという話。

 なお,RS5 1809 では同じエントリーポイントで Allow Dark のみが使える感じです。

[DllImport("uxtheme.dll", EntryPoint = "#135")]
static extern bool AllowDarkModeForApp(bool bAllowDarkMode); // RS5 1809

 テーマの切り替えをアプリ側でしたいケースが存在すると思うのですが,その場合,FORCEDARK や FORCELIGHT を使うことになると思うんですが,

  • (OS: Light) FORCEDARK (2) → DEFAULT (0), FORCELIGHT (3)
  • (OS: Dark) ALLOWDARK (1), FORCEDARK (2) → DEFAULT (0), FORCELIGHT (3)

のケースのみ,AppMode が正常に変わらないという問題を抱えています。

 ちなみに,SetPreferredAppMode のあと RefreshImmersiveColorPolicyState を呼ばないと正常にテーマ変更されないのでご注意を。

 この不具合は 1909 と 20H1 で発生しています(1909 以前のバージョンは調べていません。そもそも 1909 と 20H1 以外手元に持ち合わせていないのですが……)。

7/27追記: 回避策は FORCELIGHT をセットしたいときに事前にテキトーなものをセット,リロードすれば良さげです。

if (appMode == PreferredAppMode.APPMODE_DEFAULT
  || appMode == PreferredAppMode.APPMODE_FORCELIGHT)
{
  SetPreferredAppMode(PreferredAppMode.APPMODE_ALLOWDARK);
  RefreshImmersiveColorPolicyState();
}

var ret = SetPreferredAppMode(appMode) == appMode;
RefreshImmersiveColorPolicyState();
return ret;

2. Win32 の Dark Mode 実装の参考に

 こういうものが GitHub で公開されています。

github.com

 実はまだこの Win32 のテーマ切り替えの全容理解していなくて,ハイコントラストのときどのように動作するとかいまいちよくわかっていません…… 非公開 API な上,API が洗練されていないっぽいし,上記に書いた通り不具合もあるようですし……

 ちなみに,MetroRadiance で動作させた場合こんな感じです。

f:id:mntone:20200727171947p:plain

 System Menu とか使っている人少なさそうなので,完全に趣味の領域ですけどね(CaptionIcon クリック or タイトルバー領域の右クリック)。

github.com

まとめ

 Dark Theme も Acrylic Blur も WinUI でやれ! 感すごいですね。WinUI 3 preview 2 だとまだ実用アプリ組むのには条件的にしんどいと思っていて……

 preview 3 になったら実用的なアプリ作れるのかなぁ🤔 って感じですね。