WinForm中UnityWebPlayer屏蔽右键菜单

    百度到的解决方案:

    鼠标右键的BUG
     1).3D模型基本操作都是鼠标右键按下以后,拖动鼠标可以旋转模型视角,但是WPF加载后的UnityWebPlayer控件存在一个BUG:右键菜单
     2).网上有很多方法去除右键菜单的问题.但都是在网页中去除,UnityWebPlayer封装好的控件还是会携带右键菜单.经过几番周折,也没有直接
        在控件里去除右键菜单的问题.在网上,所有的方法都是在网页中修改JS代码解决右键菜单的问题.但是WPF是没有办法修改JS代码的.因为我
        们不需要用到Untiy3D发布后的html文件.那怎么解决这个问题呢?我的方式是截取鼠标右键的点击,抬起,按下三个事件,在截取的同时,向模型中发送鼠标消息.   

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);         

   }            

}    

  经试验失败,无法拦截鼠标消息。而且要修改场景,也没说明怎么修改。

  通过观察消息,发现左右键单击时都有个WM_PARENTNOTIFY消息,其字符串表示中有个“WM_RBUTTONDOWN”以及“WM_LBUTTONDOWN”来区分左右键。

Spy++ ,发现右键单击后会有个 Unity.ContextSubMenu 窗口。

  思路是用Api控制使右键菜单隐藏。

API 函数 ShowWindow有点效果,但不理想,Minisize无法完全隐藏。

MoveWindow(0, 0, 0, 0, true); 可以完全隐藏掉,但是有阴影。

为了解决这个阴影花了点时间。


    /// <summary>     

    /// 封装U3d WebPlayer控件,屏蔽ocx中的鼠标右键显示菜单功能      
    /// </summary>       
    public class UnityWebPlayer : AxUnityWebPlayer
    {
        [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)
        {
            switch (m.Msg)
            {
                case WM_PARENTNOTIFY:
                    HideContextMenu(m);
                    break;
            }
            base.WndProc(ref m);
        }

        /// <summary>
        /// 是否隐藏右键菜单,默认还是要显示的,new出来后要设置一下
        /// </summary>
        public bool DisableContextMenu { get; set; }

        private bool _menuHided;

        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()
        {
            IntPtr handle = FindWindow("Unity.ContextSubmenu", null);
            if (handle != IntPtr.Zero)
            {
                MoveWindow(handle, 0, 0, 10, 10, true); //这个必须要,不然会有阴影,而且怎么Refresh(),Inalidate()都没法去掉
                MoveWindow(handle, 0, 0, 0, 0, true);
                _menuHided = true;
            }
        }
    }

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。