When OnDocumentComplete is fired, you call GetDHTMLDocument to get a IHTMLDocument2 class. From then, you call get_all and go thru the elements received.
Here is a sample code, the variables are in French but I hope it is understandable enough.
// Méthode: AssocierTagClass
// Desc. : Associe l'événement de tous les éléments HTML d'un type donné et d'une classe donnée
// à une fonction.
// Param. : strNomTag (entrée) Type d'élément HTML
// strNomClasse(entrée) Nom de la classe impliquée ou "" pour toutes les classes
// strNomEven (entrée) nom de l'événement (comme "onclick")
// varFO (entrée) pointeur vers la fonction à appeler ou NULL pour enlever l'événement
// Retour : Aucun
void VueDHTML::AssocierTagClass(CString strNomTag, CString strNomClasse, CString strNomEven, CComVariant varFO)
IHTMLElementCollection *pToutTags = NULL;
long lNbTags = 0;
IHTMLElementCollection *pToutTagSpec = NULL;
CComVariant varPosition = 0;
CComVariant varIndex = 0;
hr = GetDHtmlDocument(&pDocument);
if (SUCCEEDED(hr) && pDocument)
hr = pDocument->get_all(&pToutTags);
if (SUCCEEDED(hr) && pToutTags)
hr = pToutTags->tags(CComVariant(strNomTag), &pInterface);
if (SUCCEEDED(hr) && pInterface)
hr = pInterface->QueryInterface(&pToutTagSpec);
if (SUCCEEDED(hr) && pToutTagSpec)
hr = pToutTagSpec->get_length(&lNbTags);
for (long i=0; iitem(varPosition, varIndex, &pItem);
if (SUCCEEDED(hr) && pItem)
hr = pItem->QueryInterface(&pElement);
if (SUCCEEDED(hr) && pElement)
hr = pElement->get_className(&bstrClasse);
strClasse = bstrClasse;
This article is excellent, but I can't understand why the class is derived from CView and not from CWnd: it's obvious that this "view" will never be associated to a "document" (in the Document/View architecture sense).
Well, the view may very well be connected to a document depending on the data being display. I use the HTML interface as a plain "display GUI", not a browser. All data and the physical RPC-connection is contained in the document so I don't think it's that "obvious"...
But, anyway, I have also rewritten the class to use CWnd instead.
Thanks a lot for the code I tried it and I see 3 major issues:
3. Sometimes (but not always!?!) the destructor of the CComBSTR fires an unhandled exception when calling ::SysFreeString.
I tried to debug the first two issues with no luck. Any hint?
Ok. I wrote it, got it to work, but didn't have to use it (se explanation below).
1. The IE control has a unique function to load items from a resourcefile (the Mozilla COM-clone can't). The syntax for this is to name the URL as "res://[exactpath]/[yourapplication].exe/[yourpage].html". Check the LoadFromResource() method.
2 and 3. No idea. I probably missed something with the COM-interface like reference counters or.
Why, if I may suggest, dont you try to get rid of the page loads and scripts instead? That's the solution I'm using. One page and no scripts at all. I just rewrite the HTML-content using IHTMLElement()->SetElementHtml() all along. All events and functions are performed in C++. Works great!
And btw, I don't use the DOC/VIEW class that originally started this thread anymore. I rewrote it to use plain CWnd instead.
Another solution that have other advantages (like generating dynamic graphics) is to implement a simple HTML-server in your application. Perhaps sounds a little bit odd but it works by listening for example on 127.0.0.1:5000 and then referring all pages to load from "http://127.0.0.1:5000/[thispage].html" instead from "res://". The "server" part of the application then extracts and/or generates the data and/or graphics and returns it on the port instead. We have an application using this workaround-method so I know it works.
This is a great class. I starting messing around by adding a couple of text boxes and trying to get and set the text within them. I can set the text no problem. I am have trouble retrieving text and can't seem to find the problem. Here is my code snippet:
Nice work! Now I tried to add a spin control (I want to use it in my App). The HTML-Editor in .net adds the following code the html-file: <OBJECT id=Spinbutton1 classid=clsid:79176FB0-B7F2-11CE-97EF-00AA006D2776 VIEWASTEXT> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="BackColor" VALUE="2147483663"> <PARAM NAME="VariousPropertyBits" VALUE="27"> <PARAM NAME="Size" VALUE="265;529"> <PARAM NAME="Min" VALUE="0"> <PARAM NAME="Max" VALUE="100"> <PARAM NAME="Position" VALUE="0"> <PARAM NAME="PrevEnabled" VALUE="1"> <PARAM NAME="NextEnabled" VALUE="1"> <PARAM NAME="SmallChange" VALUE="1"> <PARAM NAME="Orientation" VALUE="4294967295"> <PARAM NAME="Delay" VALUE="50"> <PARAM NAME="MousePointer" VALUE="0"> </OBJECT>
But do I have to add to the DHTML_EVENT_MAP to catch the up or down events when clicked? I tried many things, but nothing ever worked. Any ideas?
first of all let me say this is great work. But i have problems to access a IHTMLElement after changing the displayed resource with LoadFromResource(...).
Like your second example I want to write a table inside a div-tag. It works fine if the HTML resource was loaded in OnInitialUpdate(). But if a startpage was loaded first, and the other resource is loaded with LoadFromResource() after an klick on a button, the function GetElement returns NULL.
I am converting an application that uses JScript and XML data islands in the HTML file. I can't get the following to work: var xmlJobs = new ActiveXObject("Msxml2.DOMDocument");
xmlJobs.async = false;
xmlJobs.resolveExternals = false;
xmlJobs.load("jobs.xml"); // or fully qualified path