个人技术总结——Unity窗口互动实现

文章目录

  • 技术概述
  • 技术详述
  • 技术使用中遇到的问题和解决过程
  • 总结
  • 参考链接

技术概述

unity实现不同Windows应用窗口间的交互和窗口的透明及穿透,但不仅限于unity应用实现。

技术详述

  • 透明化窗口

调用动态库

     [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow(); //获取最前端窗体句柄
    /// 
    /// 获取窗口句柄
    /// 
    /// 
    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();
    /// 
    /// 设置窗体透明
    /// 
    /// 
    /// 
    /// 
    /// 
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

    [DllImport("Dwmapi.dll")]
    private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);
    /// 
    /// 设置窗口置顶
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);

    /// 
    /// 设置鼠标穿透
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    [DllImport("user32", EntryPoint = "SetLayeredWindowAttributes")]
    private static extern uint SetLayeredWindowAttributes(IntPtr hwnd, int crKey, int bAlpha, int dwFlags);
 //定义窗体样式,-16表示设定一个新的窗口风格。
    const int GWL_STYLE = -16;
    //设定一个新的扩展风格
    const int GWL_EXSTYLE = -20;
    /// 
    /// 弹出窗口
    /// 
    const uint WS_POPUP = 0x80000000;
    /// 
    /// 可见状态
    /// 
    const uint WS_VISIBLE = 0x10000000;
    /// 
    /// 分层或透明窗口,该样式可使用混合特效
    /// 
    const uint WS_EX_LAYERED = 0x80000;
    /// 
    /// 当前窗体句柄
    /// 
    public IntPtr hwnd;

获取焦点窗口句柄后,用相应SetWindowLong()设置窗口透明和穿透

        SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
        SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED| 0x00000080);//穿透,不透明
  • 通过unity应用激活其它应用

直接开启外部应用

                    try
                    {
                        Process process = new Process();
                        string fileName = UnityEngine.Application.streamingAssetsPath + "/connection/Connect.exe";//获取连接exe
                        process.StartInfo.FileName = fileName;
                        process.Start();
                    }
                    catch (Exception e)
                    {
                        UnityEngine.Debug.Log(e.StackTrace);
                    }

通过类运行相应代码

WindowsFormsApp2.Program1.Main();

技术使用中遇到的问题和解决过程

GetActiveWindow()和GetForegroundWindow()获取到的不一定是需要的窗口
        Process[] processes = Process.GetProcesses();
        foreach (Process pros in processes)
        {
            try
            {
                if (!pros.HasExited)
                {
                    if (pros.ProcessName == "Pet")
                    {
                        id = pros.Id;
                        break;
                    }
                }
            }
            catch (System.InvalidOperationException ex)
            {
                UnityEngine.Debug.Log(ex);
            }
        }
        hwnd = User32API.GetCurrentWindowHandle((uint)id);

可以通过获取电脑进程列表,根据名称获取对应的窗口。

总结

unity应用说白了和黑窗口、JAVA GUI窗口等使用起来并没有区别,使用时可以脱离unity引擎,使用通用性更强的方法。

参考链接

MolyMade
游戏蛮牛文章(服务器到期了)

你可能感兴趣的:(unity,游戏引擎)