Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/UI/Helpers/MainFormWinHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,25 @@ public void ApplyRoundedCorners()
catch { }
}

// =================================================================
// 置顶守护
// =================================================================

/// <summary>
/// 通过 Win32 API 无条件强制置顶窗口。
/// 不检查 WS_EX_TOPMOST 标志,因为在全屏应用(如 VMware、无边框全屏游戏)中
/// 该标志可能仍然存在但窗口实际被覆盖,必须重新调用 SetWindowPos 才能恢复显示。
/// </summary>
public void ReapplyTopMost()
{
try
{
SetWindowPos(_form.Handle, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
catch { }
}

// =================================================================
// Win32 API
// =================================================================
Expand All @@ -152,18 +171,24 @@ public static int RegisterTaskbarCreatedMessage()
[DllImport("dwmapi.dll")] private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
[DllImport("user32.dll", SetLastError = true)] private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", SetLastError = true)] private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)] private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern int RegisterWindowMessage(string lpString);
[DllImport("user32.dll", SetLastError = true)] public static extern bool ChangeWindowMessageFilter(uint message, uint dwFlag);

public const uint MSGFLT_ADD = 1;
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 int DWMWA_WINDOW_CORNER_PREFERENCE = 33;
private const int DWMWCP_ROUND = 2;
private const int DWMWA_BORDER_COLOR = 34;
private const int DWMWA_COLOR_NONE = unchecked((int)0xFFFFFFFE);
private const int GWL_EXSTYLE = -20;
private const int WS_EX_TRANSPARENT = 0x20;
private const int WS_EX_LAYERED = 0x80000;
private const int WS_EX_TOPMOST = 0x00000008;

public static void ActivateWindow(IntPtr handle) => SetForegroundWindow(handle);
}
Expand Down
45 changes: 28 additions & 17 deletions src/UI/MainForm_Transparent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class MainForm : Form

private Point _dragOffset;
private bool _uiDragging = false;
private System.Windows.Forms.Timer? _topMostGuardTimer;

// 防止 Win11 自动隐藏无边框 + 无任务栏窗口
protected override CreateParams CreateParams
Expand Down Expand Up @@ -324,31 +325,41 @@ protected override void OnShown(EventArgs e)
{
_ = _bizHelper.RunStartupChecksAsync();
}
// [Fix] 强制置顶刷新,增加重试机制确保在某些系统环境下依然生效
if (_cfg.TopMost)
{
this.BeginInvoke(new Action(async () =>
{
await Task.Delay(3000);
// 1. 立即执行第一次置顶
this.TopMost = false;
await Task.Delay(1000);
this.TopMost = true;
this.BringToFront();
}));
}
// [Fix] 置顶守护:周期性检测并恢复被虚拟桌面切换、全屏游戏等夺走的置顶状态
StartTopMostGuard();
}

protected override void OnFormClosed(FormClosedEventArgs e)
{
_cfg.Save();
TrafficLogger.Save();
_topMostGuardTimer?.Stop();
_topMostGuardTimer?.Dispose();
_cfg.Save();
TrafficLogger.Save();
src.WebServer.LiteWebServer.Instance?.Stop();

base.OnFormClosed(e);

_ui?.Dispose();
_bizHelper.Dispose();
}

private void StartTopMostGuard()
{
if (_topMostGuardTimer != null) return;
_topMostGuardTimer = new System.Windows.Forms.Timer { Interval = 3000 };
_topMostGuardTimer.Tick += (_, __) =>
{
if (_cfg.TopMost && Visible)
{
// 如果本应用有其他活动窗口(如设置面板),跳过强制置顶以免遮挡
var activeForm = Form.ActiveForm;
if (activeForm != null && activeForm != this)
return;

_winHelper.ReapplyTopMost();
}
};
_topMostGuardTimer.Start();
}
}
}