zoukankan      html  css  js  c++  java
  • 如何妥善处理WebBrowser对Javascript的错误问题,阻止JS弹出框,提高用户体验(原创)

         由于项目需求,最近转战客户端,开始搞浏览器开发。众所周知,现在在微软平台上开发浏览器,最常用的方法就是扩展Webbrowser,但是首先要清楚的是,WebBrowser控件仅仅是对WebBrowser ActiveX 控件提供了托管包装而已(详细了解http://msdn.microsoft.com/zh-cn/library/w290k23d(VS.80).aspx),要写一个像点样子的浏览器,很多方面还是要自己去扩展的,否则开发出来的也只能是个样子,没多少实际功能。

         本篇随笔重点将介绍如何处理WebBrowser对JS的错误处理问题。

         可能有些朋友看到上句话会觉得,这问题不是很简单嘛,设置一下 ScriptErrorsSuppressed属性不就完了嘛,殊不知这样做,像其他的譬如网页安全验证的弹出框,甚至很多其他网页内部弹出窗口也都被禁止掉了,如此当然是行不通的。可能还会有一部分朋友会说,那可以通过WebBrowser向网页中注入JS错误处理脚本,捕获JS错误,不是也可以嘛。那我会告诉你,这种方法在面对使用很多iframe的网站是也玩完。

         那么接下来,我将介绍,如何更好的避免WebBrowser中的JS错误。

         避免错误,首先要想到办法去捕获错误,查遍了网上的很多资料,发现是要去实现IOleCommandTarget接口,调用接口中的Exec方法来捕获异常,然后解决,当然如果需要去调用IE的一些功能,也得需实现IObjectWithSite接口。

         定义IOleCommandTarget接口、OLECMD类:

    public static class NativeMethods 

        {
            public enum OLECMDF
            {
                
    // Fields
                OLECMDF_DEFHIDEONCTXTMENU = 0x20,
                OLECMDF_ENABLED = 2,
                OLECMDF_INVISIBLE = 0x10,
                OLECMDF_LATCHED = 4,
                OLECMDF_NINCHED = 8,
                OLECMDF_SUPPORTED = 1
            }

            
    public enum OLECMDID
            {
                
    // Fields
                OLECMDID_PAGESETUP = 8,
                OLECMDID_PRINT = 6,
                OLECMDID_PRINTPREVIEW = 7,
                OLECMDID_PROPERTIES = 10,
                OLECMDID_SAVEAS = 4,
                OLECMDID_SHOWSCRIPTERROR = 40
            }
            
    public enum OLECMDEXECOPT
            {
                
    // Fields
                OLECMDEXECOPT_DODEFAULT = 0,
                OLECMDEXECOPT_DONTPROMPTUSER = 2,
                OLECMDEXECOPT_PROMPTUSER = 1,
                OLECMDEXECOPT_SHOWHELP = 3
            }

            [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"), ComVisible(true)]
            
    public interface IOleCommandTarget
            {
                [return: MarshalAs(UnmanagedType.I4)]
                [PreserveSig]
                
    int QueryStatus(ref Guid pguidCmdGroup, int cCmds, [In, Out] NativeMethods.OLECMD prgCmds, [In, Out] IntPtr pCmdText);
                [return: MarshalAs(UnmanagedType.I4)]
                [PreserveSig]
                
    int Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, [In, MarshalAs(UnmanagedType.LPArray)] object[] pvaIn, ref int pvaOut);
            }

            [StructLayout(LayoutKind.Sequential)]
            
    public class OLECMD
            {
                [MarshalAs(UnmanagedType.U4)]
                
    public int cmdID;
                [MarshalAs(UnmanagedType.U4)]
                
    public int cmdf;
                
    public OLECMD()
                {
                }
            }

            
    public const int S_FALSE = 1;
            
    public const int S_OK = 0;

            
    public static readonly Guid CGID_DocHostCommandHandler = new Guid("f38bc242-b950-11d1-8918-00c04fc2c836");

            
    public const int VARIANT_TRUE = -1;
            
    public const int VARIANT_FALSE = 0;
            
    public const int OLECMDERR_E_NOTSUPPORTED = -2147221244;


        }

           然后定义一个类ExtendedWebBrowserSite,去实现接口:

    class ExtendedWebBrowserSite : WebBrowserSite, NativeMethods.IOleCommandTarget
            {
                
    /// <summary>
                
    /// Creates a new instance of the <see cref="ExtendedWebBrowserSite"/> class
                
    /// </summary>
                
    /// <param name="host">The <see cref="ExtendedWebBrowser"/> hosting the browser</param>
                public ExtendedWebBrowserSite(ExtendedWebBrowser host)
                    : 
    base(host)
                {
                    _host 
    = host;
                }


                
    private ExtendedWebBrowser _host;
                
    private ExtendedWebBrowser Host
                {
                    
    get
                    {
                        
    return _host;
                    }
                }

                
    #region IOleCommandTarget Members

                
    int NativeMethods.IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, int cCmds, NativeMethods.OLECMD prgCmds, IntPtr pCmdText)
                {
                    
    return NativeMethods.S_FALSE;
                }

                
    int NativeMethods.IOleCommandTarget.Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, object[] pvaIn, ref int pvaOut)
                {
                    
    int hResult = NativeMethods.S_OK;
                    
    if (pguidCmdGroup == null)
                        
    return hResult;
                    
    // Check for invalid pointers (or get a NullReferenceException on a value type???)
                    
    //if (NativeMethods.CGID_DocHostCommandHandler.Equals(pguidCmdGroup))
                    {
                        
    switch (nCmdID)
                        {
                            
    case (int)NativeMethods.OLECMDID.OLECMDID_SHOWSCRIPTERROR:
                                
    // Hide the dialog
                                pvaOut = NativeMethods.VARIANT_TRUE;


                                
    break;
                            
    default:
                                hResult 
    = NativeMethods.OLECMDERR_E_NOTSUPPORTED;
                                
    break;
                        }
                    }
                    
    return hResult;
                }

                
    #endregion

            }

       } 

        当然这里主要是通过实现IOleCommandTarget.Exec方法去捕获OLECMDID.OLECMDID_SHOWSCRIPTERROR消息,然后避免异常。

          最后在你的扩展的WebBrowser里面重载一下CreateWebBrowserSiteBase方法,完成调用。

            protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
            {
                
    return new ExtendedWebBrowserSite(this);

            } 

        完成以上操作,就可以完全避免WebBrowser中的JS错误发生。

          由于时间有限,并没有多少时间去详细介绍,感兴趣的朋友可以仔细去研究COM组件。

    作者:Frederick Yang
    出处:http://www.cnblogs.com/yangtongnet/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    智能计算及其应用--蚁群算法
    智能计算及其应用--粒子群优化算法
    智能计算及其应用--遗传算法的改进
    智能计算及其应用--进化算法与遗传算法
    《数据挖掘:理论与算法》学习笔记(三)—数据预处理(下)
    《数据挖掘:理论与算法》学习笔记(二)—数据预处理(上)
    X V$ASM_DISKGROUP 视图解释说明
    Exhaustive Search
    Binary Search
    Linear Search
  • 原文地址:https://www.cnblogs.com/yangtongnet/p/2143420.html
Copyright © 2011-2022 走看看