VB6 - Internet Explorer Control

Sprache:
VB6

Typ:
Beispiel

Stand:
Feb.2003, abgeschlossen

Stichworte:
VB6, Internet Explorer Control, DHTML, Javascript, "DHTML Editing component"
 
 
 
Einleitung

Das Internet Explorer Control kann in VB (natürlich auch in C++, Delphi,...) zu weit mehr benutzt werden, als wie man auf den ersten Blick denkt. Mit ihm lassen sich komplexe grafische Ausgaben und sogar ganze Anwendungen mit HTML Oberflächen erzeugen. Hierbei hatte ich jedoch einige Probleme, die ich an dieser Stelle kurz beschreibe.

Beispiele

Batchping
Ein Programm, welches fast ausschließlich aus HTML Oberflächen besteht. Diese lassen sich dabei über Templates steuern, so dass die Oberfläche individuell konfigurierbar ist.




Übersicht Raumplanung
Eine Raumbelegungsübersicht die aus einem IE Control besteht, dass mit Datenbankinhalten gefüllt wird. Man kann auf Wochen/Monats und Jahresebene zoomen, die angezeigten Räume festlegen, die Farben wechseln, uvm. Durch einen Klick auf die HTML Tabelle kann zu dem Raum/Termin eine neue Belegung eingegeben werden.




Tagebuch Control
Ein einfaches Control, dass ähnlich einem Listview im Report Modus funktioniert, aber aufgrund der HTML Oberfläche erheblich mehr Formatierungsmöglichkeiten bietet.




Tips

Link Ereignisse delegieren

Das erste Problem besteht darin in VB auf die Ereignisse aus dem IE zu reagieren. Dazu kann man folgenden Trick verwenden: Innerhalb des HTML Quelltextes definiert man Links mit einem pseudo Protokoll wie zB. "VB://": <input type=button value="Test" class="btnBottom" onClick="javascript:window.location.href='VB://CEvent.Test(-1)'"> In VB kann man dann diese Links im BeforeNavigate2 Ereignis abfangen, selber weiterverarbeiten und das ursprüngliche Ereignis unterdrücken (Cancel = True): Private Sub ie_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, FLAGS As Variant, _ TargetFrameName As Variant, PostData As Variant, Headers _ As Variant, Cancel As Boolean) on error goto errSub: If UCase(Left(URL, 5)) = "VB://" Then Dim exec As String, va1 As String Cancel = True If InStr(URL, "(") > 0 And InStr(URL, ")") > 0 Then exec = UCase(Mid(URL, 6, InStr(URL, "(") - 6)) va1 = UnQuote(Mid(URL, InStr(URL, "(") + 1, InStrRev(URL, ")") - InStr(URL, "(") - 1)) End If Select Case exec Case "CTERMIN.ADD": ... Case "CTERMIN.EDIT": ... Case "CTERMIN.DELETE": ... Case "CEVENT.POPUPMENU": ... Case "CEVENT.TEST": Msgbox "Test" Case Else ... End Select End If Exit Sub errSub: Cancel = True ' ... evt.ErrorHandler Err, Me, "BeforeNavigate", False End Sub

Zugriff auf Elemente

Nun stellt sich die Frage, wie man aus VB heraus auf das DOM der HTML Seite zugreifen kann. Hier einige Beispiele: 1.) Wert einer Textbox ----------------------- HTML: <INPUT maxLength=20 name=txt1 style="WIDTH: 300px" value=""> VB: ie.Document.All("txt1").Value = "Hallo" 2.) InnerHTML von einem Element -------------------------------- HTML: <div id="Bereich1" style="visibility:visible;">Guten Tag</div> VB: ie.Document.body.All("Bereich1").innerHTML = "Guten Abend" 3.) Style von einem Element ---------------------------- HTML: <div id="Termin1" style="background-color:#FFFFC0;"> ... </div> VB: ie.Document.body.All("Termin1").Style.backgroundcolor = "#000000" 4.) Eingebettetes Javascript ----------------------------- HTML/Javascript: <script language="JavaScript"> <!-- var noHoverEx=true; //--> </script> VB: ie.Document.parentWindow.execScript code:="noHoverEx=false" 5.) Alle Elemete durchlaufen ------------------------------ VB: For Each Element In web.Document.All.Tags("div") Element.innerHTML = strValue Next Element Standard Ereignisse des IE unterdrücken oder überschreiben

Bei eigenen Anwendungen ist das Standardverhalten des Browsers oft störend. Es ist leider nicht möglich das Popupmenü oder die Steuerung via Tastatur in den Controleigenschaften abzuschalten. Abhilfe schafft ein Javascript, welches die Ereignisse abfängt bzw. weiterdelegiert. Beispiel: <script language="JavaScript" type="text/javascript"> function nocontextmenu() { // Popup Event delegieren try { window.location.href='VB://CEVENT.POPUPMENU()'; event.cancelBubble = true, event.returnValue = false; return false; } catch (exception) {} } function cancelEvent() { try { event.keyCode=0; event.cancelBubble = true, event.returnValue = false; return false; } catch (exception) {} } document.oncontextmenu = nocontextmenu; document.onselectstart = cancelEvent; document.onkeydown = cancelEvent; document.onkeypress = cancelEvent; </script> Partielle Aktualisierung vs. Reload

Ein komplexes Layout mit Tabellen oder Layern braucht beim Laden idR. viel Zeit. Oft ist hier ein Tuning möglich indem nur die geänderten Bereiche und nicht die gesamte Seite aktualisiert werden. Hierzu ein Beispiel. Im Raumplanungscontrol (siehe oben) kann der Benutzer neue Termine eingeben, die dann in der HTML Tabelle dargestellt werden. Bei der Neuanlage ist es jedoch nicht notwendig das gesammmte Layout neu zu zeichnen sondern es genügt nur die Termin Layer zu aktualisieren: If doAreaRefresh Then ' <- Nur Layer aktualisieren ie.Document.body.All("Bereich1").innerHTML = ... ' [HTML, neue Layer] Else ' <- Alles aktualisieren, dh. neu laden ie.Navigate ... End If <div id="Bereich1" style="visibility:visible;"> <div id="Termin1" style="position:absolute; left:309; ... </div> <div id="Termin2" style="position:absolute; left:352; ... </div> <div id="Termin3" style="position:absolute; left:387; ... </div> <div id="Termin4" style="position:absolute; left:308; ... </div> </div> Scrollposition

Nach einer Änderung der Seite verliert der IE seine letzte Scrollposition. Durch das Speichern dieser vor und Wiederherstellen nach dem Laden kann dieses Problem umgangen werden. Auslesen: sPos = ie.Document.body.scrollTop Setzen : ie.Document.body.scrollTop = sPos Ausführen von Browserbefehlen, zB. Druckvorschau

Die Methode ExecWB erlaubt das Absetzen von Browserbefehlen die z.B. normalerweise über die Menüs des IE verfügbar sind. Eine Referenz der umfangreichen Möglichkeiten findet man im MSDN. Das folgende Beispiel zeigt den Aufruf der Druckvorschau. ie.ExecWB OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT, 0, 0 "DHTML Editing component"

Innerhalb des Internet Explorer ist die "DHTML Editing component" enthalten mit der sich Internetseiten direkt bearbeiten lassen. Diese Komponente läßt sich als HTML Editor, aber auch als ganz allgemeiner Texteditor verwenden. Hiermit kann zB. eine Pagedesigner in einer VB Anwendung realisert werden. Beispiel:



Eine Einführung in diese Komponente würde an dieser Stelle zu weit führen und es wird auf die Beispiele im MSDN verwiesen.

Anmerkung

Auch wenn sich die Möglichkeiten des IE Controls auf den ersten Blick scheinbar unbegrenzt sind, so gibt es doch in der Praxis erhebliche Einschränkungen.
  • Ein Internet Explorer muss installiert sein und je nach verwendetem DHTML/Javascript auch noch eine bestimmte Version
  • Es wird sehr viel Arbeitsspeicher benötigt
  • Die Geschwindigkeit ist je nach Komplexität des Layouts gering
  • Nach ~9000 Layern war bei mir, unabhängig vom Arbeitsspeicher bzw. CPU, das Limit das IE überschritten ;)
  • Einige Fehler, insbesondere in ungewöhnlichen Umgebungen (*), lassen sich kaum nachvollziehen
  • Die Hoffnung, dass sich die HTML Oberflächen schneller/einfacher als die VB Oberflächen erstellen lassen, hat sich bei mir nicht erfüllt.
*) Die Anwendung "Batchping" läuft zB. nur dann über "VNC", wenn der Hover Effekt für die Tabellenzeilen deaktiviert ist.



Impressum
 


Copyright 2002,2003 M. Schmitz