Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7061833
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T04:31:19+00:00 2026-05-28T04:31:19+00:00

I have a WinForms application in which I have hosted a web page inside

  • 0

I have a WinForms application in which I have hosted a web page inside a WebBrowser control.

The contents of the web page is the following:

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <title>onbeforeunload test</title>
  <meta charset="utf-8">
</head>
<body>

<a href="#" onclick="window.location.reload();">Test</a>

<script type="text/javascript">
    window.onbeforeunload = function () {
        return 'Are you sure you want to leave this page?';
    };
</script>
</body>
</html>

As you can see I have subscribed to the onbeforeunload event which allows to show a confirmation dialog before navigating away from this page. This works fine when I click on the anchor that reloads the page. The confirmation box is shown and the user can cancel the reload of the page. This works fine inside the WinForms hosted control.

Now, what I am having difficulties with is intercepting and executing this event when the user closes the WinForms application (by clicking on the X button for example).

I am able to fetch the contents of this function in the WinForms application but no matter what I tried I wasn’t able to get the contents of the string that this function returns so that I can use it later to fake a MessageBox when the user attempts to close the application:

webBrowser1.Navigated += (sender, e) =>
{
    webBrowser1.Document.Window.Load += (s, ee) =>
    {
        // In order to get the IHTMLWindow2 interface I have referenced
        // the Microsoft HTML Object Library (MSHTML) COM control
        var window = (IHTMLWindow2)webBrowser1.Document.Window.DomWindow;

        // the bu variable contains the script of the onbeforeunload event
        var bu = window.onbeforeunload();

        // How to get the string that is returned by this function
        // so that I can subscribe to the Close event of the WinForms application
        // and show a fake MessageBox with the same text?
    };
};
webBrowser1.Navigate("file:///c:/index.htm");

I have tried the window.execScript method to no available:

// returns null
var script = string.Format("({0})();", bu);
var result = window.execScript(script, "javascript");

I have also tried the following but it also returned null:

var result = window.execScript("(function() { return 'foo'; })();", "javascript");

As a final resort I could use a third party javascript parser to which I can feed the body of this function and it will execute it and give me the return value but that would really be a last resort. I would be happy if there was a more native way to do this using Microsoft’s MSHTML library.


UPDATE:

This is now solved thanks to the excellent answer that @Hans provided. For some reason I couldn’t make his solution work on my test machine (Win7 x64, .NET 4.0 Client Profile, IE9, en-US locale) and I was always getting hr = -2147024809 after the IDispatch.Invoke call. So I have modified the IDispatch P/Invoke signature to the following (this signature doesn’t require a reference to c:\windows\system32\stdole2.tlb to be added to the project):

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

[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
    );
}

and then I have subscribed to the Closing event of the Form and was able to fetch the message returned by the onbeforeunload event and prompt the user:

protected override void OnFormClosing(FormClosingEventArgs e)
{
    var window = (IHTMLWindow2)webBrowser1.Document.Window.DomWindow;
    var args = new System.Runtime.InteropServices.ComTypes.DISPPARAMS();
    var result = new object();
    var except = new System.Runtime.InteropServices.ComTypes.EXCEPINFO();
    var idisp = window.onbeforeunload as IDispatch;
    if (idisp != null)
    {
        var iid = Guid.Empty;
        var lcid = (uint)CultureInfo.CurrentCulture.LCID;
        int hr = idisp.Invoke(0, ref iid, lcid, 1, ref args, out result, ref except, null);
        if (hr == 0)
        {
            var msgBox = MessageBox.Show(
                this,
                (string)result,
                "Confirm",
                MessageBoxButtons.OKCancel
            );
            e.Cancel = msgBox == DialogResult.Cancel;
        }
    }
    base.OnFormClosing(e);
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T04:31:19+00:00Added an answer on May 28, 2026 at 4:31 am

    IHtmlWindow2.onbeforeunload does not itself display the dialog. It merely returns a string which the host must then use in a message box. Since your Winforms app is the host it must use MessageBox.Show(). Calling onbeforeunload is difficult, it is an IDispatch pointer whose default member (dispid 0) returns the string. Add a reference to c:\windows\system32\stdole2.tlb and paste this code:

    using System.Runtime.InteropServices;
    ...
            [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")]
            public interface IDispatch {
                int dummy1();
                int dummy2();
                int dummy3();
                [PreserveSig]
                int Invoke(int dispIdMember, ref Guid riid, int lcid, int dwFlags, 
                    [In, Out] stdole.DISPPARAMS pDispParams, 
                    [Out, MarshalAs(UnmanagedType.LPArray)] object[] pVarResult, 
                    [In, Out] stdole.EXCEPINFO pExcepInfo, 
                    [Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] pArgErr);
            }
    

    You’ll use it like this:

        protected override void OnFormClosing(FormClosingEventArgs e) {
            var window = (IHTMLWindow2)webBrowser1.Document.Window.DomWindow;
            var args = new stdole.DISPPARAMS();
            var result = new object[1];
            var except = new stdole.EXCEPINFO();
            var idisp = (IDispatch)window.onbeforeunload;
            var iid = Guid.Empty;
            int hr = idisp.Invoke(0, ref iid, 1033, 1, args, result, except, null);
            if (hr == 0) {
                if (MessageBox.Show(this, (string)result[0], "Confirm",
                    MessageBoxButtons.OKCancel) == DialogResult.Cancel) e.Cancel = true;
            }
            base.OnFormClosing(e);                                                       
        }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a C# 3.0 WinForms application which is occasionally required to control Excel
I have a web application which is also displayed in a web browser control
I have a WCF service which is hosted in a WinForms application. This WCF
I have a list box on my WinForms application which populates with the following
The following problem has me stumped: I have a WinForms application which used to
We have a WinForms application which runs on a touch-screen on a bit of
I have a winforms application in which I am using 2 Forms to display
I have a WinForms application with a DataGridView control and a column of DataGridViewButtonCell
I have a WinForms gui application which has a number of areas to it
I am new to Microsoft Dynamic CRM. I have a .NET Winforms application which

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.