Веб-браузер и javascript window.close () - PullRequest
9 голосов
/ 04 апреля 2011

Если я размещаю WebBrowser в своем приложении и код JavaScript на веб-странице, показанной на моем веб-браузере, вызывает window.close(), и я нажимаю «Да» в приглашении, мой WebBrowser исчезает, но моя форма остается открытой.

Я не хочу отключать JavaScript, и не нажимать «Да», очевидно, не является решением.Какой лучший способ справиться с этим?Это то, что я могу отменить программно, даже после того, как пользователь нажмет «Да»?А также, есть ли другие хитрости JavaScript, такие как window.close(), которые могут испортить мое приложение, о которых я должен знать?(Мое приложение использует WebBrowser для поиска в Интернете, поэтому следует учитывать каждый возможный код JavaScript.)

Ответы [ 5 ]

5 голосов
/ 18 марта 2014

В WPF вы можете перехватить сообщение WM_CLOSE, подключив его к циклу сообщений WebBrowser.

public MainWindow()
{
    InitializeComponent();
    webBrowser.MessageHook += webBrowser_MessageHook;
}

IntPtr webBrowser_MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch(msg)
    {
        case 0x0010:    // WM_CLOSE
            handled = true; // cancel event here
            // do additional stuff here    
            break;
    }
    return IntPtr.Zero;
}
5 голосов
/ 28 декабря 2011

Существует интерфейс DWebBrowserEvents2, который имеет метод WindowClosing, который можно использовать для отмены вызова window.close().

(я нашел предложение в этой публикации )

1 голос
/ 03 августа 2014

Элемент управления WebBrowser не имеет встроенного метода для обнаружения события JavaScript.Close. Вы можете внедрить свой собственный JS, чтобы помочь вам справиться с этим, ИЛИ вы можете расширить элемент управления WebBrowser, чтобы создать событие при запуске window.close ().

С этой страницы я получил следующую информацию http://blogs.msdn.com/b/jpsanders/archive/2007/05/25/how-to-close-the-form-hosting-the-webbrowser-control-when-scripting-calls-window-close-in-the-net-framework-version-2-0.aspx

Создайте новый файл класса и поместите следующий код в

Public Class MyExtendedBrowserControl
' Based on WebBrowser
Inherits System.Windows.Forms.WebBrowser

' Define constants from winuser.h
Private Const WM_PARENTNOTIFY As Integer = &H210
Private Const WM_DESTROY As Integer = 2

'Define New event to fire
Public Event WBWantsToClose()

Protected Overrides Sub WndProc(ByRef m As Message)
    Select Case m.Msg
        Case WM_PARENTNOTIFY
            If (Not DesignMode) Then
                If (m.WParam = WM_DESTROY) Then
                    ' Tell whoever cares we are closing
                    RaiseEvent WBWantsToClose()
                End If
            End If
            DefWndProc(m)
        Case Else
            MyBase.WndProc(m)
    End Select
End Sub

End Class

Теперь вам нужно заменить встроенный вызов WebControl новым. Отредактируйте файл form1.designer.vb или как там называется ваша форма. Для этого нажмите значок «Показать все файлы» в обозревателе решений, чтобы увидеть файл конструктора. Открыв файл конструктора, замените System.Windows.Forms.WebBrowser на MyExtendedBrowserControl.

Постройте проект. Это необходимо сделать для того, чтобы элемент управления был скомпилирован и отображался без ошибок в самой форме.

Теперь, когда вы создали проект, вы сможете редактировать элемент управления и получить доступ к новому событию WBWantsToClose. Откройте форму, щелкните элемент управления WebBrowser, откройте его свойства (F4), щелкните значок «события» (молнии), дважды щелкните «WBWantsToClose». Это приведет вас в код с событием, готовым к обработке.

0 голосов
/ 29 октября 2013

Лучшее решение в WPF, которое я нашел, это использовать DispatcherTimer:

    private readonly DispatcherTimer _dispatcherTimer;

    public MyClass()
    {
        InitializeComponent();

        WBrowser.Navigate(loginUri);

        _dispatcherTimer = new DispatcherTimer();
        _dispatcherTimer.Tick += dispatcherTimer_Tick;
        _dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
        _dispatcherTimer.Start();
    }

    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        if (WBrowser.Source == null)
        {
            _dispatcherTimer.Stop();
            Close();
        }
    }
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);

        if (_dispatcherTimer.IsEnabled)
        {
            _dispatcherTimer.Stop();
        }
    }

    private void WBrowser_OnNavigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
    {
        if(!_dispatcherTimer.IsEnabled)
        {
            _dispatcherTimer.Start();
        }
    }
0 голосов
/ 28 декабря 2011

Какую версию элемента управления WebBrowser вы используете?WinForms one или WPF one?

Для элемента управления WinForms можно попытаться обработать событие Disposed или HandleDestroyed элемента управления WebBrowser, чтобы закрытьВаша родительская форма тоже.Для элемента управления WPF вы можете попробовать то же самое с событием Unloaded .

Я не знаю, может ли другой код JS привести к тем же проблемам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...