Unity中将游戏窗口置于任务栏上方的实现方法求助
解决Unity窗口置于任务栏上方的问题
你的问题核心在于窗口最大化操作覆盖了手动位置设置,加上部分Win32 API参数类型不兼容64位环境,导致修改SetWindowPos的y值无效。以下是具体修正方案:
问题根源拆解
ShowWindowAsync(3)(窗口最大化)会让系统接管窗口布局,手动设置的x/y坐标被直接覆盖GetActiveWindow无法保证获取到Unity主窗口句柄,可能导致API调用失效- 原代码使用
int处理窗口句柄,在64位系统下会出现截断错误
修正后的完整代码
using UnityEngine; using System; using System.Runtime.InteropServices; using System.Diagnostics; public class TransparentWindow : MonoBehaviour { [DllImport("user32.dll", EntryPoint = "SetWindowLongPtrA")] static extern IntPtr SetWindowLongPtr(IntPtr hwnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll")] static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")] static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); [DllImport("user32.dll", EntryPoint = "GetWindowLongPtrA")] private static extern IntPtr GetWindowLongPtr(IntPtr hwnd, int nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowPos")] 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 IntPtr GetForegroundWindow(); // Win32常量定义 const uint LWA_COLORKEY = 0x00000001; static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); const int GWL_STYLE = -16; const int GWL_EXSTYLE = -20; const uint WS_CAPTION = 0x00C00000; const uint WS_HSCROLL = 0x00100000; const uint WS_VSCROLL = 0x00200000; const uint WS_SYSMENU = 0x00080000; const uint WS_EX_LAYERED = 0x00080000; const uint SWP_FRAMECHANGED = 0x0020; const uint SWP_SHOWWINDOW = 0x0040; const uint SWP_NOOWNERZORDER = 0x0200; void Start() { // 获取Unity主窗口句柄,替代不可靠的GetActiveWindow IntPtr handle = Process.GetCurrentProcess().MainWindowHandle; if (handle == IntPtr.Zero) handle = GetForegroundWindow(); int screenWidth = Screen.currentResolution.width; int windowHeight = Screen.currentResolution.height / 10; // 移除标题栏及滚动条样式 IntPtr currentStyle = GetWindowLongPtr(handle, GWL_STYLE); currentStyle = (IntPtr)((long)currentStyle & ~(long)(WS_CAPTION | WS_HSCROLL | WS_VSCROLL | WS_SYSMENU)); SetWindowLongPtr(handle, GWL_STYLE, currentStyle); // 设置分层透明属性 IntPtr exStyle = GetWindowLongPtr(handle, GWL_EXSTYLE); exStyle = (IntPtr)((long)exStyle | (long)WS_EX_LAYERED); SetWindowLongPtr(handle, GWL_EXSTYLE, exStyle); SetLayeredWindowAttributes(handle, 0, 0, LWA_COLORKEY); // 强制窗口置顶并固定位置(y=0贴屏幕顶部,避开底部任务栏) SetWindowPos(handle, HWND_TOPMOST, 0, 0, screenWidth, windowHeight, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOOWNERZORDER); // 匹配Unity分辨率到窗口大小,禁用全屏模式 Screen.SetResolution(screenWidth, windowHeight, false); } }
关键改动说明
- 可靠获取窗口句柄:用
Process.GetCurrentProcess().MainWindowHandle直接定位Unity主窗口,避免句柄错误 - 64位兼容修正:改用
SetWindowLongPtrA/GetWindowLongPtrA和IntPtr类型处理句柄,避免32位/64位环境下的类型截断 - 移除最大化操作:删除
ShowWindowAsync(3),让手动设置的x/y坐标生效 - 固定窗口位置:将y值设为0,让窗口紧贴屏幕顶部,自然避开底部任务栏;
HWND_TOPMOST确保窗口始终在普通窗口上方
内容的提问来源于stack exchange,提问作者alperrakn
相关产品推荐
相关产品推荐

