none
System.Windows.Forms.WebBrowser does not handle window.close() in C# / .NET3.5

    Question

  • I have seen the postings that said this is a problem in C# / .NET 2.0, but it seems this is still a problem in 3.5.  If an HTML page has a button that calls "window.close()", clicking on the button does not close the window.  I tried the workarounds posted for 2.0 (override the WndProc() method), and they don't seem to work.

    Sample HTML:

    <HTML>
    <HEAD>
    <TITLE>Close Test</TITLE>
    </HEAD>
    <BODY>
    <FORM>
    <input class=button90 type=button value="Close Window" onclick=window.close()></input>
    </FORM>
    </BODY>
    </HTML>

     Sample Code:

    public class Browser : System.Windows.Forms.Form
    {
    private System.Windows.Forms.WebBrowser myBrowser;
    ...
    public Browser()
    {
    this.myBrowser = new System.Windows.Forms.WebBrowser();
    this.myBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
    this.myBrowser.Location = new System.Drawing.Point(0, 0);
    this.myBrowser.Size = new System.Drawing.Size(924, 682);
    this.myBrowser.TabIndex = 0;
    this.myBrowser.HandleDestroyed += new EventHandler(myHandleDestroyed);
    }
    ...
    private void myHandleDestroyed(object sender, EventArgs e)
    {
    this.Close();
    }
    ...
    }
    Any thoughts or suggestions?
    • Moved by CoolDadTxMVP Thursday, April 15, 2010 1:43 PM WinForms related (From:Visual C# General)
    Thursday, April 15, 2010 12:49 PM

Answers

  • My solution is based on a similar solution posted HERE.

      // A delegate type for hooking up close notifications.
      public delegate void ClosingEventHandler(object sender, EventArgs e);
    
      // We need to extend the basic Web Browser because when a web page calls
      // "window.close()" the containing window isn't closed.
      public class ExtendedWebBrowser : WebBrowser
      {
        // Define constants from winuser.h
        private const int WM_PARENTNOTIFY = 0x210;
        private const int WM_DESTROY = 2;
    
        public event ClosingEventHandler Closing;
    
        protected override void WndProc(ref Message m)
        {
          switch (m.Msg)
          {
            case WM_PARENTNOTIFY:
              if (!DesignMode)
              {
                if (m.WParam.ToInt32() == WM_DESTROY)
                {
                  Closing(this, EventArgs.Empty);
                }
              }
              DefWndProc(ref m);
              break;
            default:
              base.WndProc(ref m);
              break;
          }
        }
      }
    

    Then your containing class has the following:

    ...
      private ExtendedWebBrowser browserControl;
    ...
      this.browserControl.Closing +=new ClosingEventHandler(browserControl_Closing);
    ...
      private void browserControl_Closing(object sender, EventArgs e)
      {
        this.Close();
      }
    

    By raising an event it allows any class to know when the browser gets closed simply by registering for it.

    • Marked as answer by TPLrtn Tuesday, June 01, 2010 3:15 PM
    Tuesday, June 01, 2010 3:15 PM

All replies

  • A couple thoughts:

    Does that button close an independent browser window that is not hosted in your application?  If so, do you get a dialog asking if it's OK to close?

    Does the myHandleDestroyed event handler get called? 

     

     


    Dave Swersky
    Thursday, April 15, 2010 4:35 PM
  • > Does that button close an independent browser window that is not hosted in your application?

    When I load the HTML in I.E. I have to "Allow Blocked Content".  Once that's done, when I click on the CLOSE WINDOW button the "Do you want to close this window?" dialog appears, and when I click Yes, I.E. closes.

    > Does the myHandleDestroyed event handler get called?

    I added 'MessageBox.Show("HERE");' to myHandleDestroyed() and when I click on the CLOSE WINDOW button the "Do you want to close this window?" dialog appears, and when I click Yes, nothing happens.  When I click on the "X" to manually close the System.Windows.Forms.WebBrowser, the "HERE" dialog appears and the browser disappears.

    Should I be using a different Event Handler?  Is there a property I need to enable or a mathod I need to call to "Allow Blocked Content"?

    Wednesday, April 28, 2010 2:41 PM
  • My solution is based on a similar solution posted HERE.

      // A delegate type for hooking up close notifications.
      public delegate void ClosingEventHandler(object sender, EventArgs e);
    
      // We need to extend the basic Web Browser because when a web page calls
      // "window.close()" the containing window isn't closed.
      public class ExtendedWebBrowser : WebBrowser
      {
        // Define constants from winuser.h
        private const int WM_PARENTNOTIFY = 0x210;
        private const int WM_DESTROY = 2;
    
        public event ClosingEventHandler Closing;
    
        protected override void WndProc(ref Message m)
        {
          switch (m.Msg)
          {
            case WM_PARENTNOTIFY:
              if (!DesignMode)
              {
                if (m.WParam.ToInt32() == WM_DESTROY)
                {
                  Closing(this, EventArgs.Empty);
                }
              }
              DefWndProc(ref m);
              break;
            default:
              base.WndProc(ref m);
              break;
          }
        }
      }
    

    Then your containing class has the following:

    ...
      private ExtendedWebBrowser browserControl;
    ...
      this.browserControl.Closing +=new ClosingEventHandler(browserControl_Closing);
    ...
      private void browserControl_Closing(object sender, EventArgs e)
      {
        this.Close();
      }
    

    By raising an event it allows any class to know when the browser gets closed simply by registering for it.

    • Marked as answer by TPLrtn Tuesday, June 01, 2010 3:15 PM
    Tuesday, June 01, 2010 3:15 PM