朋友咨询如何将unity窗口置顶(always on top),貌似unity本身是没有这个功能的,那就要借助万能的windows api了,花时间翻阅了下windows api,现整理代码如下:
using System;
using System.Runtime.InteropServices;
using UnityEngine;
/// <summary>
/// https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-setwindowpos
/// </summary>
///
public class WindowAPI : MonoBehaviour
{
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32")]
private static extern IntPtr SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint wFlags);
[DllImport("user32")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern bool AllowSetForegroundWindow(IntPtr dwProcessId);
delegate bool EnumWindowsCallBack(IntPtr hwnd, IntPtr lParam);
[DllImport("user32")]
static extern int EnumWindows(EnumWindowsCallBack lpEnumFunc, IntPtr lParam);
[DllImport("user32")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref IntPtr lpdwProcessId);
private const uint SWP_SHOWWINDOW = 0x0040;
private const uint SWP_NOSIZE = 0x0001;
private const uint SWP_NOMOVE = 0x0002;
private const uint SWP_FRAMECHANGED = 0x0020;
IntPtr myWindowHandle = new IntPtr(0);
readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
void Start()
{
//!1、枚举窗口比对pid
EnumWindows(new EnumWindowsCallBack(EnumWindCallback), (IntPtr)System.Diagnostics.Process.GetCurrentProcess().Id);
//!2、根据窗口名查找
//myWindowHandle = FindWindow("UnityWndClass", Application.productName);
if (myWindowHandle.ToInt32() != 0)
{
//!注释内容为:SetWindowPos 必须保证当前窗口为foregroundwindow,程序启动时设置一般会设置成功,其他情况未测试
//if (GetForegroundWindow() != myWindowHandle)
// if (!SetForegroundWindow(myWindowHandle))
// if (AllowSetForegroundWindow((IntPtr)System.Diagnostics.Process.GetCurrentProcess().Id))
// { if (!SetForegroundWindow(myWindowHandle)) return; }
// else return;
SetWindowPos(myWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
}
}
bool EnumWindCallback(IntPtr hwnd, IntPtr lParam)
{
IntPtr pid = IntPtr.Zero;
GetWindowThreadProcessId(hwnd, ref pid);
if (pid == lParam)
{
myWindowHandle = hwnd;
return false;
}
return true;
}
}
暂无评论