From 05e5ceeb43d3aa0175080bd6141f3b2228570b23 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 29 Nov 2025 23:11:01 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E8=AE=A1=E6=97=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改进主题加载 --- Ink Canvas/MainWindow.xaml | 2 - Ink Canvas/MainWindow_cs/MW_AutoTheme.cs | 11 + Ink Canvas/Windows/MinimizedTimerControl.xaml | 2 - .../Windows/MinimizedTimerControl.xaml.cs | 120 ++++- Ink Canvas/Windows/MinimizedTimerWindow.xaml | 126 ----- .../Windows/MinimizedTimerWindow.xaml.cs | 477 ------------------ Ink Canvas/Windows/TimerControl.xaml | 2 - Ink Canvas/Windows/TimerControl.xaml.cs | 51 +- 8 files changed, 172 insertions(+), 619 deletions(-) delete mode 100644 Ink Canvas/Windows/MinimizedTimerWindow.xaml delete mode 100644 Ink Canvas/Windows/MinimizedTimerWindow.xaml.cs diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 6ffa66b6..3a6ecac9 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -38,8 +38,6 @@ - - diff --git a/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs b/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs index 005f548e..9b636ef2 100644 --- a/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs +++ b/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs @@ -536,6 +536,17 @@ namespace Ink_Canvas operatingGuideWindow.RefreshTheme(); } } + + // 刷新计时器控件 + if (TimerControl != null) + { + TimerControl.RefreshTheme(); + } + + if (MinimizedTimerControl != null) + { + MinimizedTimerControl.RefreshTheme(); + } } catch (Exception) { diff --git a/Ink Canvas/Windows/MinimizedTimerControl.xaml b/Ink Canvas/Windows/MinimizedTimerControl.xaml index 59a2ff80..d3b08ecf 100644 --- a/Ink Canvas/Windows/MinimizedTimerControl.xaml +++ b/Ink Canvas/Windows/MinimizedTimerControl.xaml @@ -9,8 +9,6 @@ - - diff --git a/Ink Canvas/Windows/MinimizedTimerControl.xaml.cs b/Ink Canvas/Windows/MinimizedTimerControl.xaml.cs index 7d92fb85..603db416 100644 --- a/Ink Canvas/Windows/MinimizedTimerControl.xaml.cs +++ b/Ink Canvas/Windows/MinimizedTimerControl.xaml.cs @@ -5,6 +5,8 @@ using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; +using Microsoft.Win32; +using iNKORE.UI.WPF.Modern; namespace Ink_Canvas.Windows { @@ -26,11 +28,17 @@ namespace Ink_Canvas.Windows ApplyTheme(); + // 监听主题变化事件 + SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; + Unloaded += MinimizedTimerControl_Unloaded; } private void MinimizedTimerControl_Unloaded(object sender, RoutedEventArgs e) { + // 取消订阅主题变化事件 + SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged; + if (parentControl != null) { parentControl.TimerCompleted -= ParentControl_TimerCompleted; @@ -42,6 +50,34 @@ namespace Ink_Canvas.Windows updateTimer.Dispose(); } } + + private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + // 当主题变化时,重新应用主题 + Application.Current.Dispatcher.Invoke(() => + { + RefreshTheme(); + }); + } + + /// + /// 刷新主题 + /// + public void RefreshTheme() + { + try + { + // 重新应用主题 + ApplyTheme(); + + // 强制刷新UI + InvalidateVisual(); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"刷新最小化计时器窗口主题出错: {ex.Message}"); + } + } public void SetParentControl(TimerControl parent) { @@ -202,7 +238,7 @@ namespace Ink_Canvas.Windows } else { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; + var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush; if (defaultBrush != null) { path.Fill = defaultBrush; @@ -229,7 +265,7 @@ namespace Ink_Canvas.Windows } else { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; + var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush; if (defaultBrush != null) { colon1.Foreground = defaultBrush; @@ -250,7 +286,7 @@ namespace Ink_Canvas.Windows } else { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; + var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush; if (defaultBrush != null) { colon2.Foreground = defaultBrush; @@ -268,10 +304,17 @@ namespace Ink_Canvas.Windows { try { - bool isLightTheme = IsLightTheme(); - if (!isLightTheme) + if (MainWindow.Settings != null) { - SetDarkThemeBorder(); + ApplyTheme(MainWindow.Settings); + } + else + { + bool isLightTheme = IsLightTheme(); + if (!isLightTheme) + { + SetDarkThemeBorder(); + } } } catch (Exception ex) @@ -279,6 +322,70 @@ namespace Ink_Canvas.Windows System.Diagnostics.Debug.WriteLine($"应用主题时出错: {ex.Message}"); } } + + private void ApplyTheme(Settings settings) + { + try + { + if (settings.Appearance.Theme == 0) // 浅色主题 + { + ThemeManager.SetRequestedTheme(this, ElementTheme.Light); + } + else if (settings.Appearance.Theme == 1) // 深色主题 + { + ThemeManager.SetRequestedTheme(this, ElementTheme.Dark); + SetDarkThemeBorder(); + } + else // 跟随系统主题 + { + bool isSystemLight = IsSystemThemeLight(); + if (isSystemLight) + { + ThemeManager.SetRequestedTheme(this, ElementTheme.Light); + } + else + { + ThemeManager.SetRequestedTheme(this, ElementTheme.Dark); + SetDarkThemeBorder(); + } + } + + // 刷新数字和冒号显示的颜色 + if (parentControl != null) + { + UpdateTimeDisplay(); + } + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"应用最小化计时器窗口主题出错: {ex.Message}"); + } + } + + private bool IsSystemThemeLight() + { + var light = false; + try + { + var registryKey = Microsoft.Win32.Registry.CurrentUser; + var themeKey = registryKey.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"); + if (themeKey != null) + { + var value = themeKey.GetValue("AppsUseLightTheme"); + if (value != null) + { + light = (int)value == 1; + } + themeKey.Close(); + } + } + catch + { + // 如果读取注册表失败,默认为浅色主题 + light = true; + } + return light; + } private bool IsLightTheme() { @@ -469,3 +576,4 @@ namespace Ink_Canvas.Windows } } + diff --git a/Ink Canvas/Windows/MinimizedTimerWindow.xaml b/Ink Canvas/Windows/MinimizedTimerWindow.xaml deleted file mode 100644 index 6693df4c..00000000 --- a/Ink Canvas/Windows/MinimizedTimerWindow.xaml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Ink Canvas/Windows/MinimizedTimerWindow.xaml.cs b/Ink Canvas/Windows/MinimizedTimerWindow.xaml.cs deleted file mode 100644 index b095f336..00000000 --- a/Ink Canvas/Windows/MinimizedTimerWindow.xaml.cs +++ /dev/null @@ -1,477 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Interop; -using System.Windows.Media; -using System.Windows.Shapes; -using System.Windows.Media.Animation; - -namespace Ink_Canvas.Windows -{ - public partial class MinimizedTimerWindow : Window - { - private TimerControl parentControl; - private System.Timers.Timer updateTimer; - private bool isMouseOver = false; - private bool isDragging = false; - private Point lastMousePosition; - - public MinimizedTimerWindow(TimerControl parent) - { - InitializeComponent(); - parentControl = parent; - - var mainWindow = Application.Current.MainWindow as MainWindow; - if (mainWindow != null) - { - this.Left = mainWindow.Left; - this.Top = mainWindow.Top; - } - - ScaleWindowForResolution(); - - updateTimer = new System.Timers.Timer(100); - updateTimer.Elapsed += UpdateTimer_Elapsed; - updateTimer.Start(); - - parentControl.TimerCompleted += ParentWindow_TimerCompleted; - - // 应用主题 - ApplyTheme(); - - // 确保窗口置顶 - Loaded += MinimizedTimerWindow_Loaded; - } - - private void MinimizedTimerWindow_Loaded(object sender, RoutedEventArgs e) - { - // 使用延迟确保窗口完全加载后再应用置顶 - Dispatcher.BeginInvoke(new Action(() => - { - ApplyTopmost(); - }), System.Windows.Threading.DispatcherPriority.Loaded); - } - - #region Win32 API 声明和置顶管理 - [DllImport("user32.dll")] - private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); - - [DllImport("user32.dll")] - private static extern int GetWindowLong(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll")] - private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); - - private const int GWL_EXSTYLE = -20; - private const int WS_EX_TOPMOST = 0x00000008; - private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); - private const uint SWP_NOMOVE = 0x0002; - private const uint SWP_NOSIZE = 0x0001; - private const uint SWP_NOACTIVATE = 0x0010; - private const uint SWP_SHOWWINDOW = 0x0040; - - /// - /// 应用最小化窗口置顶 - /// - private void ApplyTopmost() - { - try - { - var hwnd = new WindowInteropHelper(this).Handle; - if (hwnd == IntPtr.Zero) return; - - // 设置WPF的Topmost属性 - Topmost = true; - - // 使用Win32 API强制置顶 - int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); - SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST); - - // 使用SetWindowPos确保窗口在最顶层 - SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"应用最小化窗口置顶失败: {ex.Message}"); - } - } - #endregion - - /// - /// 根据屏幕分辨率和 DPI 缩放窗口大小(保持原始尺寸,使用Transform缩放) - /// - private void ScaleWindowForResolution() - { - try - { - // 获取屏幕尺寸(考虑 DPI 缩放) - double screenWidth = SystemParameters.PrimaryScreenWidth; - double screenHeight = SystemParameters.PrimaryScreenHeight; - - // 基准分辨率(1920x1080) - const double baseWidth = 1920.0; - const double baseHeight = 1080.0; - - // 计算缩放比例(使用较小的比例以保持比例) - double scaleX = screenWidth / baseWidth; - double scaleY = screenHeight / baseHeight; - double scale = Math.Min(scaleX, scaleY); - - // 限制最小和最大缩放,避免过小或过大 - scale = Math.Max(0.5, Math.Min(2.0, scale)); - - // 应用缩放变换到整个窗口内容 - var scaleTransform = this.FindName("WindowScaleTransform") as ScaleTransform; - if (scaleTransform != null) - { - scaleTransform.ScaleX = scale; - scaleTransform.ScaleY = scale; - } - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"缩放窗口大小时出错: {ex.Message}"); - } - } - - private void UpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) - { - if (parentControl != null) - { - Application.Current.Dispatcher.Invoke(() => - { - if (ShouldCloseWindow()) - { - this.Close(); - return; - } - - UpdateTimeDisplay(); - }); - } - } - - private bool ShouldCloseWindow() - { - if (parentControl == null) return true; - - if (MainWindow.Settings.RandSettings?.EnableOvertimeCountUp == true) - { - if (parentControl.IsTimerRunning) - { - return false; - } - - var remainingTime = parentControl.GetRemainingTime(); - if (remainingTime.HasValue && remainingTime.Value.TotalSeconds < 0) - { - return false; - } - - return true; - } - else - { - return !parentControl.IsTimerRunning; - } - } - - private void UpdateTimeDisplay() - { - if (parentControl == null) return; - - var remainingTime = parentControl.GetRemainingTime(); - if (remainingTime.HasValue) - { - var timeSpan = remainingTime.Value; - bool isOvertimeMode = timeSpan.TotalSeconds < 0; - bool shouldShowRed = isOvertimeMode && MainWindow.Settings.RandSettings?.EnableOvertimeRedText == true; - - int hours, minutes, seconds; - - if (isOvertimeMode) - { - var totalTimeSpan = parentControl.GetTotalTimeSpan(); - if (totalTimeSpan.HasValue) - { - var elapsedTime = parentControl.GetElapsedTime(); - if (elapsedTime.HasValue) - { - var overtimeSpan = elapsedTime.Value - totalTimeSpan.Value; - hours = (int)overtimeSpan.TotalHours; - minutes = overtimeSpan.Minutes; - seconds = overtimeSpan.Seconds; - } - else - { - hours = 0; - minutes = 0; - seconds = 0; - } - } - else - { - hours = 0; - minutes = 0; - seconds = 0; - } - } - else - { - hours = (int)timeSpan.TotalHours; - minutes = timeSpan.Minutes; - seconds = timeSpan.Seconds; - } - - SetDigitDisplay("MinHour1Display", Math.Abs(hours / 10) % 10, shouldShowRed); - SetDigitDisplay("MinHour2Display", (hours % 10 + 10) % 10, shouldShowRed); - - SetDigitDisplay("MinMinute1Display", minutes / 10, shouldShowRed); - SetDigitDisplay("MinMinute2Display", minutes % 10, shouldShowRed); - - SetDigitDisplay("MinSecond1Display", seconds / 10, shouldShowRed); - SetDigitDisplay("MinSecond2Display", seconds % 10, shouldShowRed); - - SetColonDisplay(shouldShowRed); - } - } - - private void ParentWindow_TimerCompleted(object sender, EventArgs e) - { - Application.Current.Dispatcher.Invoke(() => - { - this.Close(); - }); - } - - private void SetDigitDisplay(string pathName, int digit, bool isRed = false) - { - var path = this.FindName(pathName) as Path; - if (path != null) - { - string resourceKey = $"Digit{digit}"; - var geometry = this.FindResource(resourceKey) as Geometry; - if (geometry != null) - { - path.Data = geometry; - } - - // 设置颜色 - if (isRed) - { - path.Fill = Brushes.Red; - } - else - { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; - if (defaultBrush != null) - { - path.Fill = defaultBrush; - } - else - { - bool isLightTheme = IsLightTheme(); - path.Fill = isLightTheme ? Brushes.Black : Brushes.White; - } - } - } - } - - /// - /// 设置最小化窗口冒号显示颜色 - /// - /// 是否显示为红色 - private void SetColonDisplay(bool isRed = false) - { - var colon1 = this.FindName("MinColon1Display") as TextBlock; - var colon2 = this.FindName("MinColon2Display") as TextBlock; - - if (colon1 != null) - { - if (isRed) - { - colon1.Foreground = Brushes.Red; - } - else - { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; - if (defaultBrush != null) - { - colon1.Foreground = defaultBrush; - } - else - { - bool isLightTheme = IsLightTheme(); - colon1.Foreground = isLightTheme ? Brushes.Black : Brushes.White; - } - } - } - - if (colon2 != null) - { - if (isRed) - { - colon2.Foreground = Brushes.Red; - } - else - { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; - if (defaultBrush != null) - { - colon2.Foreground = defaultBrush; - } - else - { - bool isLightTheme = IsLightTheme(); - colon2.Foreground = isLightTheme ? Brushes.Black : Brushes.White; - } - } - } - } - - private void ApplyTheme() - { - try - { - - bool isLightTheme = IsLightTheme(); - if (!isLightTheme) - { - SetDarkThemeBorder(); - } - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"应用主题时出错: {ex.Message}"); - } - } - - private bool IsLightTheme() - { - try - { - var mainWindow = Application.Current.MainWindow as MainWindow; - if (mainWindow != null) - { - var currentModeField = mainWindow.GetType().GetField("currentMode", - System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - if (currentModeField != null) - { - var currentMode = currentModeField.GetValue(mainWindow); - return currentMode?.ToString() == "Light"; - } - } - } - catch - { - // 如果获取主题失败,默认使用浅色主题 - } - return true; - } - - // 设置深色主题下的灰色边框 - private void SetDarkThemeBorder() - { - try - { - // 找到Border元素并设置灰色边框 - var border = this.FindName("MainBorder") as Border; - if (border != null) - { - border.BorderBrush = new SolidColorBrush(Color.FromRgb(64, 64, 64)); - } - } - catch - { - } - } - - private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) - { - // 记录点击时间 - lastClickTime = DateTime.Now; - // 开始拖动 - isDragging = true; - lastMousePosition = e.GetPosition(this); - this.CaptureMouse(); - } - - private void Window_MouseMove(object sender, MouseEventArgs e) - { - if (isDragging) - { - var currentPosition = e.GetPosition(this); - var deltaX = currentPosition.X - lastMousePosition.X; - var deltaY = currentPosition.Y - lastMousePosition.Y; - - this.Left += deltaX; - this.Top += deltaY; - } - } - - private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) - { - if (isDragging) - { - isDragging = false; - this.ReleaseMouseCapture(); - - var clickDuration = DateTime.Now - lastClickTime; - if (clickDuration.TotalMilliseconds < 200) - { - this.Close(); - } - } - } - - private DateTime lastClickTime = DateTime.Now; - - private void Window_MouseEnter(object sender, MouseEventArgs e) - { - isMouseOver = true; - // 鼠标进入时显示关闭按钮 - if (CloseButton != null) - { - CloseButton.Opacity = 1.0; - } - } - - private void Window_MouseLeave(object sender, MouseEventArgs e) - { - isMouseOver = false; - // 鼠标离开时隐藏关闭按钮 - if (CloseButton != null) - { - CloseButton.Opacity = 0.7; - } - } - - private void CloseButton_Click(object sender, RoutedEventArgs e) - { - if (parentControl != null) - { - parentControl.StopTimer(); - } - this.Close(); - } - - protected override void OnClosed(EventArgs e) - { - if (parentControl != null) - { - parentControl.TimerCompleted -= ParentWindow_TimerCompleted; - } - - // 清理资源 - if (updateTimer != null) - { - updateTimer.Stop(); - updateTimer.Dispose(); - } - base.OnClosed(e); - } - } -} diff --git a/Ink Canvas/Windows/TimerControl.xaml b/Ink Canvas/Windows/TimerControl.xaml index 280c913c..02f931f3 100644 --- a/Ink Canvas/Windows/TimerControl.xaml +++ b/Ink Canvas/Windows/TimerControl.xaml @@ -12,8 +12,6 @@ - - diff --git a/Ink Canvas/Windows/TimerControl.xaml.cs b/Ink Canvas/Windows/TimerControl.xaml.cs index a290419c..4ea97948 100644 --- a/Ink Canvas/Windows/TimerControl.xaml.cs +++ b/Ink Canvas/Windows/TimerControl.xaml.cs @@ -10,7 +10,7 @@ using System.Windows.Media; using System.Windows.Shapes; using Newtonsoft.Json; using System.Windows.Threading; - +using Microsoft.Win32; namespace Ink_Canvas.Windows { /// @@ -46,6 +46,46 @@ namespace Ink_Canvas.Windows hideTimer = new Timer(1000); // 每秒检查一次 hideTimer.Elapsed += HideTimer_Elapsed; lastActivityTime = DateTime.Now; + + // 监听主题变化事件 + SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; + + // 监听卸载事件,清理资源 + Unloaded += TimerControl_Unloaded; + } + + private void TimerControl_Unloaded(object sender, RoutedEventArgs e) + { + // 取消订阅主题变化事件 + SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged; + } + + private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + // 当主题变化时,重新应用主题 + Application.Current.Dispatcher.Invoke(() => + { + RefreshTheme(); + }); + } + + /// + /// 刷新主题(供外部调用) + /// + public void RefreshTheme() + { + try + { + // 重新应用主题 + ApplyTheme(); + + // 强制刷新UI + InvalidateVisual(); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"刷新计时器窗口主题出错: {ex.Message}", LogHelper.LogType.Error); + } } #region 事件定义 @@ -296,6 +336,9 @@ namespace Ink_Canvas.Windows SetDarkThemeBorder(); } } + + // 刷新数字和冒号显示的颜色 + UpdateDigitDisplays(); } catch (Exception ex) { @@ -457,7 +500,7 @@ namespace Ink_Canvas.Windows } else { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; + var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush; if (defaultBrush != null) { path.Fill = defaultBrush; @@ -487,7 +530,7 @@ namespace Ink_Canvas.Windows } else { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; + var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush; if (defaultBrush != null) { colon1.Foreground = defaultBrush; @@ -507,7 +550,7 @@ namespace Ink_Canvas.Windows } else { - var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush; + var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush; if (defaultBrush != null) { colon2.Foreground = defaultBrush;