Unity打包程序嵌入WinForm或者WPF(2) 问题

嵌入方式两种,官方的-parentHandle和我的WinAPI嵌入。

问题1.主程序卡死

    [-parentHandle]:主程序打开3D后,切换到其他程序,再切换回来,卡死。

    [WinAPI]:主程序打开3D后,过一段时间卡死。其实这里的打开的Unity程序也算是其他程序了。

    这个问题结果发现是主程序其他部分导致的。

问题2.嵌入Unity的控件隐藏后,GPU使用率达到99%。

    所谓的Unity控件隐藏是指嵌入Unity程序的Panel,这里命名为UnityPanel,在主程序中不显示时,最小化没关系。

    两种都会有。

    考虑修改Unity的打包方式。

    感觉相关的属性有 Run In Background和 Visible In Background。

    生成4种情况 

        True True:会99%,原来打包的方式

        True False:会99%

        False True:不会99%,但是,一旦失去焦点,Unity程序就停止运行了,就算是焦点在主程序也一样。

        False False:和上面一个一样。

    单独的Unity程序不会有问题,考虑在控件隐藏时让Unity程序独立出来。

    独立出来后还要隐藏,不然突然多出一个窗口。

    隐藏和显示用User32.dll的ShowWindow,不过隐藏不是用SW_HIDE而是用,SW_MINIMIZE。SW_HIDE本身就会导致那个99%的问题。

    但是嵌入的控件无法自动识别是否显示的状态,必须通过在主程序的各个地方添加调用函数主动控制Unity程序的状态。

[csharp] view plain copy
  1. public void SetVisible(bool isVisible)  
  2.        {  
  3.            if (isVisible == false)  
  4.            {  
  5.                NoEmbedWnd();//独立显示  
  6.                ShowMini();//最小化  
  7.                //HideTaskBarIcon();//隐藏任务栏图标,但是用了的话GPU就还是99%了  
  8.            }  
  9.            else  
  10.            {  
  11.                EmbedWnd();  
  12.                ShowNormal();  
  13.            }  
  14.        }  
  15.   
  16.        public void HideTaskBarIcon()  
  17.        {  
  18.            User32.SetWindowLong(WndHandle, User32.GWL_EXSTYLE, User32.WS_EX_TOOLWINDOW);  
  19.        }  
  20.        public void EmbedWnd()  
  21.        {  
  22.            if (IsEmbeded == truereturn;  
  23.            IsEmbeded = true;  
  24.            User32.SetParent(WndHandle, ParentWnd);  
  25.        }  
  26.   
  27.        public void NoEmbedWnd()  
  28.        {  
  29.            if (IsEmbeded == falsereturn;  
  30.            IsEmbeded = false;  
  31.            User32.SetParent(WndHandle, IntPtr.Zero);  
  32.        }  
  33.   
  34.        public void ShowMini()  
  35.        {  
  36.            User32.ShowWindow(WndHandle, User32.SW_MINIMIZE);  
  37.        }  
  38.   
  39.        public void ShowNormal()  
  40.        {  
  41.            User32.ShowWindow(WndHandle, User32.SW_NORMAL);  
  42.        }  

    扩展问题:任务栏图标怎么隐藏?将Unity独立出来后,点击任务栏上的图标就能单独看到Unity的程序了。

    放弃隐藏任务栏菜单的情况下,可以让窗口看不到。通过设置窗口的边框位置,让窗口处于显示器外面。不过要在设置窗口独立前设置,独立后设置就没有效果了。为什么呢?

    既然是因为控件隐藏导致的,让控件不隐藏就好了,或者该控件隐藏时让Unity嵌入到另一个不会被隐藏的控件中:在主程序的一个现实区域添加一个小块的WindowsFormsHost,里面放一块Panel,这里命名为UnityHidePanel,让UnityPanel隐藏时将Unity程序嵌入到UnityHidePanel中。GPU99%和任务栏图标问题就解决了。

    将该WindowsFormsHost的长宽设置为0,不用看到。另外发现,设置为1,即有长宽时GPU是30%;设置为0时,是14%,即Unity程序单独运行时最小化时的状态。

    不过在切换的一瞬间GPU会提高一下,稍微卡一下,1s左右。这个是概率出现的和下面的闪一下一样看电脑的状态的。

问题3.[WinAPI]:打开Unity时,Unity程序可能会闪一下。

    从上的问题的处理方法想到,能否先用[-parentHandle]嵌入到一个控件中,再用[WinAPI]方式嵌入到另一个控件中。这样就不会闪一下,而且,也能输入中文了。

    结果发现不行,用-parentHandle方式打开的Unity程序,就是独立出来,也是无法输入的。别说中文了,英文也无法输入。

问题4.[-parentHandle]:无法输入中文。

    暂时没找到办法,只能改用WinAPI方式了。

问题5.主程序意外关闭后,Unity程序还在后台运行。

    要不要弄个心跳包之类的,主程序不在了,Unity程序也就自己退出。

猜你喜欢

转载自blog.csdn.net/lzkqcc/article/details/79913138
今日推荐