improve:计时器
改进主题加载
This commit is contained in:
@@ -38,8 +38,6 @@
|
|||||||
<!-- 合并新橡皮擦资源 -->
|
<!-- 合并新橡皮擦资源 -->
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceDictionary Source="MainWindow_cs/MW_Eraser.xaml"/>
|
<ResourceDictionary Source="MainWindow_cs/MW_Eraser.xaml"/>
|
||||||
<ResourceDictionary Source="Resources/Styles/Light.xaml"/>
|
|
||||||
<ResourceDictionary Source="Resources/Styles/Dark.xaml"/>
|
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
<c:IsEnabledToOpacityConverter x:Key="IsEnabledToOpacityConverter" />
|
<c:IsEnabledToOpacityConverter x:Key="IsEnabledToOpacityConverter" />
|
||||||
|
|||||||
@@ -536,6 +536,17 @@ namespace Ink_Canvas
|
|||||||
operatingGuideWindow.RefreshTheme();
|
operatingGuideWindow.RefreshTheme();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 刷新计时器控件
|
||||||
|
if (TimerControl != null)
|
||||||
|
{
|
||||||
|
TimerControl.RefreshTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MinimizedTimerControl != null)
|
||||||
|
{
|
||||||
|
MinimizedTimerControl.RefreshTheme();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceDictionary Source="DigitResources.xaml" />
|
<ResourceDictionary Source="DigitResources.xaml" />
|
||||||
<ResourceDictionary Source="/Resources/Styles/Light.xaml" />
|
|
||||||
<ResourceDictionary Source="/Resources/Styles/Dark.xaml" />
|
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using System.Windows.Controls;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using iNKORE.UI.WPF.Modern;
|
||||||
|
|
||||||
namespace Ink_Canvas.Windows
|
namespace Ink_Canvas.Windows
|
||||||
{
|
{
|
||||||
@@ -26,11 +28,17 @@ namespace Ink_Canvas.Windows
|
|||||||
|
|
||||||
ApplyTheme();
|
ApplyTheme();
|
||||||
|
|
||||||
|
// 监听主题变化事件
|
||||||
|
SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged;
|
||||||
|
|
||||||
Unloaded += MinimizedTimerControl_Unloaded;
|
Unloaded += MinimizedTimerControl_Unloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MinimizedTimerControl_Unloaded(object sender, RoutedEventArgs e)
|
private void MinimizedTimerControl_Unloaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
// 取消订阅主题变化事件
|
||||||
|
SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged;
|
||||||
|
|
||||||
if (parentControl != null)
|
if (parentControl != null)
|
||||||
{
|
{
|
||||||
parentControl.TimerCompleted -= ParentControl_TimerCompleted;
|
parentControl.TimerCompleted -= ParentControl_TimerCompleted;
|
||||||
@@ -43,6 +51,34 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
|
||||||
|
{
|
||||||
|
// 当主题变化时,重新应用主题
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
RefreshTheme();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 刷新主题
|
||||||
|
/// </summary>
|
||||||
|
public void RefreshTheme()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 重新应用主题
|
||||||
|
ApplyTheme();
|
||||||
|
|
||||||
|
// 强制刷新UI
|
||||||
|
InvalidateVisual();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"刷新最小化计时器窗口主题出错: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SetParentControl(TimerControl parent)
|
public void SetParentControl(TimerControl parent)
|
||||||
{
|
{
|
||||||
if (parentControl != null)
|
if (parentControl != null)
|
||||||
@@ -202,7 +238,7 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush;
|
var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush;
|
||||||
if (defaultBrush != null)
|
if (defaultBrush != null)
|
||||||
{
|
{
|
||||||
path.Fill = defaultBrush;
|
path.Fill = defaultBrush;
|
||||||
@@ -229,7 +265,7 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush;
|
var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush;
|
||||||
if (defaultBrush != null)
|
if (defaultBrush != null)
|
||||||
{
|
{
|
||||||
colon1.Foreground = defaultBrush;
|
colon1.Foreground = defaultBrush;
|
||||||
@@ -250,7 +286,7 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush;
|
var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush;
|
||||||
if (defaultBrush != null)
|
if (defaultBrush != null)
|
||||||
{
|
{
|
||||||
colon2.Foreground = defaultBrush;
|
colon2.Foreground = defaultBrush;
|
||||||
@@ -267,6 +303,12 @@ namespace Ink_Canvas.Windows
|
|||||||
private void ApplyTheme()
|
private void ApplyTheme()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if (MainWindow.Settings != null)
|
||||||
|
{
|
||||||
|
ApplyTheme(MainWindow.Settings);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
bool isLightTheme = IsLightTheme();
|
bool isLightTheme = IsLightTheme();
|
||||||
if (!isLightTheme)
|
if (!isLightTheme)
|
||||||
@@ -274,12 +316,77 @@ namespace Ink_Canvas.Windows
|
|||||||
SetDarkThemeBorder();
|
SetDarkThemeBorder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine($"应用主题时出错: {ex.Message}");
|
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()
|
private bool IsLightTheme()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -469,3 +576,4 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
<Window x:Class="Ink_Canvas.Windows.MinimizedTimerWindow"
|
|
||||||
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:Ink_Canvas.Windows"
|
|
||||||
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
|
|
||||||
Topmost="True" Background="Transparent"
|
|
||||||
mc:Ignorable="d" WindowStyle="None" AllowsTransparency="True"
|
|
||||||
ResizeMode="NoResize"
|
|
||||||
WindowStartupLocation="Manual" Title="计时器" Height="200" Width="600"
|
|
||||||
MouseLeftButtonDown="Window_MouseLeftButtonDown" MouseLeftButtonUp="Window_MouseLeftButtonUp"
|
|
||||||
MouseEnter="Window_MouseEnter" MouseLeave="Window_MouseLeave" MouseMove="Window_MouseMove">
|
|
||||||
|
|
||||||
<Window.Resources>
|
|
||||||
<ResourceDictionary>
|
|
||||||
<ResourceDictionary.MergedDictionaries>
|
|
||||||
<ResourceDictionary Source="DigitResources.xaml" />
|
|
||||||
</ResourceDictionary.MergedDictionaries>
|
|
||||||
</ResourceDictionary>
|
|
||||||
</Window.Resources>
|
|
||||||
|
|
||||||
<Border x:Name="MainBorder" Background="{DynamicResource NewTimerWindowBackground}"
|
|
||||||
CornerRadius="15"
|
|
||||||
BorderThickness="1"
|
|
||||||
BorderBrush="{DynamicResource NewTimerWindowBorderBrush}"
|
|
||||||
Margin="0"
|
|
||||||
UseLayoutRounding="True"
|
|
||||||
SnapsToDevicePixels="True">
|
|
||||||
<Grid>
|
|
||||||
<!-- 时间显示 -->
|
|
||||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20,20,20,20">
|
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
|
||||||
<!-- 小时 -->
|
|
||||||
<Path x:Name="MinHour1Display" Data="{StaticResource Digit0}"
|
|
||||||
Fill="{DynamicResource NewTimerWindowDigitForeground}"
|
|
||||||
Width="72" Height="72"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Stretch="Uniform"
|
|
||||||
Margin="0,0,12,0"/>
|
|
||||||
<Path x:Name="MinHour2Display" Data="{StaticResource Digit0}"
|
|
||||||
Fill="{DynamicResource NewTimerWindowDigitForeground}"
|
|
||||||
Width="72" Height="72"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Stretch="Uniform"
|
|
||||||
Margin="0,0,12,0"/>
|
|
||||||
|
|
||||||
<!-- 冒号 -->
|
|
||||||
<TextBlock x:Name="MinColon1Display" Text=":" FontSize="48" FontWeight="Bold"
|
|
||||||
Foreground="{DynamicResource NewTimerWindowDigitForeground}"
|
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
||||||
Margin="0,0,12,0"/>
|
|
||||||
|
|
||||||
<!-- 分钟 -->
|
|
||||||
<Path x:Name="MinMinute1Display" Data="{StaticResource Digit0}"
|
|
||||||
Fill="{DynamicResource NewTimerWindowDigitForeground}"
|
|
||||||
Width="72" Height="72"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Stretch="Uniform"
|
|
||||||
Margin="0,0,12,0"/>
|
|
||||||
<Path x:Name="MinMinute2Display" Data="{StaticResource Digit0}"
|
|
||||||
Fill="{DynamicResource NewTimerWindowDigitForeground}"
|
|
||||||
Width="72" Height="72"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Stretch="Uniform"
|
|
||||||
Margin="0,0,12,0"/>
|
|
||||||
|
|
||||||
<!-- 冒号 -->
|
|
||||||
<TextBlock x:Name="MinColon2Display" Text=":" FontSize="48" FontWeight="Bold"
|
|
||||||
Foreground="{DynamicResource NewTimerWindowDigitForeground}"
|
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
||||||
Margin="0,0,12,0"/>
|
|
||||||
|
|
||||||
<!-- 秒 -->
|
|
||||||
<Path x:Name="MinSecond1Display" Data="{StaticResource Digit0}"
|
|
||||||
Fill="{DynamicResource NewTimerWindowDigitForeground}"
|
|
||||||
Width="72" Height="72"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Stretch="Uniform"
|
|
||||||
Margin="0,0,12,0"/>
|
|
||||||
<Path x:Name="MinSecond2Display" Data="{StaticResource Digit0}"
|
|
||||||
Fill="{DynamicResource NewTimerWindowDigitForeground}"
|
|
||||||
Width="72" Height="72"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Stretch="Uniform"
|
|
||||||
Margin="0,0,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- 关闭按钮 -->
|
|
||||||
<Button x:Name="CloseButton"
|
|
||||||
Width="24" Height="24"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
VerticalAlignment="Top"
|
|
||||||
Margin="0,8,8,0"
|
|
||||||
Background="Transparent"
|
|
||||||
BorderThickness="0"
|
|
||||||
Click="CloseButton_Click"
|
|
||||||
Cursor="Hand"
|
|
||||||
Opacity="0.7">
|
|
||||||
<Button.Template>
|
|
||||||
<ControlTemplate TargetType="Button">
|
|
||||||
<Border Background="{TemplateBinding Background}" CornerRadius="12">
|
|
||||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
||||||
</Border>
|
|
||||||
<ControlTemplate.Triggers>
|
|
||||||
<Trigger Property="IsMouseOver" Value="True">
|
|
||||||
<Setter Property="Background" Value="#E81123"/>
|
|
||||||
<Setter Property="Foreground" Value="White"/>
|
|
||||||
</Trigger>
|
|
||||||
</ControlTemplate.Triggers>
|
|
||||||
</ControlTemplate>
|
|
||||||
</Button.Template>
|
|
||||||
<TextBlock Text="✕" FontSize="12" FontWeight="Bold"
|
|
||||||
Foreground="{DynamicResource NewTimerWindowButtonForeground}"
|
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
</Window>
|
|
||||||
@@ -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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用最小化窗口置顶
|
|
||||||
/// </summary>
|
|
||||||
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
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据屏幕分辨率和 DPI 缩放窗口大小(保持原始尺寸,使用Transform缩放)
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置最小化窗口冒号显示颜色
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="isRed">是否显示为红色</param>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,8 +12,6 @@
|
|||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceDictionary Source="Controls/WinUI3CloseButton.xaml" />
|
<ResourceDictionary Source="Controls/WinUI3CloseButton.xaml" />
|
||||||
<ResourceDictionary Source="DigitResources.xaml" />
|
<ResourceDictionary Source="DigitResources.xaml" />
|
||||||
<ResourceDictionary Source="/Resources/Styles/Light.xaml" />
|
|
||||||
<ResourceDictionary Source="/Resources/Styles/Dark.xaml" />
|
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using System.Windows.Media;
|
|||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
using Microsoft.Win32;
|
||||||
namespace Ink_Canvas.Windows
|
namespace Ink_Canvas.Windows
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -46,6 +46,46 @@ namespace Ink_Canvas.Windows
|
|||||||
hideTimer = new Timer(1000); // 每秒检查一次
|
hideTimer = new Timer(1000); // 每秒检查一次
|
||||||
hideTimer.Elapsed += HideTimer_Elapsed;
|
hideTimer.Elapsed += HideTimer_Elapsed;
|
||||||
lastActivityTime = DateTime.Now;
|
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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 刷新主题(供外部调用)
|
||||||
|
/// </summary>
|
||||||
|
public void RefreshTheme()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 重新应用主题
|
||||||
|
ApplyTheme();
|
||||||
|
|
||||||
|
// 强制刷新UI
|
||||||
|
InvalidateVisual();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"刷新计时器窗口主题出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 事件定义
|
#region 事件定义
|
||||||
@@ -296,6 +336,9 @@ namespace Ink_Canvas.Windows
|
|||||||
SetDarkThemeBorder();
|
SetDarkThemeBorder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 刷新数字和冒号显示的颜色
|
||||||
|
UpdateDigitDisplays();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -457,7 +500,7 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush;
|
var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush;
|
||||||
if (defaultBrush != null)
|
if (defaultBrush != null)
|
||||||
{
|
{
|
||||||
path.Fill = defaultBrush;
|
path.Fill = defaultBrush;
|
||||||
@@ -487,7 +530,7 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush;
|
var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush;
|
||||||
if (defaultBrush != null)
|
if (defaultBrush != null)
|
||||||
{
|
{
|
||||||
colon1.Foreground = defaultBrush;
|
colon1.Foreground = defaultBrush;
|
||||||
@@ -507,7 +550,7 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var defaultBrush = this.FindResource("NewTimerWindowDigitForeground") as Brush;
|
var defaultBrush = this.TryFindResource("NewTimerWindowDigitForeground") as Brush;
|
||||||
if (defaultBrush != null)
|
if (defaultBrush != null)
|
||||||
{
|
{
|
||||||
colon2.Foreground = defaultBrush;
|
colon2.Foreground = defaultBrush;
|
||||||
|
|||||||
Reference in New Issue
Block a user