由于项目需求,最近转战客户端,开始搞浏览器开发。众所周知,现在在微软平台上开发浏览器,最常用的方法就是扩展Webbrowser,但是首先要清楚的是,WebBrowser控件仅仅是对WebBrowser ActiveX 控件提供了托管包装而已(详细了解),要写一个像点样子的浏览器,很多方面还是要自己去扩展的,否则开发出来的也只能是个样子,没多少实际功能。
本篇随笔重点将介绍如何处理WebBrowser对JS的错误处理问题。
可能有些朋友看到上句话会觉得,这问题不是很简单嘛,设置一下 ScriptErrorsSuppressed属性不就完了嘛,殊不知这样做,像其他的譬如网页安全验证的弹出框,甚至很多其他网页内部弹出窗口也都被禁止掉了,如此当然是行不通的。可能还会有一部分朋友会说,那可以通过WebBrowser向网页中注入JS错误处理脚本,捕获JS错误,不是也可以嘛。那我会告诉你,这种方法在面对使用很多iframe的网站是也玩完。
那么接下来,我将介绍,如何更好的避免WebBrowser中的JS错误。
避免错误,首先要想到办法去捕获错误,查遍了网上的很多资料,发现是要去实现IOleCommandTarget接口,调用接口中的Exec方法来捕获异常,然后解决,当然如果需要去调用IE的一些功能,也得需实现IObjectWithSite接口。
定义IOleCommandTarget接口、OLECMD类:
{
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,去实现接口:
}
当然这里主要是通过实现IOleCommandTarget.Exec方法去捕获OLECMDID.OLECMDID_SHOWSCRIPTERROR消息,然后避免异常。
最后在你的扩展的WebBrowser里面重载一下CreateWebBrowserSiteBase方法,完成调用。
}
完成以上操作,就可以完全避免WebBrowser中的JS错误发生。
由于时间有限,并没有多少时间去详细介绍,感兴趣的朋友可以仔细去研究COM组件。