Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 468|回复: 0

在Winform中屏蔽UnityWebPlayer的右键以及自带Logo解决方案整理

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-5-13 17:26:50 | 显示全部楼层 |阅读模式

            根据项目的需要,对已经完成的Unity三维模型以及游戏要使用Winform进行包装,也就是使用Winform做一层外壳。因此在展示Unity的时候使用到了UnityWebPlayer这个插件,对于此插件就不多说了,无论是想把Unity嵌在网页中还是winform中都要使用到。

            网上很多资料是在Web中使用Unity的,很自然的把Unity发布成Web类型,在此如何在Web中使用Unity也就不多说了,重点是解决在winform中使用Unity出现的插件自带的右键问题以及Logo问题。

          一、winform中使用Unity

         在winform中使用Unity,同样是像网页形式把做好的Unity发布成Web类型,然后直接使用文件格式为.unity3d的文件。把Unity文件的路径赋值给UnityWebplayer的src属性即可,对于动态赋值,从网上找到如下方法:

    /// <summary>
            /// 实例化UnitywebPlayer控件并添加到界面上
            /// </summary>
            /// <param name="panel">承载unity的控件</param>
            /// <param name="unityfileServerpath">服务端路径</param>
            public void BindUnity(Panel panel,string unityfileServerpath)
            {
                if (panel.Controls.Count > 0)
                {
                    panel.Controls[0].Dispose();
                }
                panel.Controls.Clear();
                ///指定空的Unity3D,用来做外壳
                string unityfilepath = Application.StartupPath + unityfileServerpath;//"/U3D/LoadAsset.unity3d";
                unityex = new UnityWebPlayerEx();
                ((System.ComponentModel.ISupportInitialize)(unityex)).BeginInit();
                this.Controls.Add(unityex);
                ((System.ComponentModel.ISupportInitialize)(unityex)).EndInit();
                unityex.src = unityfilepath;
                AxHost.State state = unityex.OcxState;
                unityex.Dispose();
                unityex = new UnityWebPlayerEx();
                ((System.ComponentModel.ISupportInitialize)(unityex)).BeginInit();
                this.SuspendLayout();
                unityex.Dock = DockStyle.Fill;
                unityex.Name = "Unityex";
                unityex.OcxState = state;
                unityex.TabIndex = 0;
                unityex.DisableContextMenu = true;
                unityex.OnExternalCall += new AxUnityWebPlayerAXLib._DUnityWebPlayerAXEvents_OnExternalCallEventHandler(unityex_OnExternalCall);
                panel.Controls.Add(unityex);
                ((System.ComponentModel.ISupportInitialize)(unityex)).EndInit();
                this.ResumeLayout(false);
            }

             二、屏蔽UnityWebPlayer控件的右键问题

             实现的代码如下:

    class UnityWebPlayerEx : AxUnityWebPlayerAXLib.AxUnityWebPlayer
        {
            #region MyRegion
            //private const int WM_RBUTTONDOWN = 0x204;
    
            //private const int WM_RBUTTONUP = 0x205;
    
            //private const int WM_RBUTTONBLCLK = 0x206;
    
            //public override bool PreProcessMessage(ref Message msg)
            //{
            //    switch (msg.Msg)
            //    {
            //        case 0x204://鼠标右键按下消息                  
    
            //            this.SendMessage("ThiredViewCamera", "RightMouseButtonDown", null); 
            //            this.SendMessage("FirstViewCamera", "RightMouseButtonDown", null); 
            //            this.SendMessage("Main Camera", "RightMouseButtonDown", null);
            //            this.Focus();
            //            return true;
    
            //        case 0x205://鼠标右键抬起消息                  
    
            //            this.SendMessage("ThiredViewCamera", "RightMouseButtonUp", null); 
            //            this.SendMessage("FirstViewCamera", "RightMouseButtonUp", null); 
            //            this.SendMessage("Main Camera", "RightMouseButtonUp", null);
            //            return true;
            //        case 0x206://鼠标右键点击消息                  
            //            return true;
            //    }
            //    return base.PreProcessMessage(ref msg);
            //}  
            #endregion
    
            public UnityWebPlayerEx()
            {
                
            }
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool bRepaint);
    
            [DllImport("user32")]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
            private const int WM_PARENTNOTIFY = 0x210;
    
            protected override void WndProc(ref Message m)
            {
                _menuHided = false;
                switch (m.Msg)
                {
                    case WM_PARENTNOTIFY:
                        HideContextMenu(m);
                        break;
                }
                base.WndProc(ref m);
            }
    
            /// <summary>
            /// 是否隐藏右键菜单,默认还是要显示的,new出来后要设置一下
            /// </summary>
            public bool DisableContextMenu{ get; set; }
    
            private bool _menuHided { get; set; }
    
            private void HideContextMenu(Message m)
            {
                if (_menuHided) return;
                if (DisableContextMenu == false) return;
                if (m.ToString().Contains("WM_RBUTTONDOWN"))
                {
                    if (_menuHided == false)
                    {
                        new Thread(() =>
                        {
                            while (_menuHided == false)
                            {
                                HideContextMenu();
                            }
                        }).Start();
                    }
                }
            }
            private void HideContextMenu()
            {
                //Unity.ContextSubmenu 为右键快键菜单的Form
                IntPtr handle = FindWindow("Unity.ContextSubmenu", null);
                if (handle != IntPtr.Zero)
                {
                    //把快捷菜单Form移到左上角并设置其大小为0
                    MoveWindow(handle, 0, 0, 10, 10, true); 
                    MoveWindow(handle, 0, 0, 0, 0, true);
                    _menuHided = true;
                }
            }
        }
    View Code


            需要注意的是在关闭使用的窗体的时候需要释放Unitywebplayer所占用的资源,否则在第二次进来的点击的第一次右键还是会弹出快捷菜单。

            三、遮住unitywebplayer的Logo

            在网上找了很多资料,基本都是网页形式通过修改param参数来更换Logo的,但是winform中直接使用Unity文件,也就没有使用到其一起发布的js文件,所以此方式的可能性不大。一开始也还是抱着可行的态度尝试了使用C#调用js的方式,然并没有解决。在网上是在找不到方法的时候想到了一种“投机取巧”的方法:先遮住UnityWebPlayer,等加载完成后在显示出来。于是在初始化UnityWebPlayer的时候先在其上边添加一个遮挡物,遮挡物可以自定义,比如使用Panel或者自定义一个用户控件,把界面做得好看些。

    //实例化遮挡物
                shadeuc = new ShadeUC();
                shadeuc.Name = "shadeuc1";
                shadeuc.Dock = DockStyle.Fill;
                //把遮罩层添加到界面
                this.splitContainerEx1.Panel1.Controls.Add(shadeuc);
                //遮罩层置顶以遮住底层
                shadeuc.BringToFront();


           接下来的一个问题是何时移除遮挡物,根据自己的项目我是在UnityWebPlayer的OnExternalCall事件中接收到Unity返回的消息时移除的,这种方式得到的效果还可以。还有一种不是太靠谱的方式是使用计时器,自定义一个时长移除遮挡物。

    this.splitContainerEx1.Panel1.Controls.Remove(shadeuc);

     

          

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

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

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 02:18 , Processed in 0.142620 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表