简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย

签名
叶凡
22GS

[技术干货] Unity 程序始终显示在最上层,并且保持交互代码实现分享

[复制链接]

Unity 程序始终显示在最上层,并且保持交互代码实现分享

发表于 2021-12-27 11:29:48 来自 技术干货 阅读模式 倒序浏览
1648 0 查看全部
做项目遇到一个需求,需要是unity打包出来的程序在运行的时候窗口最大化,并且保持在最上层,最难的是要时刻保持交互,不然输入控制会失效,网上百般查询和亲自验证后,利用window自带的方法实现窗口置顶,然后程序使用鼠标点击屏幕某个位置实现保持交互(这个不完美,但是想不到其它方法实现,有大佬可以指教一下)。

重点:一定要将Update中FindWindow()方法里的程序名称换成自己打包出来的名字。

下面代码:
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Runtime.InteropServices;
  6. using System.Threading;
  7. using UnityEngine;
  8. public class WindowMaxAndMin : MonoBehaviour
  9. {
  10.     [DllImport("user32.dll")]
  11.     public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);

  12.     [DllImport("user32.dll")]
  13.     static extern IntPtr GetForegroundWindow();

  14.     [DllImport("User32.dll")]
  15.     private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  16.     [DllImport("User32.dll")]
  17.     private static extern bool SetForegroundWindow(IntPtr hWnd);

  18.     [DllImport("User32.dll")]
  19.     private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

  20.     [DllImport("user32.dll")]
  21.     static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

  22.     [DllImport("user32.dll")]
  23.     private static extern int SetCursorPos(int x, int y); //设置光标位置
  24.     [DllImport("user32.dll")]
  25.     private static extern bool GetCursorPos(ref int x, ref int y); //获取光标位置
  26.     [DllImport("user32.dll")]
  27.     static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, UIntPtr extraInfo); //鼠标事件

  28.     //这个枚举同样来自user32.dll
  29.     [Flags]
  30.     enum MouseEventFlag : uint
  31.     {
  32.         Move = 0x0001,
  33.         LeftDown = 0x0002,
  34.         LeftUp = 0x0004,
  35.         RightDown = 0x0008,
  36.         RightUp = 0x0010,
  37.         MiddleDown = 0x0020,
  38.         MiddleUp = 0x0040,
  39.         XDown = 0x0080,
  40.         XUp = 0x0100,
  41.         Wheel = 0x0800,
  42.         VirtualDesk = 0x4000,
  43.         Absolute = 0x8000
  44.     }

  45.     const int SW_SHOWMINIMIZED = 2; //{最小化, 激活}
  46.     const int SW_SHOWMAXIMIZED = 3;//最大化
  47.     const int SW_SHOWRESTORE = 1;//还原
  48.     private void Awake()
  49.     {

  50.         if (GameObject.Find("SetWindow").gameObject != this.gameObject)
  51.         {
  52.             Destroy(this.gameObject);
  53.         }

  54.         DontDestroyOnLoad(this.gameObject);
  55.     }
  56.     private void Start()
  57.     {
  58.         StartCoroutine(Setposition());
  59.         OnClickMaximize();
  60.     }
  61.     public void OnClickMinimize()
  62.     { //最小化
  63.         ShowWindow(GetForegroundWindow(), SW_SHOWMINIMIZED);
  64.     }

  65.     public void OnClickMaximize()
  66.     {
  67.         //最大化
  68.         ShowWindow(GetForegroundWindow(), SW_SHOWMAXIMIZED);
  69.     }

  70.     public void OnClickRestore()
  71.     {
  72.         //还原
  73.         ShowWindow(GetForegroundWindow(), SW_SHOWRESTORE);
  74.     }

  75.     //测试
  76.     public void OnGUI()
  77.     {
  78.         //if (GUI.Button(new Rect(100, 100, 200, 100), "最大化"))
  79.         //    OnClickMaximize();
  80.         //if (GUI.Button(new Rect(100, 300, 200, 100), "最小化"))
  81.         //    OnClickMinimize();
  82.         //if (GUI.Button(new Rect(100, 500, 200, 100), "窗口还原"))
  83.         //    OnClickRestore();
  84.     }


  85.     IEnumerator Setposition()
  86.     {
  87.         yield return new WaitForSeconds(0.1f);                //不知道为什么发布于行后,设置位置的不会生效,我延迟0.1秒就可以
  88.         SetWindowPos(GetForegroundWindow(), -1, 0, 0, 0, 0, 1 | 2);       //设置屏幕大小和位置
  89.     }
  90.     float addTime=0;
  91.     void Update()
  92.     {
  93.         addTime += Time.deltaTime;
  94.         if (addTime>=5)
  95.         {
  96.             addTime = 0;

  97.             // apptitle自己到查看进程得到,一般就是程序名不带.exe
  98.             // 或者用spy++查看
  99.             IntPtr hwnd = FindWindow(null, "ZuoYuan");

  100.             // 如果没有找到,则不做任何操作(找不到一般就是apptitle错了)
  101.             if (hwnd == IntPtr.Zero)
  102.             {
  103.                 return;
  104.             }

  105.             IntPtr activeWndHwnd = GetForegroundWindow();

  106.             // 当前程序不是活动窗口,则设置为活动窗口
  107.             if (hwnd != activeWndHwnd)
  108.             {
  109.                 SetWindowPos(hwnd, -1, 0, 0, 0, 0, 1 | 2);
  110.                 OnClickMaximize();

  111.                 SetCursorPos(100, 100);

  112.                 mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
  113.                 mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
  114.             }
  115.         }   
  116.     }

  117. }
复制代码


回复

使用道具 举报

游客~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|极客同行 ( 蜀ICP备17009389号-1 ) 川公网安备 51019002006459号

© 2013-2016 Comsenz Inc. Powered by Discuz! X3.4