improve:快抽按钮

This commit is contained in:
CJK_mkp
2025-11-08 22:17:52 +08:00
parent 1baa74bb69
commit c3fd5551d8
5 changed files with 165 additions and 571 deletions
@@ -1,22 +1,19 @@
<Window x:Class="Ink_Canvas.QuickDrawFloatingButton"
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"
Topmost="True" Background="Transparent"
mc:Ignorable="d" WindowStyle="None" AllowsTransparency="True"
Loaded="FloatingButton_Loaded" WindowStartupLocation="Manual"
ShowInTaskbar="False" Focusable="False"
Title="快抽悬浮按钮" Height="45" Width="65">
<Window.Resources>
<UserControl x:Class="Ink_Canvas.Controls.QuickDrawFloatingButtonControl"
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"
mc:Ignorable="d"
Width="65" Height="45">
<UserControl.Resources>
<ResourceDictionary>
<!-- 悬浮按钮资源 -->
<SolidColorBrush x:Key="QuickDrawFloatingButtonBackground" Color="#80000000"/>
<SolidColorBrush x:Key="QuickDrawFloatingButtonBorderBrush" Color="#40000000"/>
<SolidColorBrush x:Key="QuickDrawFloatingButtonIconForeground" Color="White"/>
</ResourceDictionary>
</Window.Resources>
</UserControl.Resources>
<Border Background="{DynamicResource QuickDrawFloatingButtonBackground}"
CornerRadius="8"
@@ -85,4 +82,5 @@
</Border>
</Grid>
</Border>
</Window>
</UserControl>
@@ -0,0 +1,149 @@
using Ink_Canvas.Windows;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
using HorizontalAlignment = System.Windows.HorizontalAlignment;
using VerticalAlignment = System.Windows.VerticalAlignment;
namespace Ink_Canvas.Controls
{
/// <summary>
/// 快抽悬浮按钮控件
/// </summary>
public partial class QuickDrawFloatingButtonControl : UserControl
{
private bool _isDragging = false;
private Point _dragStartPoint;
private Point _controlStartPoint;
public QuickDrawFloatingButtonControl()
{
InitializeComponent();
}
/// <summary>
/// 快抽按钮点击事件
/// </summary>
private void FloatingButton_Click(object sender, MouseButtonEventArgs e)
{
try
{
// 如果正在拖动,不触发点击事件
if (_isDragging) return;
// 打开快抽窗口
var quickDrawWindow = new QuickDrawWindow();
quickDrawWindow.ShowDialog();
}
catch (Exception ex)
{
Helpers.LogHelper.WriteLogToFile($"打开快抽窗口失败: {ex.Message}", Helpers.LogHelper.LogType.Error);
}
}
/// <summary>
/// 拖动区域鼠标按下事件
/// </summary>
private void DragArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_isDragging = false;
// 记录鼠标在屏幕上的初始位置
_dragStartPoint = this.PointToScreen(e.GetPosition(this));
// 记录控件的初始位置
var parent = this.Parent as FrameworkElement;
if (parent != null)
{
var transform = this.TransformToVisual(parent);
var currentPos = transform.Transform(new Point(0, 0));
_controlStartPoint = currentPos;
}
else
{
var currentMargin = this.Margin;
_controlStartPoint = new Point(
double.IsNaN(currentMargin.Left) ? 0 : currentMargin.Left,
double.IsNaN(currentMargin.Top) ? 0 : currentMargin.Top);
}
((UIElement)sender).CaptureMouse();
e.Handled = true;
}
/// <summary>
/// 拖动区域鼠标移动事件
/// </summary>
private void DragArea_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed && ((UIElement)sender).IsMouseCaptured)
{
// 获取鼠标在屏幕上的当前位置
Point currentScreenPoint = this.PointToScreen(e.GetPosition(this));
Vector diff = currentScreenPoint - _dragStartPoint;
if (!_isDragging && (Math.Abs(diff.X) > 3 || Math.Abs(diff.Y) > 3))
{
_isDragging = true;
// 切换到绝对定位模式
this.HorizontalAlignment = HorizontalAlignment.Left;
this.VerticalAlignment = VerticalAlignment.Top;
}
if (_isDragging)
{
// 计算新位置
var parent = this.Parent as FrameworkElement;
if (parent != null)
{
// 计算屏幕坐标相对于父容器的位置
var parentPoint = parent.PointFromScreen(currentScreenPoint);
var startParentPoint = parent.PointFromScreen(_dragStartPoint);
// 计算相对于初始位置的偏移
double offsetX = parentPoint.X - startParentPoint.X;
double offsetY = parentPoint.Y - startParentPoint.Y;
// 新位置 = 初始位置 + 偏移
double newLeft = _controlStartPoint.X + offsetX;
double newTop = _controlStartPoint.Y + offsetY;
// 限制在父容器范围内
newLeft = Math.Max(0, Math.Min(newLeft, parent.ActualWidth - this.ActualWidth));
newTop = Math.Max(0, Math.Min(newTop, parent.ActualHeight - this.ActualHeight));
// 更新Margin
this.Margin = new Thickness(newLeft, newTop, 0, 0);
}
}
}
}
/// <summary>
/// 拖动区域鼠标释放事件
/// </summary>
private void DragArea_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (((UIElement)sender).IsMouseCaptured)
{
((UIElement)sender).ReleaseMouseCapture();
}
if (_isDragging)
{
Dispatcher.BeginInvoke(new Action(() => { _isDragging = false; }),
DispatcherPriority.Background);
}
else
{
_isDragging = false;
}
e.Handled = true;
}
}
}
+3 -71
View File
@@ -6,6 +6,7 @@
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:c="clr-namespace:Ink_Canvas.Converter"
xmlns:Controls="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
xmlns:controls="clr-namespace:Ink_Canvas.Controls"
mc:Ignorable="d"
AllowsTransparency="True"
WindowStyle="None"
@@ -3958,81 +3959,12 @@
</Canvas>
<!-- 快抽悬浮按钮 -->
<Border x:Name="QuickDrawFloatingButton"
Background="#80000000"
CornerRadius="8"
BorderThickness="1"
BorderBrush="#40000000"
Width="65"
Height="45"
<controls:QuickDrawFloatingButtonControl x:Name="QuickDrawFloatingButton"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0,0,0,200"
Visibility="Collapsed"
Panel.ZIndex="1001">
<Border.Effect>
<DropShadowEffect Color="Black" Direction="315" ShadowDepth="3" Opacity="0.3" BlurRadius="5"/>
</Border.Effect>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="22"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 拖动区域 -->
<Border Grid.Column="0"
MouseLeftButtonDown="QuickDrawFloatingButton_DragArea_MouseLeftButtonDown"
MouseMove="QuickDrawFloatingButton_DragArea_MouseMove"
MouseLeftButtonUp="QuickDrawFloatingButton_DragArea_MouseLeftButtonUp"
Cursor="SizeAll"
Background="Transparent">
<Grid VerticalAlignment="Center" Height="14" IsHitTestVisible="False">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="4"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="4"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 三个白色横线 -->
<Border Grid.Row="0" Background="White" Height="2" Width="10"
HorizontalAlignment="Center"
CornerRadius="1" Opacity="0.8" IsHitTestVisible="False"/>
<Border Grid.Row="2" Background="White" Height="2" Width="10"
HorizontalAlignment="Center"
CornerRadius="1" Opacity="0.8" IsHitTestVisible="False"/>
<Border Grid.Row="4" Background="White" Height="2" Width="10"
HorizontalAlignment="Center"
CornerRadius="1" Opacity="0.8" IsHitTestVisible="False"/>
</Grid>
</Border>
<!-- 半透明分割线 -->
<Rectangle Grid.Column="1" Width="1" Fill="#20FFFFFF" Margin="0,8,0,8"/>
<!-- 按钮区域 -->
<Border Grid.Column="2"
MouseLeftButtonDown="QuickDrawFloatingButton_Click"
Cursor="Hand"
Background="Transparent">
<Grid IsHitTestVisible="False">
<Path Data="M5 7C5 8.06087 5.42143 9.07828 6.17157 9.82843C6.92172 10.5786 7.93913 11 9 11C10.0609 11 11.0783 10.5786 11.8284 9.82843C12.5786 9.07828 13 8.06087 13 7C13 5.93913 12.5786 4.92172 11.8284 4.17157C11.0783 3.42143 10.0609 3 9 3C7.93913 3 6.92172 3.42143 6.17157 4.17157C5.42143 4.92172 5 5.93913 5 7Z M3 21V19C3 17.9391 3.42143 16.9217 4.17157 16.1716C4.92172 15.4214 5.93913 15 7 15H11C12.0609 15 13.0783 15.4214 13.8284 16.1716C14.5786 16.9217 15 17.9391 15 19V21 M16 3.13C16.8604 3.35031 17.623 3.85071 18.1676 4.55232C18.7122 5.25392 19.0078 6.11683 19.0078 7.005C19.0078 7.89318 18.7122 8.75608 18.1676 9.45769C17.623 10.1593 16.8604 10.6597 16 10.88 M21 21V19C20.9949 18.1172 20.6979 17.2608 20.1553 16.5644C19.6126 15.868 18.8548 15.3707 18 15.15"
Stroke="White"
StrokeThickness="2"
StrokeLineJoin="Round"
Fill="Transparent"
Width="20" Height="20"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsHitTestVisible="False"/>
</Grid>
</Border>
</Grid>
</Border>
Panel.ZIndex="1001"/>
</Grid>
<Canvas IsHitTestVisible="False">
+1 -131
View File
@@ -63,10 +63,6 @@ namespace Ink_Canvas
// 悬浮窗拦截管理器
private FloatingWindowInterceptorManager _floatingWindowInterceptorManager;
// 快抽悬浮按钮拖动相关
private bool _quickDrawButtonIsDragging = false;
private Point _quickDrawButtonDragStartPoint;
private Point _quickDrawButtonWindowStartPoint;
// 设置面板相关状态
private bool userChangedNoFocusModeInSettings;
@@ -3083,7 +3079,7 @@ namespace Ink_Canvas
{
try
{
var quickDrawButton = FindName("QuickDrawFloatingButton") as Border;
var quickDrawButton = FindName("QuickDrawFloatingButton") as Controls.QuickDrawFloatingButtonControl;
if (quickDrawButton == null) return;
// 检查设置是否启用快抽功能
@@ -3102,132 +3098,6 @@ namespace Ink_Canvas
}
}
/// <summary>
/// 快抽按钮点击事件
/// </summary>
private void QuickDrawFloatingButton_Click(object sender, MouseButtonEventArgs e)
{
try
{
// 如果正在拖动,不触发点击事件
if (_quickDrawButtonIsDragging) return;
// 打开快抽窗口
var quickDrawWindow = new QuickDrawWindow();
quickDrawWindow.ShowDialog();
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"打开快抽窗口失败: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 快抽按钮拖动区域鼠标按下事件
/// </summary>
private void QuickDrawFloatingButton_DragArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_quickDrawButtonIsDragging = false;
var quickDrawButton = FindName("QuickDrawFloatingButton") as Border;
if (quickDrawButton == null) return;
// 记录鼠标在屏幕上的初始位置
_quickDrawButtonDragStartPoint = quickDrawButton.PointToScreen(e.GetPosition(quickDrawButton));
// 记录按钮的初始位置(相对于Grid)
var parentGrid = quickDrawButton.Parent as Grid;
if (parentGrid != null)
{
var transform = quickDrawButton.TransformToVisual(parentGrid);
var currentPos = transform.Transform(new Point(0, 0));
_quickDrawButtonWindowStartPoint = currentPos;
}
else
{
var currentMargin = quickDrawButton.Margin;
_quickDrawButtonWindowStartPoint = new Point(
double.IsNaN(currentMargin.Left) ? 0 : currentMargin.Left,
double.IsNaN(currentMargin.Top) ? 0 : currentMargin.Top);
}
((UIElement)sender).CaptureMouse();
e.Handled = true;
}
/// <summary>
/// 快抽按钮拖动区域鼠标移动事件
/// </summary>
private void QuickDrawFloatingButton_DragArea_MouseMove(object sender, MouseEventArgs e)
{
var quickDrawButton = FindName("QuickDrawFloatingButton") as Border;
if (quickDrawButton == null) return;
if (e.LeftButton == MouseButtonState.Pressed && ((UIElement)sender).IsMouseCaptured)
{
// 获取鼠标在屏幕上的当前位置
Point currentScreenPoint = quickDrawButton.PointToScreen(e.GetPosition(quickDrawButton));
Vector diff = currentScreenPoint - _quickDrawButtonDragStartPoint;
if (!_quickDrawButtonIsDragging && (Math.Abs(diff.X) > 3 || Math.Abs(diff.Y) > 3))
{
_quickDrawButtonIsDragging = true;
// 切换到绝对定位模式
quickDrawButton.HorizontalAlignment = HorizontalAlignment.Left;
quickDrawButton.VerticalAlignment = VerticalAlignment.Top;
}
if (_quickDrawButtonIsDragging)
{
// 计算新位置
var parentGrid = quickDrawButton.Parent as Grid;
if (parentGrid != null)
{
// 计算屏幕坐标相对于Grid的位置
var gridPoint = parentGrid.PointFromScreen(currentScreenPoint);
var startGridPoint = parentGrid.PointFromScreen(_quickDrawButtonDragStartPoint);
// 计算相对于初始位置的偏移
double offsetX = gridPoint.X - startGridPoint.X;
double offsetY = gridPoint.Y - startGridPoint.Y;
// 新位置 = 初始位置 + 偏移
double newLeft = _quickDrawButtonWindowStartPoint.X + offsetX;
double newTop = _quickDrawButtonWindowStartPoint.Y + offsetY;
// 限制在Grid范围内
newLeft = Math.Max(0, Math.Min(newLeft, parentGrid.ActualWidth - quickDrawButton.ActualWidth));
newTop = Math.Max(0, Math.Min(newTop, parentGrid.ActualHeight - quickDrawButton.ActualHeight));
// 更新Margin
quickDrawButton.Margin = new Thickness(newLeft, newTop, 0, 0);
}
}
}
}
/// <summary>
/// 快抽按钮拖动区域鼠标释放事件
/// </summary>
private void QuickDrawFloatingButton_DragArea_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (((UIElement)sender).IsMouseCaptured)
{
((UIElement)sender).ReleaseMouseCapture();
}
if (_quickDrawButtonIsDragging)
{
Dispatcher.BeginInvoke(new Action(() => { _quickDrawButtonIsDragging = false; }),
DispatcherPriority.Background);
}
else
{
_quickDrawButtonIsDragging = false;
}
e.Handled = true;
}
#endregion
}
@@ -1,355 +0,0 @@
using Ink_Canvas.Helpers;
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Runtime.InteropServices;
using System.Windows.Threading;
namespace Ink_Canvas
{
/// <summary>
/// 快抽悬浮按钮
/// </summary>
public partial class QuickDrawFloatingButton : Window
{
private bool isDragging = false;
private Point dragStartPoint;
private Point windowStartPoint;
public QuickDrawFloatingButton()
{
InitializeComponent();
// 设置无焦点状态
this.Focusable = false;
this.ShowInTaskbar = false;
// 窗口句柄创建后应用无焦点模式
this.SourceInitialized += QuickDrawFloatingButton_SourceInitialized;
}
private void QuickDrawFloatingButton_SourceInitialized(object sender, EventArgs e)
{
ApplyNoFocusMode();
}
private void FloatingButton_Loaded(object sender, RoutedEventArgs e)
{
// 设置位置到屏幕右下角稍微靠近中部
SetPositionToBottomRight();
// 应用无焦点模式
ApplyNoFocusMode();
// 应用置顶
ApplyFloatingButtonTopmost();
if (MainWindow.Settings?.Advanced?.EnableUIAccessTopMost != true)
{
StartTopmostMaintenance();
}
}
private void SetPositionToBottomRight()
{
try
{
// 获取主屏幕的工作区域
var workingArea = SystemParameters.WorkArea;
this.Left = workingArea.Right - this.Width - 0;
this.Top = workingArea.Bottom - this.Height - 200;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"设置悬浮按钮位置失败: {ex.Message}", LogHelper.LogType.Error);
// 如果计算失败,使用默认位置
this.Left = 720;
this.Top = 400;
}
}
private void FloatingButton_Click(object sender, MouseButtonEventArgs e)
{
try
{
// 如果正在拖动,不触发点击事件
if (isDragging) return;
// 打开快抽窗口
var quickDrawWindow = new QuickDrawWindow();
quickDrawWindow.ShowDialog();
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"打开快抽窗口失败: {ex.Message}", LogHelper.LogType.Error);
}
}
private void DragArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
isDragging = false;
// 记录鼠标在屏幕上的初始位置
dragStartPoint = this.PointToScreen(e.GetPosition(this));
// 记录窗口的初始位置
windowStartPoint = new Point(this.Left, this.Top);
((UIElement)sender).CaptureMouse();
e.Handled = true;
}
private void DragArea_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed && ((UIElement)sender).IsMouseCaptured)
{
// 获取鼠标在屏幕上的当前位置
Point currentScreenPoint = this.PointToScreen(e.GetPosition(this));
Vector diff = currentScreenPoint - dragStartPoint;
if (!isDragging && (Math.Abs(diff.X) > 3 || Math.Abs(diff.Y) > 3))
{
isDragging = true;
}
if (isDragging)
{
// 使用窗口初始位置加上鼠标移动的距离
double newLeft = windowStartPoint.X + diff.X;
double newTop = windowStartPoint.Y + diff.Y;
// 限制在屏幕范围内
var workingArea = SystemParameters.WorkArea;
newLeft = Math.Max(workingArea.Left, Math.Min(newLeft, workingArea.Right - this.Width));
newTop = Math.Max(workingArea.Top, Math.Min(newTop, workingArea.Bottom - this.Height));
this.Left = newLeft;
this.Top = newTop;
}
}
}
private void DragArea_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (((UIElement)sender).IsMouseCaptured)
{
((UIElement)sender).ReleaseMouseCapture();
}
// 延迟重置拖动状态,避免触发点击事件
if (isDragging)
{
Dispatcher.BeginInvoke(new Action(() => { isDragging = false; }),
DispatcherPriority.Background);
}
else
{
isDragging = false;
}
e.Handled = true;
}
#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")]
[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_NOACTIVATE = 0x08000000;
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;
/// <summary>
/// 应用无焦点模式
/// </summary>
private void ApplyNoFocusMode()
{
try
{
var hwnd = new WindowInteropHelper(this).Handle;
if (hwnd == IntPtr.Zero) return;
int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
// 悬浮快抽窗口始终启用无焦点模式
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE);
}
catch (Exception)
{
}
}
/// <summary>
/// 应用悬浮按钮置顶
/// </summary>
private void ApplyFloatingButtonTopmost()
{
try
{
var hwnd = new WindowInteropHelper(this).Handle;
if (hwnd == IntPtr.Zero) return;
// 设置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);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"应用快抽悬浮按钮置顶失败: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 启动置顶维护定时器
/// </summary>
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;
}
/// <summary>
/// 停止置顶维护定时器
/// </summary>
private void StopTopmostMaintenance()
{
if (topmostMaintenanceTimer != null && isTopmostMaintenanceEnabled)
{
topmostMaintenanceTimer.Stop();
isTopmostMaintenanceEnabled = false;
}
}
/// <summary>
/// 置顶维护定时器事件
/// </summary>
private void TopmostMaintenanceTimer_Tick(object sender, EventArgs e)
{
try
{
if (MainWindow.Settings?.Advanced?.EnableUIAccessTopMost == 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);
}
// 确保无焦点模式样式正确
if ((exStyle & WS_EX_NOACTIVATE) == 0)
{
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"快抽悬浮按钮置顶维护定时器出错: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 窗口关闭时停止置顶维护定时器
/// </summary>
protected override void OnClosed(EventArgs e)
{
StopTopmostMaintenance();
base.OnClosed(e);
}
#endregion
}
}