Groups | Blog | Home
all groups > dotnet interop > march 2005 >

dotnet interop : Initializing IE from a string (IPersistStreamInit & UCOMIStream) ?


Glass Half Full
3/13/2005 6:37:25 PM
I would like to know how to initialize (load html) Internet Explorer from a
string rather than a file. I know that I can navigate to "about:blank",
grab the HTMLdocument, then directly set the body.innerHTML, but that's a
bit of a hack that leaves certain things improperly configured (for example
when you "View Source" something set this way you get "<HTML></HTML>", plus
a form I've placed on the page in this way doesn't seem to fire it's submit
event ... I assume because it doesn't get properly 'wired-up' <shrug>).

I have read some posts that suggest that this sort of string loading can be
done via IPersistStreamInit and UCOMIStream, but it's not obvious to me how
this should be done. Between SHDocVw and mshtml there are a dizzying number
of objects, interfaces and events.

Does anyone have a simple "<HTML>Hello World</HTML>" kind of example of how
do this in .NET (c# if possible) ?

Thanks

v-phuang NO[at]SPAM online.microsoft.com (
3/14/2005 6:34:48 AM
Hi

Based on the link below we know that navigating to about:blank is the first
steps to use the IPersistStreamInit interface to load html contect from a
stream.
Loading HTML content from a Stream
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrows
er/tutorials/webocstream.asp

private void button1_Click(object sender, System.EventArgs e)
{
string html = "<html><head></head><body><p>Hello</body></html>";
SHDocVw.InternetExplorer internetExplorer = new
SHDocVw.InternetExplorerClass();
SHDocVw.IWebBrowser2 webBrowser = (SHDocVw.IWebBrowser2)internetExplorer;
webBrowser.Visible = true;
object noValue = System.Reflection.Missing.Value;
webBrowser.Navigate("about:blank", ref noValue, ref noValue, ref
noValue, ref noValue);
mshtml.IHTMLDocument2 htmlDoc = internetExplorer.Document as
mshtml.IHTMLDocument2;
htmlDoc.writeln(html);
htmlDoc.close();
}

After I use the View Source, I found that I can not the string now as below.
<html><head></head><body><p>Hello</body></html>

which is what we have set into the webbrowser.

You may have a try and let me know the result.
Otherwise can you post the reproduce sample. e.g. the html string you want
to show in the webbrowser.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Glass Half Full
3/14/2005 5:53:19 PM
Mr. Huang,

Thank you very much for your reply. The information provided was quite
helpful and a great deal easier to use than I was anticipating.
Unfortunately, I still have some problems. Using the html document write
method solved the issue with display source, but not with the onsubmit
event. I have included simple example code of what I'm doing. What I see
with this code is as follows:

The form will come up and I press the "Go" button to run the code that
uses the browser.
After "Go" the page loads as expected.
When I double click in the form element, a breakpoint set in my
catchDblClick method is hit.
When I press the "Submit" button on that same form element most of the
time nothing happens, sometimes it attempts to submit, but never does the
breakpoint in my catchSubmit method get hit.

This brought to light another issue, with using the "tab" key on the form.
Sometimes "tab" will just move me between the browser and the "Go" button,
sometimes it will move me through the web page form elements (Submit button
and text box) and the "Go" button. The behaviour seems random. I would
like to find a way so that the tab would move thought the webpage when the
focus is on the browser control (it would be really nice if it moved out of
the browser control when the last web page element was tabbed from).

Thank you

Code:
-----------------------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace iejunk
{
public class Form1 : System.Windows.Forms.Form
{
private AxSHDocVw.AxWebBrowser axWebBrowser1;
private System.Windows.Forms.Button button1;

private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new
System.Resources.ResourceManager(typeof(Form1));
this.axWebBrowser1 = new AxSHDocVw.AxWebBrowser();
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.axWebBrowser1)).BeginInit();
this.SuspendLayout();
//
// axWebBrowser1
//
this.axWebBrowser1.Anchor =
((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.axWebBrowser1.Enabled = true;
this.axWebBrowser1.Location = new System.Drawing.Point(3, 2);
this.axWebBrowser1.OcxState =
((System.Windows.Forms.AxHost.State)(resources.GetObject("axWebBrowser1.OcxState")));
this.axWebBrowser1.Size = new System.Drawing.Size(909, 575);
this.axWebBrowser1.TabIndex = 0;
//
// button1
//
this.button1.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom
| System.Windows.Forms.AnchorStyles.Left)));
this.button1.Location = new System.Drawing.Point(8, 582);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "Go";
this.button1.Click += new
System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(915, 607);
this.Controls.Add(this.button1);
this.Controls.Add(this.axWebBrowser1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.axWebBrowser1)).EndInit();
this.ResumeLayout(false);

}
#endregion

[STAThread]
static void Main()
{
Application.Run(new Form1());
}


//____________________________________________________________________________________________
private void BrowserReady(object sender,
AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent evt) {
if (sender != axWebBrowser1) {
return;
}

axWebBrowser1.DocumentComplete -= new
AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.BrowserReady);

mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)
axWebBrowser1.Document;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
string eol = System.Environment.NewLine;

sb.Append("<HTML>" + eol + "<BODY>" + eol + "<H1>Header</H1>");
sb.Append("<table border=\"1\" width=\"100%\">" + eol);
// header
sb.Append("<tr>" + eol);
sb.Append("<td width=\"20%\" bgcolor=\"#C0C0C0\" >Property</td>"
+ eol);
sb.Append("<td width=\"80%\" bgcolor=\"#C0C0C0\" >Value</td>" +
eol);
sb.Append("</tr>" + eol);
// BI Path
sb.Append("<tr>" + eol);
sb.Append("<td width=\"20%\">Name</td>" + eol);
sb.Append("<td width=\"80%\">Static@nospam.nospam</td>" + eol);
sb.Append("</tr>" + eol);
sb.Append("</table>" + eol);

sb.Append("<br>" + eol);
sb.Append("<hr>" + eol);
sb.Append("<form method=\"POST\" name=\"MyForm\"
action=\"about:blank\">" + eol);
sb.Append("<p><input type=\"submit\" value=\"Submit\"
name=\"B1\"></p>" + eol);
sb.Append("<p><input type=\"text\" name=\"T1\" value=\"some
text\" size=\"20\"></p>" + eol);
sb.Append("</form>" + eol);
sb.Append("<hr>" + eol);

sb.Append("</BODY>" + eol +"</HTML>" + eol);

doc.write(sb.ToString());

mshtml.IHTMLElementCollection eles =
(mshtml.IHTMLElementCollection) doc.all;
mshtml.HTMLFormElement theForm = (mshtml.HTMLFormElement)
eles.item("MyForm", 0);
((mshtml.HTMLFormElementEvents2_Event) theForm).onsubmit += new
mshtml.HTMLFormElementEvents2_onsubmitEventHandler(this.catchSubmit);
((mshtml.HTMLFormElementEvents2_Event) theForm).ondblclick +=
new
mshtml.HTMLFormElementEvents2_ondblclickEventHandler(this.catchDblClick);
}


v-phuang NO[at]SPAM online.microsoft.com (
3/15/2005 8:29:52 AM
Hi,

Currently I am researching the issue and we will reply here with more
information as soon as possible.
If you have any more concerns on it, please feel free to post here.

Thanks for your understanding!

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
v-phuang NO[at]SPAM online.microsoft.com (
3/16/2005 7:22:18 AM
Hi

Based on my research, it seems that when we click the submit button, the
webbrowser will try to redirect to another URL(the action section), then
the webbrowser will try to dispose the form, htmlelement etc. But now our
programm is keeping the reference to the form which will prevent the form
to be dispose, while if we dispose it too early the event will not fire,
because the instance has been disposed.

So as a workaround I think we can add a reference to the submit button,
after we click the button but before the submit raised, we will fire a
button click event,in the event handler, we need to release the com
reference to the form and the button, so that the following submit process
which will redirect to another url will go through.

mshtml.HTMLFormElement theForm=null;
mshtml.HTMLButtonElement btn=null;
private void BrowserReady(object sender,
AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent evt)
{
if (sender != axWebBrowser1)
{
return;
}

axWebBrowser1.DocumentComplete -= new

AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.BrowserReady)
;

mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)
axWebBrowser1.Document;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
string eol = System.Environment.NewLine;

sb.Append("<HTML>" + eol + "<BODY>" + eol + "<H1>Header</H1>");
sb.Append("<table border=\"1\" width=\"100%\">" + eol);
// header
sb.Append("<tr>" + eol);
sb.Append("<td width=\"20%\" bgcolor=\"#C0C0C0\" >Property</td>"
+ eol);
sb.Append("<td width=\"80%\" bgcolor=\"#C0C0C0\" >Value</td>" +
eol);
sb.Append("</tr>" + eol);
// BI Path
sb.Append("<tr>" + eol);
sb.Append("<td width=\"20%\">Name</td>" + eol);
sb.Append("<td width=\"80%\">Static@nospam.nospam</td>" + eol);
sb.Append("</tr>" + eol);
sb.Append("</table>" + eol);

sb.Append("<br>" + eol);
sb.Append("<hr>" + eol);
sb.Append("<P><INPUT id=button1 type=button value=Button
name=button1></P>" + eol);
sb.Append("<form method=\"POST\" name=\"MyForm\" action=\"about:blank\">"
+ eol);
sb.Append("<p><input type=\"submit\" value=\"Submit\" name=\"B1\"></p>" +
eol);
sb.Append("<p><input type=\"text\" name=\"T1\" value=\"some text\"
size=\"20\"></p>" + eol);
sb.Append("</form>" + eol);
sb.Append("<hr>" + eol);

sb.Append("</BODY>" + eol +"</HTML>" + eol);

doc.write(sb.ToString());
doc.writeln(new object[]{"<br>"});
doc.close();

mshtml.IHTMLElementCollection eles =
(mshtml.IHTMLElementCollection) doc.all;
btn = (mshtml.HTMLButtonElement)
eles.item("B1", 0);
((mshtml.HTMLButtonElementEvents_Event)btn).onclick +=new
mshtml.HTMLButtonElementEvents_onclickEventHandler(Form1_onclick);//Add a
button click event handler.

theForm = (mshtml.HTMLFormElement)
eles.item("MyForm", 0);
((mshtml.HTMLFormElementEvents2_Event) theForm).ondblclick +=
new
mshtml.HTMLFormElementEvents2_ondblclickEventHandler(this.catchDblClick);
System.Runtime.InteropServices.Marshal.ReleaseComObject(eles);
eles = null;

}
private bool Form1_onclick()
{
Console.WriteLine("Button clicked");
System.Runtime.InteropServices.Marshal.ReleaseComObject(btn);//Release the
button com reference
btn = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(theForm);//Release
the form com reference.
theForm = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
return true;
}

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
AddThis Social Bookmark Button