SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

FluentWPF 0.10.0をリリースしました

FluentWPF 0.10.0をリリースしました。
今回は、ウィンドウのアクリル効果の改善を中心に、結構手を入れています。

新機能

AcrylicWindowのアクリル効果改善

Windows10 1903以降でも、UWP風のアクリル効果を使えるように対応

FluentWPFでは、SetWindowCompositionAttributeという非公開Win32APIを使い、ウィンドウへのアクリル効果を適用しています。
しかし、Windows10 1903以降では、このAPIを使うとウィンドウ移動やリサイズ時に描画がカクつく問題がありました。 現時点でも、この問題は解決される見込みはありません(そもそも非公開APIですし・・・)
そこで、ウィンドウの移動やリサイズ中は、ぼかし効果の弱い別種表示に切り替えるようにして、この問題を回避しています。

f:id:minami_SC:20210812123954g:plain

アクリル効果の有効/無効切替

AcrylicWindow.Enabled指定でアクリル化した場合には、プログラム実行中にもアクリル効果の有効/無効を切り替えられるようにしました。

<Window x:Class="FluentWPFSample.Views.AcrylicWindow2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FluentWPFSample.Views"
        xmlns:fw="clr-namespace:SourceChord.FluentWPF;assembly=FluentWPF"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="AcrylicWindow2" Height="450" Width="800"
        ResizeMode="CanResizeWithGrip"
        MaxWidth="950" MaxHeight="600"
        fw:AcrylicWindow.Enabled="{Binding IsChecked, ElementName=chkIsEnabled}"
        Icon="/Assets/Images/logo_icon.png">
    <Grid>
        <CheckBox x:Name="chkIsEnabled"
                  Content="AcrylicWindow.Enabled" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"
                  IsChecked="False"/>
    </Grid>
</Window>

f:id:minami_SC:20210812124101g:plain

アクリル効果の種別手動設定・・・・AcrylicWindow.AcrylicAccentStateプロパティ

AcrylicWindow.AcrylicAccentStateというプロパティで、アクリル効果の種別を指定できるようにしました。
このプロパティで、SetWindowCompositionAttribute関数の引数に指定するパラメータを手動で指定できます。

<fw:AcrylicWindow x:Class="FluentWPFSample.Views.AcrylicWindow3"
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                  xmlns:fw="clr-namespace:SourceChord.FluentWPF;assembly=FluentWPF"
                  xmlns:sys="clr-namespace:System;assembly=mscorlib"
                  xmlns:local="clr-namespace:FluentWPFSample.Views"
                  mc:Ignorable="d"
                  Title="AcrylicWindow3" Height="450" Width="800"
                  ResizeMode="CanResizeWithGrip"
                  fw:AcrylicWindow.AcrylicAccentState="BlurBehind">

(既定では「Default」という設定になっており、OSのバージョンに応じて最適な設定を使います。)

設定内容を変えると、それぞれ以下のような表示になります。 f:id:minami_SC:20210812124030g:plain

ウィンドウ最大化時の表示不具合修正

今まで、マルチディスプレイ環境にてFluentWPFでアクリル化したウィンドウを最大化すると、となりのディスプレイ領域にこんな風にぼかし効果の効いた領域がはみ出す、、という問題がありました。
今回のリリースで、この問題を修正してます。
f:id:minami_SC:20210812122904p:plain

これは、対応するのはかなり大変でした・・・
Windowsでは、ウィンドウを最大化するとHWNDレベルではディスプレイ領域外まではみ出した大きさのウィンドウになってます。
最大化表示するときには、各種UI表示用のフレームワークがウィンドウ領域外の部分はクリッピング表示することで、余計な部分が表示されないようになってます。

しかし、FluentWPFで使っているSetWindowCompositionAttribute関数を呼び出すと、このディスプレイ領域外の部分まで含めてアクリル効果がかかってしまい、この問題が起きてました。てことで、ウィンドウ最大化時のウィンドウサイズなどを色々制御することで、この問題に対応してます。

Win32APIを多用した、結構面倒な対応しているので、機会があれば今回対応した内容を別途記事にまとめようと思います。

アクリル効果付きのメッセージボックス(AcrylicMessageBox)

AcrylicMessageBoxというコントロールを追加しました。
WPF標準のMessageBoxと似たようなIFで、以下のようなStaticメソッド呼出しでアクリル効果付きのメッセージボックスを表示できます。

var result1 = AcrylicMessageBox.Show(this, "This is AcrylicMessageBox\nTest", "Title", MessageBoxButton.OK);
var result2 = AcrylicMessageBox.Show(this, "This is AcrylicMessageBox\nTest", "Title", MessageBoxButton.OKCancel);
var result3 = AcrylicMessageBox.Show(this, "This is AcrylicMessageBox\nTest", "Title", MessageBoxButton.YesNoCancel);
var result4 = AcrylicMessageBox.Show(this, "This is AcrylicMessageBox\nTest", "Title", MessageBoxButton.YesNo);

f:id:minami_SC:20210812121359p:plain

MahApps.Metroとの連携表示

FluentWPFでは、添付プロパティ設定でアクリル効果を有効化でき、MahApps.Metroなどその他のWPF向けUIフレームワークで作成したウィンドウとも共存できるような仕組みとしてました。(※下記記事参照)

添付プロパティとしてAcrylicなウィンドウを作成できるようにしているので、MahApps.Metroのような独自ウィンドウクラスを用いるライブラリとも併用できます。

WPFでFluent Design Systemを再現するライブラリを作ってみました~FluentWPF~ - SourceChord

ですが、MahApps.MetroとFluentWPF双方のバージョンアップに伴い、この方法では正しく連携できなくなってました。
今回AcrylicWindowなどの仕組みに色々手を入れながら、この問題も一緒に修正しています。

以下のようなコードで、MahApps.Metroで作ったウィンドウにアクリル効果を適用できます。

<mah:MetroWindow x:Class="MahAppsTest.MainWindow"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:fw="clr-namespace:SourceChord.FluentWPF;assembly=FluentWPF"
                 xmlns:local="clr-namespace:MahAppsTest"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 Title="MainWindow"
                 Width="525"
                 Height="350"
                 fw:AcrylicWindow.Enabled="True"
                 fw:AcrylicWindow.AcrylicWindowStyle="None"
                 BorderThickness="0"
                 GlowBrush="Black"
                 mc:Ignorable="d">
    <Grid>
        <TextBlock Margin="5" Text="Hello World!!" />
        <Button Content="Button" Width="75" Height="35" />
    </Grid>
</mah:MetroWindow>

f:id:minami_SC:20210812214334p:plain

不具合修正

その他、以下のような不具合対応をしてます。

  • Fix the issue that AcrylicBrush doesn't be rendered correctly without Width/Height properties(#10)
  • Fix the issue that sometimes TextBlock doesn't follow system themes(#120)
  • Fix the issue that DisplayMemberPath doesn't work with ComboBoxRevealStyle(#123)
  • Fix the issue that app crashes when referenced AccentColors before Application.Current.MainWindow initialized(#107)

今後の予定

気付けばGitHubのスター数も1000を超えました。
たくさんの方に使ってもらえ、また多くのフィードバックもいただけるようになりました。
改めて見返してみると、なかなか感慨深いものですね。 f:id:minami_SC:20210812144428p:plain

今後の予定ですが、以下のような対応を進めようと思ってます。

  • Windows11対応
    • Win11環境でのアクリル有効化
      ※現時点では、Windows11環境ではアクリル効果が正しく反映されません。
      そのため、FluentWPF 0.10.0では、Win11環境ではアクリル効果を無効化してます。
    • Mica対応・・・Win11で追加されるMicaマテリアルに対応できないか調査
    • 各種Reveal系スタイルの改善
      各種標準コントロール用のスタイル追加や、Windows11でのFluentDesignに合わせたスタイル定義修正
  • GitHubリポジトリの整備
    • GitHub ActionsでのCI環境作成
    • ドキュメント整備(Wiki or README or GitHub Pages)