114. Die Lehre vom Wechsel von HTML-Seiten in Frames mit VBS (HTA nur Internetexplorer)

Einleitung

Der Sternenhimmelstuermer schrieb bereits ein Kompendium über HTA. Dieses wurde selbstverständlich mit dieser Abhandlung ergänzt. Hier geht es primär um die Zusammenarbeit zwischen Batch und VBS mit der grafischen Oberfläche (GUI) Hta!
Als Nebenprodukt werden folgende Fragen beantwortet:

1. Wie legt man ein Frameset in einer HTA an?
2. Wie startet man eine Batch aus einer HTA mit VBS und bringt das Skript zum warten auf das Ergebnis der Batch?
3. Wie bringt man in eine HTA in einen Frame eine neue HTML Seite?

Inhaltsangabe
vereinfachte Lösungsschema in Tabelle Quick und dirty
Einführung
Code der drei Skripte
Erklärung Schritt für Schritt
Fazit

vereinfachte Lösungsschema in Tabelle Quick und dirty


Für Menschen, die eine kurze und schnelle Lösung für einen einfachen Framewechsel mit VBS haben wollen, fertigte der Sternenhimmelstuermer folgende Lösungstabelle nur mit dem wesentlichen Code für ein Frameset und Wechsel eies Frames mit HTA und VBS:

Datei mit Frameset: frames.hta
Frame 1: frame_1.htm
Frame 2: frame_2.htm
 Framewechsel: frame_wechsel.htm
<head>
<title>HTA Hilfe für Batchschreiber</title>
<HTA:APPLICATION
        APPLICATIONNAME="HTAHilfe"
    SCROLL="yes"
    SINGLEINSTANCE="yes"
    WINDOWSTATE="maximize"
>
</head>
<frameset rows="50%,50%">
 <frame application="yes"
src="frame_1.htm">
 <frame application="no" src="frame_2.htm" name="frame_2">
</frameset>
<html>
<head>
<title>HTA Hilfe für Batchschreiber</title>
<HTA:APPLICATION
        APPLICATIONNAME="HTAHilfe"
    SCROLL="yes"
    SINGLEINSTANCE="yes"
    WINDOWSTATE="maximize"
>
</head>
<SCRIPT Language="VBScript">
Sub RunScript
    WINDOW.PARENT.FRAME_2.LOCATION.HREF="frame_wechsel.htm"
End Sub
</SCRIPT>
<body>
<div>Der Framewechsel erfolgt nach Betätigung des Buttons</div>
<br>
<input id=runbutton  class="button" type="button" value="start" name="run_button"  onClick="RunScript">
<br>
<br>
<body>
<html>
<htm>
<BODY>
<div>Das ist ein ursprünglicher Frame<div>
</BODY>
</htm>
<html>
<BODY>
<div>Das ist ein Frame nach einem Framwechsel...</div>
</BODY>
</html>
Alle Dateien in einen Ordner (relative Links).
Mit einem Doppelklick auf die Frame.hta wird die Anwendung gestartet.


Die ausführenden VBScripts müssen in den anderen HTM-Frames sein, da nur das Frameset in Frame.hta   ausgelesen wird und andere Befehle ignoriert werden.

Es können keine HTA-Dateien mit der  Frame.hta in einen Frame geladen werden - es sei denn die hta soll wiederum als einzelne Instanz geöffnet werden-:)

Die beiden Frames frame_1.htm und frame_2.htm werden geladen.
Im ersten Frame_1 ist die Hauptanwendung, nämlich ein Start-Button, der den Framewechsel auslöst.

Unter dem Headbereich von frame_1.htm  ist die Ausführungsroutine im VBS:.

WINDOW.PARENT.FRAME_2.LOCATION.HREF="frame_wechsel.htm"

Das ist der Pfad zur Framewechselseite ind eigenständiger Befehl zu gleich. Windows.Parent ist die Adresse zum Hauptframe und Frame_2 die ID vom Frame  Location.Href ist halt die Url, die im Window angezeigt wird...

Das Sub RunScript wird durch Betätigen des Buttons im Bodybereich durch den User ausgelöst:

<input id=runbutton  class="button" type="button" value="start" name="run_button"  onClick="RunScript">
Dieser Frame wurde ursprünglich angezeigt..

Ist eine ganz normale HTM-Seite...
...und durch diesen Frame nach Betätigen des Buttons ersetzt.


Ist eine ganz normale HTM-Seite...
Rows und cols: Das ist die Angabe, ob es zwei Frames übereinander (row) oder nebeneinander (cols) gibt. Der Sternenhimmelstuermer schlägt eine Angabe in Prozent danach vor, damit sich die Fenster im Browser anpassen.

Tipp: Natürlich können Sie auch mit einem Betätigen des Buttons zwei Frames ändern: Einfach dem zweiten Frame einen Namen geben in frames.hta - in der Art: src="frame_1.htm" name="frame_1">
Dann noch in frame_1.htm eine Zeile in der Art:  WINDOW.PARENT.FRAME_1.LOCATION.HREF="frame_wechsel.htm" hinzufügen. Warum geht das? Im VBS Script werden die einzelnen Befehle
innerhalb des Sub Runscripts abgearbeitet - ob da nun ein Frame gewechselt wird oder zwei ist so ziemlich egal - Sie könnten auch eine Zeitschleife einbauen und das Ergebnis für zehn Sekunden anzeigen
lassen, um dann wieder zum alten Frame zurückzukehren...VBS ist echt flexibel, wenn man die Grundkenntnisse hat...
Genausogut können Sie einen Frame mit derselben Adresse einfach neu laden - so eine Art Reload-Funktion. Das kann nützlich sein, um einen Clear-Button einzubauen, der die Eingaben des Users in einem Formular löscht...


Und immer daran denken: VBS geht nur im Internet Explorer: Die Sprache für die Internet-Applikationen ist für alle Browser Javascript...

Einführung


Die Einführung bezieht sich nicht auf die o. a. Quick und Dirty-Tabelle, sondern um die folgende Anwendung, mit der Sie eine Usereingabe in ein Textfeld in einen leeren Frame bringen - mit dem kleinen Umweg über ein erstelltes Textdokument des VB-Scriptes, dass von einer Batch in ein Framedokument konvertiert wird und als solches von der HTA geladen wird !

Wozu? Es geht um die Ausgabe von Ergebnissen von Batches in einem Frame einer HTA...

Sie bauen sich drei Dateien, die nach der Einführung im Quellcode vorliegen. Die können Sie in einem beliebigen Ordner platzieren. Danach starten Sie die Frame.hta mit einem Doppelklick. Die startet eine HTA mit zwei Frames. Der erste Frames wird mit der Cassandra.htm geladen (oberer Frame).

Der zweite Frame wird mit about:blank geladen, also eine leere imaginäre weiße Seite - Da könnte natürlich auch ein Link zu einer HTML-Seite drin sein...

In der Cassandra.html ist unserer HTA-Code. Die Rechte für die Ausführung bekommen wir aus der Frame.hta <frame application="yes" . Hm, der Sternenhimmelstuermer schreibt trotzdem den hta-Kopf noch einmal in die Html-Seite - kann nicht wirklich schaden...

Wie dem auch sei, nun hat Cassandra.htm volle Rechte. Sie wartet nun auf eine Eingabe des Users (<div><input type="text" name="BasicTextBox" size="100"></div>)  und nach Eingabe des Users ins Textfeld und Betätigung des Run-Buttons (<input id=runbutton  class="button" type="button" value="Suche" name="run_button"  onClick="RunScript">)   wird das VBSkript aktiv und ein Textdokument mit der Eingabe des Users wird generiert.

Dann wird die probe.bat gestartet und so lange gewartet, bis sich die Batch schließt (shell.run """probe.bat""", 1, true)  .

Die Batch erstellt nun  rein zufällig eine HTM-Seite mit dem Namen New.htm, in der der Eingabetext vom User aus der HTA steht,  und schließt sich.

Darauf hat unsere Cassandra.htm nur gewartet. Denn nun wird Sie wieder aktiv und lädt die New.htm (WINDOW.PARENT.FRAME2.LOCATION.HREF="NEW.HTM") als neue Seite in den leeren Frame ( <frame application="no" src="about:blank" ) name="frame2">  - der User liest im neuen Frame also das, was er gerade eingab.

Für Profis ist bereits an dieser Stelle die Abhandlung beendet.

Code der drei Dateien

Frame.hta (Der Name ist nicht wirklich interessant, aber die Endung ist  *.hta)

<head>
<title>HTA Hilfe für Batchschreiber</title>
<HTA:APPLICATION
        APPLICATIONNAME="HTAHilfe"
    SCROLL="yes"
    SINGLEINSTANCE="yes"
    WINDOWSTATE="maximize"
>
</head>
<frameset rows="50%,50%">
 <frame application="yes"
src="cassandra.htm">
 <frame application="no" src="about:blank" name="frame2">
</frameset>


----


cassandra.htm (Der Name ist Pflicht...)

<html>
<head>
<title>HTA Hilfe für Batchschreiber</title>
<HTA:APPLICATION
        APPLICATIONNAME="HTAHilfe"
    SCROLL="yes"
    SINGLEINSTANCE="yes"
    WINDOWSTATE="maximize"
>
<style type="text/css">
a {color:#FFFF33; font-size:10pt; font-family:verdana,sans-serif,tahoma; text-decoration:none}
a:hover {color:#FF0000; font-size:10pt; font-family:verdana,sans-serif,tahoma; text-decoration:none}
a.menu1 {color:#FFFFFF; font-family:verdana,sans-serif,tahoma; font-size:8pt; text-decoration:none}
a.menu1:hover {color:#FF0000; font-family:verdana,sans-serif,tahoma; font-size:8pt; text-decoration:none}
a.menu2 {color:#FFFFFF; font-family:verdana,sans-serif,tahoma; font-size:9pt; text-decoration:none}
a.menu2:hover {color:#FF0000; font-family:verdana,sans-serif,tahoma; font-size:9pt; text-decoration:none}
</style>
</head>
<SCRIPT Language="VBScript">
Sub RunScript
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    objFSO.CreateTextFile("suchwort.log")
    Set objFile = objFSO.OpenTextFile("suchwort.log", 2)
    objFile.WriteLine  BasicTextBox.Value
objFile.Close
dim shell
set shell = createobject("wscript.shell")
shell.run """probe.bat""", 1, true
WINDOW.PARENT.FRAME2.LOCATION.HREF="NEW.HTM"
End Sub
</SCRIPT>
<body style="color: white; background-color: black;" alink="red"
link="yellow" vlink="#3333ff">
<br>
<br>
<br>
<center><div><big><big><big><span style="color: red;">&#x8CEC; cassandra &#x8CEC;</span></big></big></big></div><c/enter>
<br>
<br>
<div><input type="text" name="BasicTextBox" size="100"></div>
<br>
<div>Der Eingabetext wird in dem leeren Frame nach Betätigen des Buttons angezeigt</div>
<br>
<input id=runbutton  class="button" type="button" value="start" name="run_button"  onClick="RunScript">
<br>
<br>
<body>
<html>

----

probe.bat

set destination=%~dp0%
>"%destination%New.htm"  ECHO ^<html^>
>>"%destination%New.htm" ECHO ^<BODY^>
set /p ergebnis=<suchwort.log
>>"%destination%New.htm" ECHO %ergebnis%
>>"%destination%New.htm" ECHO ^</BODY^>
>>"%destination%New.htm" ECHO ^</html^>
del suchwort.log  



Erklärung

Wir gehen chronologisch vor. Sie starten die frame.hta. Zur Erinnerung den ganzen Code

<head>
<title>HTA Hilfe für Batchschreiber</title>
<HTA:APPLICATION
        APPLICATIONNAME="HTAHilfe"
    SCROLL="yes"
    SINGLEINSTANCE="yes"
    WINDOWSTATE="maximize"
>
</head>
<frameset rows="50%,50%">
 <frame application="yes"
src="cassandra.htm">
 <frame application="no" src="about:blank" name="frame2">
</frameset>

Der blaue Teil ist der Kopf der HTA - da verweist der Sternenhimmelstuermer auf sein Kompendium über hta.

<frameset rows="50%,50%">


Wir eröffnen im Container - also unsere hta ein Frameset mit der Verteilung 50%  zu 50 %. Die folgenden Frames sind oben und unten (row, für nebeneinander cols). Schauen Sie sich eine Dokumentation von Frameset an. Die Ausnahme zum herkömmlichen Frame ist <frame application="yes" .
Hier bestimmen Sie, ob im Frame Applikationen ausgeführt werden können. Damit ist in der Regel VBS gemeint. Für den oberen Frame  src="cassandra.htm"> ist also VBS zugelassen.

Anders im unteren Frame <frame application="no" src="about:blank" name="frame2">. Hier ist kein VBS nötig: also ein klares nein bzw. no...

Der Name des Frames ist die eindeutige ID und deshalb wichtig. Als Verlegenheitslösung nehmen wir eine leere unbeschriebene Seite als URL (internetadresse: about:blank). Damit brauchen wir nicht noch eine Datei zu erstellen.

Als nächstes werden die beiden Frames beim Starten mit Leben erfüllt. Interessant ist unsere Eingabeseite cassandra.htm.

<html>
<head>
<title>HTA Hilfe für Batchschreiber</title>
<HTA:APPLICATION
        APPLICATIONNAME="HTAHilfe"
    SCROLL="yes"
    SINGLEINSTANCE="yes"
    WINDOWSTATE="maximize"
>
<style type="text/css">
a {color:#FFFF33; font-size:10pt; font-family:verdana,sans-serif,tahoma; text-decoration:none}
a:hover {color:#FF0000; font-size:10pt; font-family:verdana,sans-serif,tahoma; text-decoration:none}
a.menu1 {color:#FFFFFF; font-family:verdana,sans-serif,tahoma; font-size:8pt; text-decoration:none}
a.menu1:hover {color:#FF0000; font-family:verdana,sans-serif,tahoma; font-size:8pt; text-decoration:none}
a.menu2 {color:#FFFFFF; font-family:verdana,sans-serif,tahoma; font-size:9pt; text-decoration:none}
a.menu2:hover {color:#FF0000; font-family:verdana,sans-serif,tahoma; font-size:9pt; text-decoration:none}
</style>
</head>
<SCRIPT Language="VBScript">
Sub RunScript
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    objFSO.CreateTextFile("suchwort.log")
    Set objFile = objFSO.OpenTextFile("suchwort.log", 2)
    objFile.WriteLine  BasicTextBox.Value
objFile.Close
dim shell
set shell = createobject("wscript.shell")
shell.run """probe.bat""", 1, true
WINDOW.PARENT.FRAME2.LOCATION.HREF="NEW.HTM"
End Sub
</SCRIPT>
<body style="color: white; background-color: black;" alink="red"
link="yellow" vlink="#3333ff">
<br>
<br>
<br>
<center><div><big><big><big><span style="color: red;">&#x8CEC; cassandra &#x8CEC;</span></big></big></big></div><c/enter>
<br>
<br>
<div><input type="text" name="BasicTextBox" size="100"></div>
<br>
<div>Der Eingabetext wird in dem leeren Frame nach Betätigen des Buttons angezeigt</div>
<br>
<input id=runbutton  class="button" type="button" value="start" name="run_button"  onClick="RunScript">
<br>
<br>
<body>
<html>

Der blaue Text ist nur Formatierung bzw. der Kopf der HTML-Seite, in der der Sternenhimmelstuermer den Kopf einer HTA und ein VBS integrierte.

Wir fangen mal mit dem Body-Tag an, in dem die Eingabezeile für den User ( <div><input type="text" name="BasicTextBox" size="100"></div> ) steht.

Ist eine einzeilige Eingabezeile. Der ID-Name name="BasicTextBox"  ist wichtig. Unter diesem Namen läuft in Zukunft unsere Zeileneingabe im VBS.

Dann haben wir noch einen Button zum Start des VBScript (  <input id=runbutton  class="button" type="button" value="start" name="run_button"  onClick="RunScript">)

Der value="start" ist die Aufschrift des Buttons. Bei Betätigung des Buttons startet ein VBScript mit dem Namen RunScript  ( onClick="RunScript" ).

Zwischen Body und Head steht das Script, dass durch den Einleitungssatz ( <SCRIPT Language="VBScript"> ) geöffnet wird.

<SCRIPT Language="VBScript">
Sub RunScript
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    objFSO.CreateTextFile("suchwort.log")
    Set objFile = objFSO.OpenTextFile("suchwort.log", 2)
    objFile.WriteLine  BasicTextBox.Value
objFile.Close

Das Skript reagiert auf Betätigung des Buttons mit der Routine ( Sub RunScript).

Sub
ist fester Bestandteil und RunScript der kreativ erfundene Teil.

Dann wird ein Container ( Set objFSO = CreateObject("Scripting.FileSystemObject") ) erstellt, in dem ein Dokument Namens suchwort.log (objFSO.CreateTextFile("suchwort.log")) erstellt wird.

Das wird dann geöffnet und destruktiv (2) überschrieben ( Set objFile = objFSO.OpenTextFile("suchwort.log", 2) ). In das Textdokument wird der Wert des Eingabefeldes geschrieben ( objFile.WriteLine  BasicTextBox.Value).

BasicTextBox
ist ja unsere eindeutige ID des Eingabefeldes deren Eingabewert ( .Value ) hineingeschrieben wird. Danach wird die Bearbeitung beendet und das Dokument geschlossen ( objFile.Close ).

Danach wird  eine Variable  deklariert ( dim shell). Es wird der Container für eine Batchanwendung geschaffen ( set shell = createobject("wscript.shell") ) und in diesem Container die probe.bat gestartet ( shell.run """probe.bat""", 1, true ).

Für diese Zeile ein wenig mehr Erklärung. Die 1 und true stehen für einen Wartebefehl , bis die Anwenung ausgeführt wurde. Im eben genannten Links steht die Erklärung für den Wert 1 mit true. Für uns egal...das VBS wartet bis zum Ende
der Ausführung der Batch.

Der Sternenhimmelstuermer wandelt auf dem Pfad der Usereingabe - deshalb schauen wir uns nun zwischenzeitlich die Batch an:

probe.bat

set destination=%~dp0%
>"%destination%New.htm"  ECHO ^<html^>
>>"%destination%New.htm" ECHO ^<BODY^>
set /p ergebnis=<suchwort.log
>>"%destination%New.htm" ECHO ^<div^>%ergebnis%^</div^>
>>"%destination%New.htm" ECHO ^</BODY^>
>>"%destination%New.htm" ECHO ^</html^>
del suchwort.log 

Die  liegt im selben Ordner wie die übrigen Dateien? Dann wird Sie nun gestartet!

Erstmal bestimmt die Batch ihre Lage und schreibt den Ordnerpfad in die Variable destination.
set destination=%~dp0%

In diesem Pfad (der muss absolut sein) wird ein New.htm geschrieben.

Erste Zeile > destruktiv, weitere Zeilen ergänzend >> (>>"%destination%New.htm" ECHO ^<BODY^>)

Mit dem Echo-Befehl wird Zeile für Zeile geschrieben. Was hinter Echo steht, ist Text für New.htm.

Na ja, es gibt noch eine kleine Besonderheit: in der htm-Sprache steht fast alles in <Tags> . Und gerade die blöden Dinger sind Eingabe < oder Ausgabezeichen > für Batches.

Deshalb muss immer davor ein ^< Escapezeichen stehen.

Das ist ein schöner Übergang zur nächsten Zeile set /p ergebnis=<suchwort.log. Die platzierte der Sternenhimmelstuermer vorsichtshalber ein paar Zeilen tiefer, damit auf jedem Fall ein suchwort.log von der HTA vorliegt (vassandra.htm).

Eine Batch oder die Kommandozeile sind fähig die erste Zeile eines Dokumentes  als Variable zu deklarieren  =<suchwort.log Die heißt jetzt %ergebnis%.

In der nächsten Zeile wird die Variable %ergebnis% (in Batch mit zwei Prozentzeichen) nun im Echo-Befehl verbraten, also der Eingabetext in das Dokument geschrieben >>"%destination%New.htm" ECHO ^<div^>%ergebnis%^</div^>.
Dann wird noch schnell das Dokument beendet. Das ist jetzt ein mieses HTML-Gerüst, da der Headbereich fehlt, aber als Demo...

Zu guter letzt wird der suchwort.log vernichtet. Die Usereingabe wurde ja bereits ins HTML-Dokument übernommen.

Wenn Sie mal testen wollen, ob die HTA wirklich auf die Batch wartet, dann fügen Sie unten den Befehl pause (nur das Wort in die letzte Zeile) hinzu.

Warum? Weil dann die Batch stehen bleibt, bzw. die cmd geöffnet stehen bleibt. Durch ein Enter mit der Returntaste oder Schließen des Fensters der CMD wird die Batch beendet und erst dann der neue Frame geladen. Das VBScript wartet eben auch Jahre, wenn es sein muss -:)

Wir haben nun das letzte Dokument für den Frame und kommen nun zu dem Teil, auf den 80 % der Leser dieser Abhandlung gewartet haben.

Der Code in der HTA wird nämlich nach Schließen der Batch wieder aktiv...

Der Befehl zum Öffnen eines neuen Frames wird mit einer belanglosen Zeile geöffnet: WINDOW.PARENT.FRAME2.LOCATION.HREF="NEW.HTM".

Ähem, muss der Sternenhimmelstuermer eigentlich noch ein Wort dazu sagen? Ist nur die Ortsangebe zum Hauptfenster WINDOW.PARENT, Unterabteilung ID des Frames  FRAME2 und dann die URL HREF="NEW.HTM".

Diese Zeile scheint so schwer zu sein, dass der Sternenhimmelstuermer erst im Jahr 2012 hunderten von Anfragern in Foren mal die Lösung präsentiert, die keine vernünftigen Antworten erhalten.

Wie dem auch sei, die New.htm wird geöffnet und mit dem festen Befehlssatz End Sub die Subroutine der Befehlskette nach dem Betätigen des Startbuttons beendet. Das VBScript muss natürlich geschlossen werden </SCRIPT>.

Fazit

Cassandra ist eigentlich der Suchname für eine Suchmaschine des Sternenhimmelstuermers, die mit 18 KB noch unschuldig mit einer veralteten Technik ohne Frames läuft. Das passte noch nicht didaktisch ins Konzept, da mit dieser
Abhandlung Frames und Implementierung von Ergebnissen von Batches erklärt wurden. Die HTA-Abhandlung wird nun mit der Übergabe von Ergebnissen aus einer Batch in eine HTA abgeschlossen - ein Versprechen, dass sich aus
einer Umfrage auf dieser Seite gab und nun verspätet eingelöst wurde. Damit ist das Thema HTA eine GUI für Ihre Batch abgeschlossen...







Haftungsausschluss - Das verwenden von Tipps oder Software auf dieser Seite auf eigene Gefahr.


Impressum
Datenschutz