Unity容器窗口改为重叠窗口后行为异常,如何修复?
问题
我用Unity开发游戏,程序包含主窗口和可停靠窗口。有多块屏幕的情况下,把部分子窗口拖到其他屏幕后,切换回Unity主窗口时,这些子窗口总会跑到其他应用窗口的前面,这不是我想要的效果。
通过Spy++查到这些子窗口带有WS_POPUP和WS_EX_TOOLWINDOW样式,于是写了以下代码尝试修改:
EnumWindows(FindUnityWindows, NULL);
以及回调函数:
BOOL CALLBACK FindUnityWindows(HWND hwnd, LPARAM lParam) { char class_name[80]; GetClassName(hwnd, class_name, sizeof(class_name)); int processid = GetWindowThreadProcessId(hwnd, NULL); if (!strcmp(class_name, "UnityContainerWndClass")) { long style = GetWindowLong(hwnd, GWL_STYLE); style |= WS_OVERLAPPED; style &= ~(WS_POPUP); long exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); exstyle |= WS_EX_APPWINDOW; exstyle &= ~(WS_EX_TOOLWINDOW); ShowWindow(hwnd, SW_HIDE); SetWindowLong(hwnd, GWL_STYLE, style); SetWindowLong(hwnd, GWL_EXSTYLE, exstyle); ShowWindow(hwnd, SW_SHOW); } return TRUE; }
Spy++显示窗口样式已经修改成功,但实际行为没变化:任务栏里没有这些子窗口的标签,而且激活主窗口时子窗口还是会前置。请问还有什么办法能解决这个问题?
解决方案建议
- 调整窗口所有者与Z序:调用
SetWindowLongPtr将子窗口的所有者设置为Unity主窗口,所有者窗口和子窗口的Z序绑定逻辑和父窗口不同,能避免子窗口自动前置:// 先获取Unity主窗口的HWND,可通过查找窗口标题或类名实现 SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR)unityMainHwnd); SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - 替换Win32 API调用:将
SetWindowLong换成SetWindowLongPtr,确保64位环境下样式修改真正生效:LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE); style |= WS_OVERLAPPED; style &= ~(WS_POPUP); SetWindowLongPtr(hwnd, GWL_STYLE, style); LONG_PTR exstyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); exstyle |= WS_EX_APPWINDOW; exstyle &= ~(WS_EX_TOOLWINDOW); SetWindowLongPtr(hwnd, GWL_EXSTYLE, exstyle); - 拦截窗口激活消息:子类化子窗口,拦截
WM_ACTIVATE消息,当主窗口激活时阻止子窗口自动获得焦点或前置:LRESULT CALLBACK SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { if (uMsg == WM_ACTIVATE && LOWORD(wParam) == WA_ACTIVE) { // 返回FALSE阻止默认激活行为 return FALSE; } return DefSubclassProc(hwnd, uMsg, wParam, lParam); } // 在找到子窗口后调用SetWindowSubclass进行子类化 - 适配Unity自身逻辑:Unity可能在运行时重新覆盖窗口样式,建议在Unity的窗口初始化回调(比如
EditorWindow的OnEnable)中注入修改代码,或者使用Unity内置的窗口层级控制API,而非直接修改Win32窗口属性。
内容的提问来源于stack exchange,提问作者Entretoize
相关产品推荐
相关产品推荐

