2011-04-04 77 views
9

如果我是主持人在我的應用程序WebBrowser,並在我的web瀏覽器中顯示網頁中的JavaScript代碼調用window.close()和我點擊該提示,我WebBrowser消失,但我的形式「是」保持開放。web瀏覽器和JavaScript window.close()的

我不想禁用JavaScript,而不是按「是」顯然不是解決方案。處理這個問題的最好方法是什麼?即使在用戶按下「是」之後,我可以以編程方式取消該操作嗎?還有,有沒有其他的JavaScript技巧,如window.close(),可以搞砸我的應用程序,我應該知道的? (我的應用程序使用WebBrowser來搜索網頁,因此應考慮每個可能的javascript代碼。)

回答

5

有一個interface DWebBrowserEvents2它有一個method WindowClosing你可以用它來取消window.close()調用。

(我發現this posting建議)

+1

這是正確的,但您必須使用P/Invoke調用來實現此目的(WebBrowser控件不公開此事件)。 – CedX 2011-12-28 18:13:00

+0

@CédricBelin這是一個尋找和使用正確的界面(來自SHDocVw)和鑄造的問題。 – 2011-12-28 18:40:06

+5

任何人都可以詳細說明「你可以使用」這個嗎? – teynon 2013-05-22 15:26:08

0

您正在使用哪個版本的WebBrowser控件? WinForms的還是WPF的?

對於WinForms控件,您可以嘗試處理WebBrowser控件的DisposedHandleDestroyed事件,以便關閉父窗體。對於WPF控件,您可以嘗試與Unloaded事件相同。

我不知道其他JS代碼是否會導致相同的問題。

+0

只是一個頭(我知道的舊線程),但卸載/處置不會引發javascript window.close()被調用時。 – 2013-03-20 03:25:43

0

我發現在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(); 
     } 
    } 
4

在WPF可以通過附加到Web瀏覽器的消息趕上WM_CLOSE消息循環。

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; 
} 
+0

我已使用此代碼,並正常工作。有一點需要注意,當使用IDE的屬性窗口分配事件時,缺少處理參數的'ref'部分。只需將其放回簽名中即可正常編譯。 – mickeymicks 2014-06-04 10:06:35

0

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 

現在,你必須更換內置的Web控件喚起這個新的一個。編輯form1.designer.vb文件或任何您的窗體被稱爲。爲此,請在解決方案資源管理器中單擊「顯示所有文件」圖標以查看設計器文件。一旦你打開了設計器文件,用MyExtendedBrowserControl替換System.Windows.Forms.WebBrowser。

構建項目。你需要這樣做來編譯控件,並在窗體本身上顯示沒有錯誤。

現在您構建了該項目,您將能夠編輯該控件並訪問新的WBWantsToClose事件。打開窗體,單擊WebBrowser控件,打開其屬性(F4),單擊「事件」圖標(閃電),雙擊「WBWantsToClose」。這將帶您進入代碼,並準備好處理事件。