Formular-Elemente aus einer HTML Seite extrahieren
-
Hi Alle zusammen!
Ich test gerade an klein wenig mit der CppWebBrowser Compo herum und möchte nun aus einem HTML Formular alle Formularelemente und gewisse zugehörige Werte (Editfelder, Buttons usw.) in einer Liste anzeigen lassen.
Dazu muss man ja irgendwie die IHTMLElementCollection des Formulars durchforsten. Nur habe ich leider keinen blassen Dunst wie ich das anstellen soll. pAll->item() liefert mir ja nur ein Element zurück, dessen Namen ich schon kenne. Ich will aber alle Elemente des Formulars haben und dann entsprechend in eine Liste eintragen.
Hat jemand einen Vorschlag wie ich das am Besten anstellen kann?
Mein Code bisher:
void __fastcall TForm1::CppWebBrowser1DocumentComplete(TObject *Sender, LPDISPATCH pDisp, Variant *URL) { IHTMLDocument2 *HTMLDocument = NULL; if (SUCCEEDED(CppWebBrowser1->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&HTMLDocument))) { if (HTMLDocument != NULL) { IHTMLElementCollection *pAll = NULL; if (SUCCEEDED(HTMLDocument->get_all(&pAll)) && pAll) { long iColLengh; pAll->get_length(&iColLengh); for (long i=0; i<iColLengh; i++) { TVariant vName; TVariant vIndex = 0; IDispatch *pDisp = NULL; WideString wsECName; pAll->toString(&wsECName); if (SUCCEEDED(pAll->item(vName, vIndex, &pDisp)) && pDisp) { IHTMLInputElement *pInput = NULL; // pInput bleibt NULL, da ich ja keinen Namen spezifiziert habe if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLInputElement, (LPVOID*)&pInput)) && pInput) { // String des Elementes holen WideString wsElementName; pInput->get_name(&wsElementName); } pDisp->Release(); } } pAll->Release(); } } HTMLDocument->Release(); } }
-
Wenn ich die MDSN richtig verstehe dann kannst du vName auch eienn Integer zuweisen. Damit sollte es doch eigentlich möglich sein, quasi auf Verdacht durch die Collection zu iterieren. Sobald der Aufruf fehlschlägt sollte das Ende der Collection erreicht sein.
-
Jawohl! Ich habe mir mal auf Grund Deines Tipps
das Beispiel in der MSDN angeschaut und hatte Erfolg.Der Schlüssel liegt in der Zeile
if (SUCCEEDED(pAll->item(vIndex, vIndex, &pDisp)) && pDisp)begraben. Über die einfache Angabe des Indexes kann mann schön in der Element-Liste rumiterieren. Hier mal mein Beispielcode, der alle Input-Elemente (Name, Typ, Wert) einer bel. Webseite auflistet:
void __fastcall TForm1::CppWebBrowser1DocumentComplete(TObject *Sender, LPDISPATCH pDisp, Variant *URL) { IHTMLDocument2 *HTMLDocument = NULL; // Zeiger auf das geladene Document TListItem *ListItem; lvElements->Items->Clear(); // falls eine Seite geladen if (SUCCEEDED(CppWebBrowser1->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&HTMLDocument))) { if (HTMLDocument != NULL) { IHTMLElementCollection *pAll = NULL; // Zeiger auf den Documentinhalt holen if (SUCCEEDED(HTMLDocument->get_all(&pAll)) && pAll) { // Anz. der Elemente auf der Seite holen long iColLengh; pAll->get_length(&iColLengh); // die Elementliste durchsuchen for (long i=0; i<iColLengh; i++) { TVariant vIndex = i; IDispatch *pDisp = NULL; if (SUCCEEDED(pAll->item(vIndex, vIndex, &pDisp)) && pDisp) { IHTMLInputElement *pInput = NULL; // wenn das gefundene Element ein Input-Element ist if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLInputElement, (LPVOID*)&pInput)) && pInput) { WideString wsElementName; WideString wsElementValue; WideString wsElementType; // Name, Typ, Wert holen pInput->get_name(&wsElementName); pInput->get_value(&wsElementValue); pInput->get_type(&wsElementType); // ins Listview schreiben ListItem = lvElements->Items->Add(); ListItem->Caption = wsElementName; ListItem->SubItems->Add(wsElementType); ListItem->SubItems->Add(wsElementValue); } pDisp->Release(); } } pAll->Release(); } } HTMLDocument->Release(); } }
Das wäre doch mal wieder was für die FAQ, oder? 
-
F98 schrieb:
Der Schlüssel liegt in der Zeile
if (SUCCEEDED(pAll->item(vIndex, vIndex, &pDisp)) && pDisp)begraben. Über die einfache Angabe des Indexes kann mann schön in der Element-Liste rumiterieren.
Muss der zweite Parameter denn zwingend ebenfalls inkrementiert werden?
-
Nöja, nicht unbedingt. Es geht auch, wenn man eine 2. TVariant-Variable mit 0 übergibt, aber im MSDN Beispiel wird ebenfals 2x der selben Index übergeben:
Ich denke mal, wenn vorne kein String steht, ist der 2. Parameter egal.