1

在组件中加载的网页的 iFrame 中加载的某些网页WebBrowser在关闭网页时会弹出确认窗口。这个确认窗口阻止了主网页关闭,所以我必须点击离开页面的选项。我想通过更改onbeforeunload在 iFrame 中加载的网页的事件来避免这种情况。

我已尝试修改此解决方案并将其应用于我的案例。但是,该解决方案似乎仅在访问加载到内部的页面事件时才适用WebBrowser,而不是在其中的 iFrame 事件时适用。

所以这就是我尝试过的。

我首先从上述解决方案中声明了接口:

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("00020400-0000-0000-C000-000000000046")]
public interface IDispatch
{
    [PreserveSig]
    int GetTypeInfoCount(out int Count);
    [PreserveSig]
    int GetTypeInfo(
        [MarshalAs(UnmanagedType.U4)] int iTInfo,
        [MarshalAs(UnmanagedType.U4)] int lcid,
        out ITypeInfo typeInfo
    );

    [PreserveSig]
    int GetIDsOfNames(
        ref Guid riid,
        [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] rgsNames,
        int cNames,
        int lcid,
        [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId
    );

    [PreserveSig]
    int Invoke(
        int dispIdMember,
        ref Guid riid,
        uint lcid,
        ushort wFlags,
        ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams,
        out object pVarResult,
        ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo,
        IntPtr[] pArgErr
    );
}

然后,我想将onbeforeunload事件设置为null或以某种方式删除它的内容,以便弹出窗口不会...弹出。

HTMLDocument document = (HTMLDocument)webBrowser2.Document.DomDocument;

// iFrame's id is "iF".
HTMLFrameElement frame = (HTMLFrameElement)document.getElementById("iF");
IHTMLWindow2 window = frame.contentWindow;

// Everything works fine until the following line.
var event = (ExtendedWebBrowser.IDispatch)window.onbeforeunload;

// Although no exception is thrown, event variable is always null, no matter if the webpage in the iFrame has or does not have onbeforeunload event specified.
// Setting the event to null does nothing. I'd have to come up with how to read this event before trying to set it to something.
window.onbeforeunload = null;

所以我的最后一个问题是:如何获取和设置在 WebBrowser 控件中加载的网页的 iFrame 内加载的网页的 onbeforeunload 事件(或任何其他事件)?

随时要求任何进一步的解释。提前致谢。

编辑:

应用程序的进一步解释。

应用程序按顺序导航到网页列表。每一页处理完后,需要关闭,加载下一个。每个网页都有一个 iframe,它反过来从不同的域加载网页。我对应用程序没有任何问题,除非在 iframe 内加载的网页调用confirmpopup在其onbeforeunload事件中。确认弹出框阻止应用程序处理更多网页。我需要摆脱这个弹出确认窗口。

4

1 回答 1

1

如果您在弹出弹出窗口时遇到问题,我已经为您提供了一个解决方案,并且如果您想在客户端机器上禁用/启用 javascript(或者甚至只是读取/查询它是否已启用/禁用),我已包含该答案对你来说,我们开始吧:

您要禁用哪个弹出消息?如果是警报消息,试试这个,显然解决窗口或框架对象以满足您的特定需求,我只是假设顶级文档,但如果您需要 iframe,您可以使用 window.frames(0) 访问它。对于第一帧等等...(关于 JavaScript 部分)...这里有一些代码,假设 WB 是您的网络浏览器控件...

WB.Document.parentWindow.execScript "window.alert = function () { };", "JScript"

但是,在您的情况下,由于您想禁用打印,只需.alert换成.print.

您必须在整个页面加载完成后才运行上述代码,我知道这很难做到(并且尚未发布完整证明版本)但是我已经这样做了一段时间(完整证明)现在,如果您阅读我之前标记为“webbrowser”和“webbrowser-control”的一些答案,您可以收集有关如何准确执行此操作的提示,但如果您想取消 .confirm JavaScript,请回到手头的问题消息,只需将 window.alert 替换为 window.confirm (当然,使用正确的对象限定您的 window.object 以到达您正在使用的文档层次结构)。您还可以使用上述技术禁用 .print 方法以及新的 IE9 .prompt 方法。

这是一个常量字符串(在 VB 中声明),它将摆脱 4 个弹出窗口,包括新的 IE9 弹出窗口。此外,它将摆脱 onbeforeunload 事件,并且它将在其运行的每个页面上执行所有这些操作。如果你有框架,你也不需要在框架中运行它们,只在父文档中运行就足够了。在这里(在 VB6 中声明), _ 只是为了便于阅读,我放置在此处的行延续,& 用于字符串连接,而 ; 在 javascript 中只是意味着将下面的内容视为另一行代码。这样,您可以在一个物理行中运行多行代码(我认为是 5 行)。

Public Const DEFAULT_JS_TO_RUN_AFTER_EACH_PAGE_LOAD As String = _
& "window.alert = function () { }; window.confirm = function () { }; " _
& "window.prompt = function () { }; window.print = function () { }; " _
& "window.onbeforeunload = function () { };"

如果要完全禁用 JavaScript,可以使用注册表来执行此操作,并且必须在 webbrowser 控件加载到内存之前更改注册表,并且每次更改它(打开和关闭)都必须重新加载 webbrowser 控件并进入内存(或只是重新启动您的应用程序)。

注册表项是 \HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\ - 键名是 1400,禁用它的值是 3,启用它是 0。

当然,因为 Zones 键下有 5 个区域,您需要为活动区域或所有区域更改它以确保。但是,如果您只想抑制 js 对话框弹出消息,那么您真的不需要这样做。

让我知道你的情况,如果我能提供进一步的帮助。

于 2012-08-31T11:44:59.033 回答