OOIII/

Unity 窗口置顶

朋友咨询如何将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;
    }
}

留下一条评论

暂无评论