From 1cb9c862d4d252c718f2cce04bfeb178d44f2205 Mon Sep 17 00:00:00 2001 From: mntone Date: Mon, 10 Aug 2020 01:09:02 +0900 Subject: [PATCH] Add updating the displays and taskbar position. --- .../UI/Bindings/SettingsWindowViewModel.cs | 69 +++++++++++++------ source/SylphyHorn/UI/SettingsWindow.xaml.cs | 50 +++++++++++++- 2 files changed, 98 insertions(+), 21 deletions(-) diff --git a/source/SylphyHorn/UI/Bindings/SettingsWindowViewModel.cs b/source/SylphyHorn/UI/Bindings/SettingsWindowViewModel.cs index 8047e81..96c82de 100644 --- a/source/SylphyHorn/UI/Bindings/SettingsWindowViewModel.cs +++ b/source/SylphyHorn/UI/Bindings/SettingsWindowViewModel.cs @@ -27,9 +27,29 @@ public class SettingsWindowViewModel : WindowViewModel public IReadOnlyCollection> Placements { get; } - public bool IsDisplayEnabled { get; } + public bool IsDisplayEnabled => this.Displays.Count > 3; - public IReadOnlyCollection> Displays { get; } + #region Displays notification property + + public IReadOnlyCollection> _Displays; + + public IReadOnlyCollection> Displays + { + get => this._Displays; + set + { + if (this._Displays != value) + { + this._Displays = value; + + this.RaisePropertyChanged(); + this.RaisePropertyChanged(nameof(this.Display)); + this.RaisePropertyChanged(nameof(this.IsDisplayEnabled)); + } + } + } + + #endregion public IReadOnlyCollection Licenses { get; } @@ -257,23 +277,7 @@ public SettingsWindowViewModel(HookService hookService) new DisplayViewModel { Display = Resources.Settings_NotificationWindowPlacement_BottomRight, Value = WindowPlacement.BottomRight, }, }.ToList(); - this.Displays = new[] { new DisplayViewModel { Display = Resources.Settings_MultipleDisplays_CurrentDisplay, Value = 0, } } - .Concat(MonitorService.GetMonitors() - .Select((m, i) => new DisplayViewModel - { - Display = string.Format(Resources.Settings_MultipleDisplays_EachDisplay, i + 1, m.Name), - Value = (uint)(i + 1), - })) - .Concat(new[] - { - new DisplayViewModel - { - Display = Resources.Settings_MultipleDisplays_AllDisplays, - Value = uint.MaxValue, - } - }) - .ToList(); - if (this.Displays.Count > 3) this.IsDisplayEnabled = true; + this.UpdateDisplays(); this.Licenses = LicenseInfo.All.Select(x => new LicenseViewModel(x)).ToArray(); @@ -287,7 +291,7 @@ public SettingsWindowViewModel(HookService hookService) this.PreviewBackgroundBrush = new SolidColorBrush(colAndWall.BackgroundColor); this.PreviewBackgroundPath = colAndWall.Path; this.PreviewBackgroundPosition = colAndWall.Position; - this.PreviewTaskbarPosition = GetTaskbarPosition(); + this.UpdateTaskbarPosition(); this.Logs = ViewModelHelper.CreateReadOnlyDispatcherCollection( LoggingService.Instance.Logs, @@ -314,6 +318,31 @@ public SettingsWindowViewModel(HookService hookService) .AddTo(this); } + public void UpdateDisplays() + { + this.Displays = new[] { new DisplayViewModel { Display = Resources.Settings_MultipleDisplays_CurrentDisplay, Value = 0, } } + .Concat(MonitorService.GetMonitors() + .Select((m, i) => new DisplayViewModel + { + Display = string.Format(Resources.Settings_MultipleDisplays_EachDisplay, i + 1, m.Name), + Value = (uint)(i + 1), + })) + .Concat(new[] + { + new DisplayViewModel + { + Display = Resources.Settings_MultipleDisplays_AllDisplays, + Value = uint.MaxValue, + } + }) + .ToList(); + } + + public void UpdateTaskbarPosition() + { + this.PreviewTaskbarPosition = GetTaskbarPosition(); + } + protected override void InitializeCore() { base.InitializeCore(); diff --git a/source/SylphyHorn/UI/SettingsWindow.xaml.cs b/source/SylphyHorn/UI/SettingsWindow.xaml.cs index f571ecc..1126d5b 100644 --- a/source/SylphyHorn/UI/SettingsWindow.xaml.cs +++ b/source/SylphyHorn/UI/SettingsWindow.xaml.cs @@ -1,9 +1,11 @@ -using SylphyHorn.UI.Bindings; +using MetroRadiance.Interop.Win32; +using SylphyHorn.UI.Bindings; using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Input; +using System.Windows.Interop; using WindowsDesktop; namespace SylphyHorn.UI @@ -12,6 +14,8 @@ partial class SettingsWindow { public static SettingsWindow Instance { get; set; } + private HwndSource _source; + public SettingsWindow() { this.InitializeComponent(); @@ -28,12 +32,56 @@ protected override void OnInitialized(EventArgs e) .AddValueChanged(this.PreviewRoot, this.OnPreviewRootCanvasPositionChanged); } + protected override void OnSourceInitialized(EventArgs e) + { + base.OnSourceInitialized(e); + + this._source = PresentationSource.FromVisual(this) as HwndSource; + if (this._source == null) return; + this._source.AddHook(this.WndProc); + } + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + + this._source?.RemoveHook(this.WndProc); + } + protected override void OnContentRendered(EventArgs e) { base.OnContentRendered(e); this.Pin(); } + private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + // Note: "Duplicated" and "Extended" change notification events will be received. + if (msg == (int)WindowsMessages.WM_SETTINGCHANGE) + { + if (wParam == new IntPtr(47) /* SPI_SETWORKAREA */) + { + this.UpdateViewModel(ref handled, taskbarPosition: true); + } + } + else if (msg == (int)WindowsMessages.WM_DEVICECHANGE) + { + this.UpdateViewModel(ref handled); + } + return IntPtr.Zero; + } + + private void UpdateViewModel(ref bool handled, bool taskbarPosition = false) + { + var viewModel = this.DataContext as SettingsWindowViewModel; + if (viewModel != null) + { + viewModel.UpdateDisplays(); + if (taskbarPosition) viewModel.UpdateTaskbarPosition(); + handled = true; + } + } + private void OnPreviewRootCanvasPositionChanged(object sender, EventArgs e) => this.UpdatePreviewBlurImageMargin();