Jeff Sanders Technical Blog

I am a Microsoft employee that has worked on all aspects of the Web Stack for a long time. I hope these blogs are useful to you! Use this information at your own risk.


<< Go Back

How To Wire The Readystatecomplete Event From The Xmlhttp Object In Internetexplorer Net

- 06 Mar 2008

I have a web page that has a global variable in the jscript called xmlhttp.  It is the build in XMLHttp object in Internet Explorer.  I am hosting the WebBrowser control in a C# (.NET managed code) application and I want to know when the XMLHttp object is done.  This occurs after the document complete event so how do I do this?

 Answer:

This worked for me!  Using Visual Studio 2008:

Create a new C# Windows Form Application Called XMLHttpReadyState
Add a WebBrowser control to the form
Double click on the WebBrowser in the form to add the documentComplete event handler.
Add a function to wire the XMLHttp Event.

Here is the commented code.  Let me know if this is useful and if it works out for you!<p mce_keep="true"> </p>

<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System;<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System.Collections.Generic;<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System.ComponentModel;<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System.Data;<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System.Drawing;<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System.Linq;<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System.Text;<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System.Windows.Forms;<font color=#0000ff size=2><font color=#0000ff size=2>

using

</font></font> System.Runtime.InteropServices;<font color=#0000ff size=2><font color=#0000ff size=2>

namespace

</font></font> XMLHttpReadyState

{</p>

</font><font color=#0000ff size=2><font color=#0000ff size=2>public</font></font> <font color=#0000ff size=2><font color=#0000ff size=2>partial</font></font> <font color=#0000ff size=2><font color=#0000ff size=2>class</font></font> <font color=#2b91af size=2><font color=#2b91af size=2>Form1</font></font> : <font color=#2b91af size=2><font color=#2b91af size=2>Form</font></font>

{</p>

</font><font color=#0000ff size=2><font color=#0000ff size=2>public</font></font> Form1()

{

InitializeComponent();

}</p>

</font><font color=#0000ff size=2><font color=#0000ff size=2>private</font></font> <font color=#0000ff size=2><font color=#0000ff size=2>void</font></font> webBrowser1_DocumentCompleted(<font color=#0000ff size=2><font color=#0000ff size=2>object</font></font> sender, <font color=#2b91af size=2><font color=#2b91af size=2>WebBrowserDocumentCompletedEventArgs</font></font> e)

{</p>

</font><font color=#008000 size=2><font color=#008000 size=2>//when the document is done loading, wire up the XMLHttp object (if it exists)</font></font>

wireXMLHttpReadyState();

}</p>

</font><font color=#008000 size=2><font color=#008000 size=2>// This class is used for the readystatechange callback. This callback expects an IDispatch interface.</font></font>

</font><font color=#008000 size=2><font color=#008000 size=2>// The constructor takes an Object which is the XMLHttp Obj so we can easily get the readystate.</font></font>

</font><font color=#008000 size=2><font color=#008000 size=2>// You could also simply go get the ready state by navigating down from the webbrowser document object.</font></font>

[

</font><font color=#2b91af size=2><font color=#2b91af size=2>ComVisible</font></font>(<font color=#0000ff size=2><font color=#0000ff size=2>true</font></font>)] <font color=#008000 size=2><font color=#008000 size=2>//this is necessary or you get an Invalid Cast exception</font></font>

</font><font color=#0000ff size=2><font color=#0000ff size=2>public</font></font> <font color=#0000ff size=2><font color=#0000ff size=2>class</font></font> <font color=#2b91af size=2><font color=#2b91af size=2>ReadyState</font></font>

{</p>

</font><font color=#0000ff size=2><font color=#0000ff size=2>public</font></font> ReadyState(<font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font> theXMLHttpObj) { setObj( theXMLHttpObj); }

</font><font color=#008000 size=2><font color=#008000 size=2>// DispId 0 is what the XMLHttpObj will call, the name does not matter</font></font>

[

</font><font color=#2b91af size=2><font color=#2b91af size=2>DispId</font></font>(0)]

</font><font color=#0000ff size=2><font color=#0000ff size=2>public</font></font> <font color=#0000ff size=2><font color=#0000ff size=2>void</font></font> onMyImplOfreadystatechange()

{</p>

</font><font color=#0000ff size=2><font color=#0000ff size=2>if</font></font> (m_XMLHttpObj != <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>)

{</p>

</font><font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font> theState = <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>;

theState = m_XMLHttpObj.GetType().InvokeMember(

</font><font color=#a31515 size=2><font color=#a31515 size=2>“readyState”</font></font>, System.Reflection.<font color=#2b91af size=2><font color=#2b91af size=2>BindingFlags</font></font>.GetProperty, <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>, m_XMLHttpObj, <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>);

</font><font color=#2b91af size=2><font color=#2b91af size=2>MessageBox</font></font>.Show(theState.ToString());

</font><font color=#008000 size=2><font color=#008000 size=2>// State 4 means done</font></font>

</font><font color=#0000ff size=2><font color=#0000ff size=2>if</font></font> ((<font color=#0000ff size=2><font color=#0000ff size=2>int</font></font>)theState == 4)

{<p mce_keep="true"> </p> </p>

</font><font color=#008000 size=2><font color=#008000 size=2>// done so release the XMLHttpObj</font></font>

setObj(

</font><font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>);

}

}</p>

</font><font color=#0000ff size=2><font color=#0000ff size=2>else</font></font>

{</p>

</font><font color=#008000 size=2><font color=#008000 size=2>// should not happen!</font></font>

</font><font color=#2b91af size=2><font color=#2b91af size=2>MessageBox</font></font>.Show(<font color=#a31515 size=2><font color=#a31515 size=2>“XMLHTTP obj not set”</font></font>);

}<p mce_keep="true"> </p>

}</p>

</font><font color=#0000ff size=2><font color=#0000ff size=2>public</font></font> <font color=#0000ff size=2><font color=#0000ff size=2>void</font></font> setObj(<font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font> theObj){m_XMLHttpObj=theObj;}

</font><font color=#0000ff size=2><font color=#0000ff size=2>private</font></font> <font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font> m_XMLHttpObj;

}</p>

</font><font color=#0000ff size=2><font color=#0000ff size=2>private</font></font> <font color=#0000ff size=2><font color=#0000ff size=2>void</font></font> wireXMLHttpReadyState()

{</p>

</font><font color=#008000 size=2><font color=#008000 size=2>// get the DomDocument</font></font>

</font><font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font> aDomObj = webBrowser1.Document.DomDocument;

</font><font color=#0000ff size=2><font color=#0000ff size=2>if</font></font> (aDomObj!=<font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>)

{</p>

</font><font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font> theScript = aDomObj.GetType().InvokeMember(<font color=#a31515 size=2><font color=#a31515 size=2>“Script”</font></font>, System.Reflection.<font color=#2b91af size=2><font color=#2b91af size=2>BindingFlags</font></font>.GetProperty, <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>, aDomObj, <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>);

</font><font color=#0000ff size=2><font color=#0000ff size=2>if</font></font> (theScript != <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>)

{</p>

</font><font color=#008000 size=2><font color=#008000 size=2>// Get the script engine interface</font></font>

</font><font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font> theXMLHttpObj = theScript.GetType().InvokeMember(<font color=#a31515 size=2><font color=#a31515 size=2>“xmlHttp”</font></font>, System.Reflection.<font color=#2b91af size=2><font color=#2b91af size=2>BindingFlags</font></font>.GetProperty, <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>, theScript, <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>);

</font><font color=#0000ff size=2><font color=#0000ff size=2>if</font></font> (theXMLHttpObj != <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>)

{</p>

</font><font color=#008000 size=2><font color=#008000 size=2>// wrap the Object as an IDispatch COM interface and…</font></font>

</font><font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font> toPass = <font color=#0000ff size=2><font color=#0000ff size=2>new</font></font> <font color=#2b91af size=2><font color=#2b91af size=2>DispatchWrapper</font></font>(<font color=#0000ff size=2><font color=#0000ff size=2>new</font></font> <font color=#2b91af size=2><font color=#2b91af size=2>ReadyState</font></font>(theXMLHttpObj));

</font><font color=#008000 size=2><font color=#008000 size=2>// pass it to the method in an argument array</font></font>

</font><font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font>[] aArgs = <font color=#0000ff size=2><font color=#0000ff size=2>new</font></font> <font color=#2b91af size=2><font color=#2b91af size=2>Object</font></font>[1];

aArgs[0] = toPass;

theXMLHttpObj.GetType().InvokeMember(

</font><font color=#a31515 size=2><font color=#a31515 size=2>“onreadystatechange”</font></font>, System.Reflection.<font color=#2b91af size=2><font color=#2b91af size=2>BindingFlags</font></font>.SetProperty, <font color=#0000ff size=2><font color=#0000ff size=2>null</font></font>, theXMLHttpObj, aArgs);

}

}

}

}

}

}<p mce_keep="true"> </p>

Sample HTML:

<body onload=’doxmlstuff();’> <script language=”javascript”> var xmlHttp = null; if (window.XMLHttpRequest) {   // If IE7, Mozilla, Safari, and so on: Use native object.   xmlHttp = new XMLHttpRequest(); } else {   if (window.ActiveXObject) {      // …otherwise, use the ActiveX control for IE5.x and IE6.      xmlHttp = new ActiveXObject(‘MSXML2.XMLHTTP.3.0’);   } } var MyName = “Bill Gates”; function ShowName() { alert(“MyName = ” + MyName); } function doxmlstuff() {   if(xmlHttp)  {  xmlHttp.open(“GET”, “<http://jsandersrvista/test.xml>“, true); xmlHttp.send();  } } </script> Hello there.
</body>

 <p mce_keep="true"> </p>

</font>

<< Go Back