如何让Form窗体始终显示在全屏应用的最上层
解决方案
WinForm 自带的 TopMost 属性仅作用于普通桌面窗口层级,独占全屏的应用会接管顶层显示优先级,普通 TopMost 设置会被覆盖。按以下步骤修改即可实现始终置顶:
1. 替换原生TopMost设置,使用Win32 API强制置顶
首先在窗体类中声明系统API:
[DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); const uint SWP_NOSIZE = 0x0001; const uint SWP_NOMOVE = 0x0002; const uint SWP_NOACTIVATE = 0x0010;
在窗体初始化时调用API完成置顶,不要直接设置TopMost = true:
// 保留原有的半透明、点击穿透样式设置后调用 SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
2. 定时刷新Z序避免被全屏应用覆盖
添加一个Timer组件,设置间隔为1000~2000ms,在Tick事件中重复调用上述SetWindowPos方法即可。为了降低资源占用,你可以额外增加前台窗口判断逻辑,仅当当前前台窗口为全屏状态时才触发置顶操作。
3. 可选:优化全屏场景判定
可以增加对前台窗口是否为全屏状态的检测逻辑,避免无意义的置顶调用:
[DllImport("user32.dll")] static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } private bool IsForegroundFullScreen() { IntPtr foregroundWnd = GetForegroundWindow(); GetWindowRect(foregroundWnd, out RECT windowRect); Screen screen = Screen.FromHandle(foregroundWnd); return windowRect.Left == screen.Bounds.Left && windowRect.Top == screen.Bounds.Top && windowRect.Right == screen.Bounds.Right && windowRect.Bottom == screen.Bounds.Bottom; }
在Timer的Tick事件中先判断IsForegroundFullScreen()返回为true时再调用SetWindowPos即可。
内容的提问来源于stack exchange,提问作者Samuel Kaizer
相关产品推荐
相关产品推荐

