Before I go off and code this, I thought I\'d see if anyone here knows of any open source (or paid for) equivalents already built.
I\'m looking for a browser control whe
Here's a crude version using the .NET WebBrowser control, which uses Internet Explorer.
namespace WindowsFormsApplication1
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
public partial class Form1 : System.Windows.Forms.Form
{
private HtmlDocument document;
private IDictionary<HtmlElement, string> elementStyles = new Dictionary<HtmlElement, string>();
public Form1()
{
InitializeComponent();
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
this.Text = e.Url.ToString();
this.document = this.webBrowser1.Document;
this.document.MouseOver += new HtmlElementEventHandler(document_MouseOver);
this.document.MouseLeave += new HtmlElementEventHandler(document_MouseLeave);
}
private void document_MouseLeave(object sender, HtmlElementEventArgs e)
{
HtmlElement element = e.FromElement;
if (this.elementStyles.ContainsKey(element))
{
string style = this.elementStyles[element];
this.elementStyles.Remove(element);
element.Style = style;
}
}
private void document_MouseOver(object sender, HtmlElementEventArgs e)
{
HtmlElement element = e.ToElement;
if (!this.elementStyles.ContainsKey(element))
{
string style = element.Style;
this.elementStyles.Add(element, style);
element.Style = style + "; background-color: #ffc;";
this.Text = element.Id ?? "(no id)";
}
}
}
}
I had a similar need and the code originally posted was a tremendous help. I would like to return the kindness of the original author.
The answer provided is insufficient. It only answers the first part of the request: highlighting the rendered HTML. It does not solve the second half of the request where the C# program can tell which node is selected.
As the mouse enters the form and moves towards the desired rendered area, the highlight will follow the mouse. This means that potentially many HTML elements will be visited by the mouse.
So how can the C# tell which element the user wants?
The program has to allow the user to click on the desired rendered area. The click should be trapped by the C# program. In addition, the C# should disable the click being delivered to the element (for example, if its an Anchor element you don't want the click to follow the link).
I solved this in my program as follows:
(1) On the 'document complete' event I added a trap (only once for the document) for the click event at the document level:
HtmlDocument htmlDoc = webBrowser.Document;
_document = webBrowser.Document;
//-- add our handler only once
if (!_documentHandlers.Contains(_document))
{
_document.MouseOver += new HtmlElementEventHandler(document_MouseOver);
_document.MouseLeave += new HtmlElementEventHandler(document_MouseLeave);
mshtml.HTMLDocumentEvents2_Event iEvent;
IHTMLDocument2 currentDoc = (IHTMLDocument2) webBrowser.Document.DomDocument;
iEvent = (mshtml.HTMLDocumentEvents2_Event) currentDoc;
iEvent.onclick += new mshtml.HTMLDocumentEvents2_onclickEventHandler(clickDocumentHandler);
_documentHandlers.Add(_document);
}
The 'document completed' event can be triggered several times for the same document (try CNN.com). The '_documentHandlers' variable is a HashSet to make sure we only add the handler one time per a given document.
(2) I also chose to trap the click at the element level. On the 'mouse over' I added:
mshtml.HTMLElementEvents2_Event iEvent;
iEvent = element.DomElement as mshtml.HTMLElementEvents2_Event;
if (iEvent == null)
return;
iEvent.onclick += new mshtml.HTMLElementEvents2_onclickEventHandler(clickElementHandler);
and at the 'mouse leave' I unregistered the click handler:
mshtml.HTMLElementEvents2_Event iEvent;
iEvent = element.DomElement as mshtml.HTMLElementEvents2_Event;
if (iEvent == null)
return;
iEvent.onclick -= new mshtml.HTMLElementEvents2_onclickEventHandler(clickElementHandler);
(3) the click handlers are simple:
private bool clickDocumentHandler(IHTMLEventObj pEvtObj)
{
IHTMLElement element = (mshtml.IHTMLElement)pEvtObj.srcElement;
pEvtObj.cancelBubble = true;
pEvtObj.returnValue = false;
return false;
}
private bool clickElementHandler(IHTMLEventObj pEvtObj)
{
IHTMLElement element = (mshtml.IHTMLElement)pEvtObj.srcElement;
pEvtObj.cancelBubble = true;
pEvtObj.returnValue = false;
return false;
}
Note that they cancel the bubbling of event and return a value of 'false' to prevent the click from percolating upwards.
In these handlers you can add your specific code to save the element being clicked and then use it elsewhere in your application.
Note that at the element level, not every IHTMLElement supports an onclick handler hence the check for null.
-Enjoy David