From db76a11347710d4d8a7de3885772166cddabbfbc Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 18 Oct 2025 20:45:23 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E7=AA=97=E5=8F=A3=E7=BD=AE=E9=A1=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Windows/NewStyleTimerWindow.cs | 134 +++++++++++++++++----- 1 file changed, 104 insertions(+), 30 deletions(-) diff --git a/Ink Canvas/Windows/NewStyleTimerWindow.cs b/Ink Canvas/Windows/NewStyleTimerWindow.cs index 8a8eecae..7c6dcbb0 100644 --- a/Ink Canvas/Windows/NewStyleTimerWindow.cs +++ b/Ink Canvas/Windows/NewStyleTimerWindow.cs @@ -6,9 +6,12 @@ using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Input; +using System.Windows.Interop; using System.Windows.Media; using System.Windows.Shapes; using Newtonsoft.Json; +using System.Runtime.InteropServices; +using System.Windows.Threading; namespace Ink_Canvas { @@ -46,6 +49,9 @@ namespace Ink_Canvas hideTimer = new Timer(1000); // 每秒检查一次 hideTimer.Elapsed += HideTimer_Elapsed; lastActivityTime = DateTime.Now; + + // 添加窗口加载事件处理,确保置顶 + Loaded += TimerWindow_Loaded; } @@ -331,6 +337,9 @@ namespace Ink_Canvas minimizedWindow = new MinimizedTimerWindow(this); minimizedWindow.Show(); + // 确保最小化窗口也置顶 + minimizedWindow.Topmost = true; + // 隐藏主窗口 this.Hide(); } @@ -777,6 +786,9 @@ namespace Ink_Canvas // 启动隐藏定时器 hideTimer.Start(); + // 确保计时器窗口置顶 + ApplyTimerWindowTopmost(); + // 保存到最近计时记录 SaveRecentTimer(); } @@ -879,36 +891,6 @@ namespace Ink_Canvas private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { isTimerRunning = false; - - if (MainWindow.Settings != null) - { - var mainWindow = Application.Current.MainWindow as MainWindow; - if (mainWindow != null) - { - try - { - var currentModeField = mainWindow.GetType().GetField("currentMode", - System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - if (currentModeField != null) - { - int currentMode = (int)currentModeField.GetValue(mainWindow); - if (currentMode == 1) // 白板模式 - { - mainWindow.Topmost = false; // 保持白板模式下的非置顶状态 - } - else - { - mainWindow.Topmost = true; // 其他模式恢复置顶 - } - } - } - catch - { - // 如果反射失败,使用默认行为 - mainWindow.Topmost = true; - } - } - } } private void CloseButton_Click(object sender, RoutedEventArgs e) @@ -1329,6 +1311,9 @@ namespace Ink_Canvas fullscreenWindow = new FullscreenTimerWindow(this); fullscreenWindow.Show(); + // 确保全屏窗口也置顶 + fullscreenWindow.Topmost = true; + // 隐藏主窗口 this.Hide(); } @@ -1342,6 +1327,8 @@ namespace Ink_Canvas this.Show(); this.Activate(); this.WindowState = WindowState.Normal; + // 重新应用置顶 + ApplyTimerWindowTopmost(); } else if (fullscreenWindow != null) { @@ -1351,7 +1338,94 @@ namespace Ink_Canvas this.Show(); this.Activate(); this.WindowState = WindowState.Normal; + // 重新应用置顶 + ApplyTimerWindowTopmost(); } } + + #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); + + [DllImport("user32.dll")] + private static extern bool IsWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern bool IsIconic(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + + [DllImport("kernel32.dll")] + private static extern uint GetCurrentProcessId(); + + private const int GWL_EXSTYLE = -20; + private const int WS_EX_TOPMOST = 0x00000008; + private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); + private static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); + 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 const uint SWP_NOOWNERZORDER = 0x0200; + + /// + /// 应用计时器窗口置顶 + /// + private void ApplyTimerWindowTopmost() + { + try + { + var hwnd = new WindowInteropHelper(this).Handle; + if (hwnd == IntPtr.Zero) return; + + // 强制激活窗口 + Activate(); + Focus(); + + // 设置WPF的Topmost属性 + Topmost = true; + + // 使用Win32 API强制置顶 + // 1. 设置窗口样式为置顶 + int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); + SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST); + + // 2. 使用SetWindowPos确保窗口在最顶层 + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER); + + LogHelper.WriteLogToFile("计时器窗口已应用置顶", LogHelper.LogType.Trace); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"应用计时器窗口置顶失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + /// + /// 窗口加载事件处理,确保置顶 + /// + private void TimerWindow_Loaded(object sender, RoutedEventArgs e) + { + // 使用延迟确保窗口完全加载后再应用置顶 + Dispatcher.BeginInvoke(new Action(() => + { + ApplyTimerWindowTopmost(); + }), DispatcherPriority.Loaded); + } + #endregion } }