From 16ae32bfd70e7445f57035869f1973dca19f9cf5 Mon Sep 17 00:00:00 2001 From: CJK_mkp <113243675+CJKmkp@users.noreply.github.com> Date: Sat, 1 Nov 2025 19:17:52 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E7=82=B9=E5=90=8DUI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Windows/NewStyleRollCallWindow.cs | 20 ++- Ink Canvas/Windows/QuickDrawFloatingButton.cs | 141 +++++++++++++++++- 2 files changed, 154 insertions(+), 7 deletions(-) diff --git a/Ink Canvas/Windows/NewStyleRollCallWindow.cs b/Ink Canvas/Windows/NewStyleRollCallWindow.cs index b560159f..bfe85d88 100644 --- a/Ink Canvas/Windows/NewStyleRollCallWindow.cs +++ b/Ink Canvas/Windows/NewStyleRollCallWindow.cs @@ -1197,6 +1197,13 @@ namespace Ink_Canvas { List usedNames = new List(); + // 确保动画期间主显示区域可见 + Application.Current.Dispatcher.Invoke(() => + { + MainResultDisplay.Visibility = Visibility.Visible; + MultiResultScrollViewer.Visibility = Visibility.Collapsed; + }); + for (int i = 0; i < animationTimes; i++) { // 随机选择一个名字进行动画显示 @@ -1207,6 +1214,8 @@ namespace Ink_Canvas Application.Current.Dispatcher.Invoke(() => { + // 确保主显示区域在动画期间保持可见 + MainResultDisplay.Visibility = Visibility.Visible; MainResultDisplay.Text = displayName; }); } @@ -1258,6 +1267,13 @@ namespace Ink_Canvas { List usedNumbers = new List(); + // 确保动画期间主显示区域可见 + Application.Current.Dispatcher.Invoke(() => + { + MainResultDisplay.Visibility = Visibility.Visible; + MultiResultScrollViewer.Visibility = Visibility.Collapsed; + }); + for (int i = 0; i < animationTimes; i++) { // 随机选择一个数字进行动画显示 @@ -1265,6 +1281,8 @@ namespace Ink_Canvas Application.Current.Dispatcher.Invoke(() => { + // 确保主显示区域在动画期间保持可见 + MainResultDisplay.Visibility = Visibility.Visible; MainResultDisplay.Text = randomNumber.ToString(); }); @@ -1280,7 +1298,7 @@ namespace Ink_Canvas // 更新历史记录 UpdateRollCallHistory(selectedNumbers); - // 显示结果 + // 显示结果(这里会根据结果数量决定显示主显示区域还是多结果区域) ShowResults(selectedNumbers); UpdateStatusDisplay($"抽选完成,共选择 {selectedNumbers.Count} 个数字"); diff --git a/Ink Canvas/Windows/QuickDrawFloatingButton.cs b/Ink Canvas/Windows/QuickDrawFloatingButton.cs index 50d96931..6c5360bd 100644 --- a/Ink Canvas/Windows/QuickDrawFloatingButton.cs +++ b/Ink Canvas/Windows/QuickDrawFloatingButton.cs @@ -31,6 +31,13 @@ namespace Ink_Canvas // 应用置顶 ApplyFloatingButtonTopmost(); + + // 如果主窗口在无焦点模式下,启动置顶维护 + if (MainWindow.Settings?.Advanced?.IsNoFocusMode == true && + MainWindow.Settings?.Advanced?.EnableUIAccessTopMost != true) + { + StartTopmostMaintenance(); + } } private void SetPositionToBottomRight() @@ -78,15 +85,39 @@ namespace Ink_Canvas [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")] + [return: MarshalAs(UnmanagedType.Bool)] + 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 DispatcherTimer topmostMaintenanceTimer; + private bool isTopmostMaintenanceEnabled; + /// /// 应用悬浮按钮置顶 /// @@ -96,11 +127,6 @@ namespace Ink_Canvas { var hwnd = new WindowInteropHelper(this).Handle; if (hwnd == IntPtr.Zero) return; - - // 强制激活窗口 - Activate(); - Focus(); - // 设置WPF的Topmost属性 Topmost = true; @@ -113,13 +139,116 @@ namespace Ink_Canvas 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 StartTopmostMaintenance() + { + if (MainWindow.Settings?.Advanced?.EnableUIAccessTopMost == true) + { + return; + } + + if (isTopmostMaintenanceEnabled) return; + + if (topmostMaintenanceTimer == null) + { + topmostMaintenanceTimer = new DispatcherTimer(); + topmostMaintenanceTimer.Interval = TimeSpan.FromMilliseconds(500); // 每500ms检查一次 + topmostMaintenanceTimer.Tick += TopmostMaintenanceTimer_Tick; + } + + topmostMaintenanceTimer.Start(); + isTopmostMaintenanceEnabled = true; + } + + /// + /// 停止置顶维护定时器 + /// + private void StopTopmostMaintenance() + { + if (topmostMaintenanceTimer != null && isTopmostMaintenanceEnabled) + { + topmostMaintenanceTimer.Stop(); + isTopmostMaintenanceEnabled = false; + } + } + + /// + /// 置顶维护定时器事件 + /// + private void TopmostMaintenanceTimer_Tick(object sender, EventArgs e) + { + try + { + if (MainWindow.Settings?.Advanced?.EnableUIAccessTopMost == true) + { + StopTopmostMaintenance(); + return; + } + + if (MainWindow.Settings?.Advanced?.IsNoFocusMode != true) + { + StopTopmostMaintenance(); + return; + } + + var hwnd = new WindowInteropHelper(this).Handle; + if (hwnd == IntPtr.Zero) return; + + // 检查窗口是否仍然可见且不是最小化状态 + if (!IsWindow(hwnd) || !IsWindowVisible(hwnd) || IsIconic(hwnd)) + { + return; + } + + // 检查是否有子窗口在前景 + var foregroundWindow = GetForegroundWindow(); + if (foregroundWindow != hwnd) + { + // 检查前景窗口是否是当前应用程序的子窗口 + var foregroundWindowProcessId = GetWindowThreadProcessId(foregroundWindow, out uint processId); + var currentProcessId = GetCurrentProcessId(); + + if (processId == currentProcessId) + { + // 如果有子窗口在前景,暂停置顶维护 + return; + } + + // 如果窗口不在最顶层且没有子窗口,重新设置置顶 + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER); + + // 确保窗口样式正确 + int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); + if ((exStyle & WS_EX_TOPMOST) == 0) + { + SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST); + } + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"快抽悬浮按钮置顶维护定时器出错: {ex.Message}", LogHelper.LogType.Error); + } + } + + /// + /// 窗口关闭时停止置顶维护定时器 + /// + protected override void OnClosed(EventArgs e) + { + StopTopmostMaintenance(); + base.OnClosed(e); + } #endregion } }