OVH Cloud OVH Cloud

[HTA] Affichage dynamique message (innertext)

15 réponses
Avatar
sympatix
Bonjour !

J'ai une page HTA, dans laquelle un script s'éxécute à l'ouverture.
Je voudrais afficher un message dynamique à l'aide d'innertext, durant
l'éxécution du script, mais je n'y arrive pas.
Dans l'exemple ci-dessous, le script tourne en boucle, tant que notepad (par
exemple) n'est pas lancé.
Normalement, il devrait s'afficher:

1: Prêt (pendant un temps très court, même trop court pour être vu...mais
c'est pas le problème)
2: Script lancé (tant que notepad n'est pas lancé)
3: Fin du script (dès l'ouverture de notepad)

Or, il n'en est rien, je n'ai que "prêt" pendant l'exécution du script,
puis, "Fin du script".
(je précise que j'ai essayé avec la balise "defer", bien qu'à priori, ça
n'ai aucun rapport dans mon cas ?)
Ou est l'erreur ?
merci d'avance !

------Couper ici-------
<HTML>

<div id=D1> Prêt </div> <BR>
<HTA:APPLICATION></HTA:APPLICATION>

<SCRIPT Language = VBSCRIPT>
Set oShell = CreateObject("WScript.Shell")
A = "Script lancé"
B = "Fin du script"
While not oShell.appactivate ("sans titre")
D1.innertext = A
Wend
D1.innertext = B
</SCRIPT>

</HTML>
------Couper ici-------
--
Cordialement
Sympatix
(Antispam: Ôter les "toto" dans l'adresse, pour me répondre)

5 réponses

1 2
Avatar
sympatix
ou en utilisant la méthode showModelessDialog du DOM et en bricolant avec
la routine Pause que j'avais postée ici dans le fichier


Très joli !
Bon, maintenant que j'ai tous les outils, je vais me mettre au boulot !
merci :-)

--
Cordialement
Sympatix
(Antispam: Ôter les "toto" dans l'adresse, pour me répondre)
"Jean" <http:// a écrit dans le message de news:

Bonjour,

ou en utilisant la méthode showModelessDialog du DOM et en bricolant avec
la routine Pause que j'avais postée ici dans le fichier Pause.HTA ... un
truc dans ce genre ci :

<!---8<---Jean-JMST-Belgium--->
<script defer language='vbs'>

s=""
i=0
ratio=0
vPosX=ScreenLeft
vPosY=ScreenTop

MoveTo 3000,3000
Set W=ShowModelessDialog(_
"about:<BODY><DIV IDÐ></DIV><DIV IDÑ></DIV></BODY>","",_

"dialogheight:70px;dialogwidth:200px;center:no;resizable:no;unadorned:yes"_
)
With W
.DialogLeft=vPosX
.DialogTop=vPosY
With .Document
With .Body
.Scroll="No"
With .Style
.Margin="0px"
.Padding="0px"
.BackGroundColor="Lavender"
.Border="3 ridge green"
.TextAlign="Center"
End With
End With
With .All.D0.Style
.Height="10px"
.Color="Yellow"
.BackGroundColor="Blue"
.Width="0%"
.Border="2 Solid Green"
End With
With .All.D1.Style
.FontSize="12px"
.Height="10px"
.Color="Blue"
.BackGroundColor="LemonChiffon"
.Width="100%"
.Border="2 Solid Silver"
End With
End With
End With

With CreateObject("Scripting.FileSystemObject")
Set fichiers=.GetFolder(.GetSpecialFolder(0)&"system32").Files
For Each f in fichiers
Pause 15
i=i+1
ratio=Round(i/(fichiers.Count/100))
'If i Mod 100=0 Then Pause(50)
With W.Document.All
.D0.InnerText=ratio&"%"
.D0.Style.Width=ratio&"%"
.D1.innerText=f.Name
End With
s=s&f.Name&"<br>"
Next
End With

W.Close
MoveTo vPosX,vPosY
document.body.innerHTML=s

Sub Pause(msec)
showModalDialog _
"about:<script language='vbscript'>setTimeout ""Close"","&_
msec&_
"<"&"/"&"script>"_
,"","dialogHeight:0px;dialogWidth:0px"
End Sub

</script>
<!---8<---Jean-JMST-Belgium--->

Amicalement,

Jean - JMST
Belgium

"sympatix" a écrit dans le message de news:

Bonjour !

Dans votre exemple, effectivement, tout fonctionne au poil, car la démo
se
sert d'une tempo en guise de code.
Mais, si je veux appliquer ça dans une boucle récursive (une collection
de
5000 fichiers par exemple), soit:

1: Je place un affichage de progression avec tempo à chaque passage de
boucle (pas possible avec une tempo)
2: Je cherche à placer l'affichage de progression à une fréquence moins
rapide (solution envisagée)...mais reste à trouver où ?

Je vais chercher, merci !

--
Cordialement
Sympatix
(Antispam: Ôter les "toto" dans l'adresse, pour me répondre)
"Jean" <http:// a écrit dans le message de news:
unxf%23%
Bonjour,

vous pouvez faire quelque chose comme ce qui suit (... et la charge CPU
sera *fortement* réduite comparée au 100% actuel ;-) ) :

http://automation.eu.tf/Temporisation_VBS.HTA (VBScript * voir code
ci-dessous)
http://automation.eu.tf/Temporisation_JS.HTA (JScript * voir code
ci-dessous)

La récursive de Michel est bonne aussi.
Au lieu de passer par une récursive j'utilise les méthodes setInterval
et
clearInterval du DOM.
Cette dernière peut aussi s'avérer utile pour interompre la
temporisation
à tout instant (via un bouton par ex.).

<!---8<---Temporisation_VBS.HTA---Jean-JMST-Belgium--->
<div idÑ></div>

<script defer language='vbs'>
Executer_Notepad_Apres_10_sec 'Simulation

titre="Sans titre"

c=""
Debut

Sub Debut
'....Code....
D1.InnerText="Prêt"
'Suite
SetTimeout "Suite",1000 'Simulation
End Sub

Sub Suite
D1.InnerText="En cours "
c=SetInterval("Temporisation",150)
End Sub

Sub Temporisation
If Not CreateObject("WScript.Shell")_
.AppActivate(titre) Then
D1.InnerTextÑ.InnerText&"... "
Else
Fin
End If
End Sub

Sub Fin
ClearInterval(c)
'....Code....
D1.InnerText="Terminé"
End Sub

Sub Executer_Notepad_Apres_10_sec
SetTimeout _
"CreateObject(""WScript.Shell"")"&_
".Run ""notepad.exe""",10000
End Sub
</script>
<!---8<---Temporisation_VBS.HTA---Jean-JMST-Belgium--->

<!---8<---Temporisation_JS.HTA---Jean-JMST-Belgium--->
<div idÑ></div>

<script defer>
executer_notepad_apres_10_sec() //Simulation

titre='Sans titre'

debut()

function debut(){
//....Code....
D1.innerText='Prêt'
//suite()
setTimeout('suite()',1000) //Simulation
}

function suite(){
D1.innerText='En cours '
c=setInterval('temporisation()',150)
}

function temporisation(){
if(!new ActiveXObject('WScript.Shell').
appActivate(titre)){
D1.innerText+='... '
}else{
fin()
}
}

function fin(){
clearInterval(c)
//....Code....
D1.innerText='Terminé'
}

function executer_notepad_apres_10_sec(){
setTimeout
(
'new ActiveXObject("WScript.Shell")'+
'.run("notepad.exe")'
,10000
)
}
</script>
<!---8<---Temporisation_JS.HTA---Jean-JMST-Belgium--->


Amicalement,

Jean - JMST
Belgium

"sympatix" a écrit dans le message de news:

Bonjour !

J'ai une page HTA, dans laquelle un script s'éxécute à l'ouverture.
Je voudrais afficher un message dynamique à l'aide d'innertext, durant
l'éxécution du script, mais je n'y arrive pas.
Dans l'exemple ci-dessous, le script tourne en boucle, tant que notepad
(par
exemple) n'est pas lancé.
Normalement, il devrait s'afficher:

1: Prêt (pendant un temps très court, même trop court pour être
vu...mais
c'est pas le problème)
2: Script lancé (tant que notepad n'est pas lancé)
3: Fin du script (dès l'ouverture de notepad)

Or, il n'en est rien, je n'ai que "prêt" pendant l'exécution du script,
puis, "Fin du script".
(je précise que j'ai essayé avec la balise "defer", bien qu'à priori,
ça
n'ai aucun rapport dans mon cas ?)
Ou est l'erreur ?
merci d'avance !

------Couper ici-------
<HTML>

<div idÑ> Prêt </div> <BR>
<HTA:APPLICATION></HTA:APPLICATION>

<SCRIPT Language = VBSCRIPT>
Set oShell = CreateObject("WScript.Shell")
A = "Script lancé"
B = "Fin du script"
While not oShell.appactivate ("sans titre")
D1.innertext = A
Wend
D1.innertext = B
</SCRIPT>

</HTML>
------Couper ici-------
--
Cordialement
Sympatix
(Antispam: Ôter les "toto" dans l'adresse, pour me répondre)





















Avatar
Michel Claveau
Bonsoir

L'instruction setTimeout redonne la main à L'OS, pour sa gestion
non-préemptif. Cela permet (notamment) à Windows de resynchroniser
l'affichage. CQFD.

Toutefois, ce n'est pas la seule instruction qui fait ça. Et ça pose parfois
des problèmes. Par exemple, je me souviens d'un cas, où deux évènements se
déclenchaient, pour un même objet, avec la même cause. Et bien, le
traitement du second évènement s'exécutait au milieu du traitement du
premier évènement. Dans ce cas, l'élément provoquant l'exécution était le
retour d'un CALL externe.


@-salutations

Michel Claveau
Avatar
sympatix
L'instruction setTimeout redonne la main à L'OS, pour sa gestion
non-préemptif. Cela permet (notamment) à Windows de resynchroniser
l'affichage. CQFD.
OK.

SeTimeout est une sorte de boucle à lui tout seul (ou me trompjes...), car
on ne voit nulle part dans le code de boucle genre do...loop, While...Wend
?

Merci pour ces précisions
--
Cordialement
Sympatix
(Antispam: Ôter les "toto" dans l'adresse, pour me répondre)
"Michel Claveau" a écrit dans le message de news:

Bonsoir

L'instruction setTimeout redonne la main à L'OS, pour sa gestion
non-préemptif. Cela permet (notamment) à Windows de resynchroniser
l'affichage. CQFD.

Toutefois, ce n'est pas la seule instruction qui fait ça. Et ça pose
parfois des problèmes. Par exemple, je me souviens d'un cas, où deux
évènements se déclenchaient, pour un même objet, avec la même cause. Et
bien, le traitement du second évènement s'exécutait au milieu du
traitement du premier évènement. Dans ce cas, l'élément provoquant
l'exécution était le retour d'un CALL externe.


@-salutations

Michel Claveau




Avatar
Jean
Bonjour,

Non, ce qui ressemble à une boucle c'est setInterval qui exécute un code à intervalles régulier.

Ce qui ressemble à une boucle dans le code proposé par Michel c'est qu'il s'agit d'une fonction récursive (une fonction qui
s'appelle elle même).

Le principe est donc ici de faire un test à intervalles régulier.
La récursive est d'ailleurs la "traduction" de setInterval à l'aide de setTimeout.
Les 2 codes suivants auront le même résultat :

<!---8<--->
<script defer>
setInterval('D=new Date();document.body.innerHTML=D',1000)
</script>
<!---8<--->

<!---8<--->
<script defer>
Interval('D=new Date();document.body.innerHTML=D',1000)

function Interval(code,msec){
setTimeout(code,msec)
setTimeout('Interval("'+code+'",'+msec+')',msec)
}
</script>
<!---8<--->

Le premier utilise la méthode setInterval, le second utilise une fonction récursive.

setTimeout et setInterval permettent l'exécution *asynchrone* de codes au sein d'une routine.

Les valeurs exprimées en millisecondes dans les exemples utilisants la récursive, setInterval ou la fonction Pause servent à alléger
la charge CPU engendrée par le flux généré par la boucle For ... Next.
Plus cette valeur sera *grande*, plus la charge CPU sera *faible* et plus l'exécution sera *lente*.
Il faut donc trouver un juste compromis ... laissé à l'appréciation du programmeur :-)

Pour les scripts client de Windows Script Host (vbs,js, ..) c'est la méthode Sleep de l'objet WScript qui est utilisée dans ce cas
de figure.

Amicalement,

Jean - JMST
Belgium

"sympatix" a écrit dans le message de news:
L'instruction setTimeout redonne la main à L'OS, pour sa gestion
non-préemptif. Cela permet (notamment) à Windows de resynchroniser
l'affichage. CQFD.
OK.

SeTimeout est une sorte de boucle à lui tout seul (ou me trompjes...), car
on ne voit nulle part dans le code de boucle genre do...loop, While...Wend
?

Merci pour ces précisions
--
Cordialement
Sympatix
(Antispam: Ôter les "toto" dans l'adresse, pour me répondre)
"Michel Claveau" a écrit dans le message de news:

Bonsoir

L'instruction setTimeout redonne la main à L'OS, pour sa gestion
non-préemptif. Cela permet (notamment) à Windows de resynchroniser
l'affichage. CQFD.

Toutefois, ce n'est pas la seule instruction qui fait ça. Et ça pose
parfois des problèmes. Par exemple, je me souviens d'un cas, où deux
évènements se déclenchaient, pour un même objet, avec la même cause. Et
bien, le traitement du second évènement s'exécutait au milieu du
traitement du premier évènement. Dans ce cas, l'élément provoquant
l'exécution était le retour d'un CALL externe.


@-salutations

Michel Claveau









Avatar
sympatix
Non, ce qui ressemble à une boucle c'est setInterval qui exécute un code à
intervalles régulier.


Ah ...

Ce qui ressemble à une boucle dans le code proposé par Michel c'est qu'il
s'agit d'une fonction récursive (une fonction qui
s'appelle elle même).


Ah oui, là je comprend un peu mieux, c'est vrai que ça ne m'a pas sauté aux
yeux, l'astuce de l'appel d'une fonction par elle-même. (En plus, j'ai déjà
utilisé cette méthode d'appel récursif dans le parcours de collections de
dossiers/fichiers)

Le principe est donc ici de faire un test à intervalles régulier.
La récursive est d'ailleurs la "traduction" de setInterval à l'aide de
setTimeout.
Les 2 codes suivants auront le même résultat :
.../...
Le premier utilise la méthode setInterval, le second utilise une fonction
récursive.
setTimeout et setInterval permettent l'exécution *asynchrone* de codes au
sein d'une routine.


La comparaison des 2 codes est interressante, effectivement.
Pour info, "setTimeout", c'est du Jscript ...ou du DOM ? (je mélange encore
les 2 !)
En cherchant dan ma bible (SCRIPT56.CHM), je n'ai rien trouvé.
j'en déduit que c'est soit du Jscript, et ma bible n'est plus à jour, soit
du DOM.

Les valeurs exprimées en millisecondes dans les exemples utilisants la
récursive, setInterval ou la fonction Pause servent à alléger
la charge CPU engendrée par le flux généré par la boucle For ... Next.
Plus cette valeur sera *grande*, plus la charge CPU sera *faible* et plus
l'exécution sera *lente*.
Il faut donc trouver un juste compromis ... laissé à l'appréciation du
programmeur :-)


OK

Pour les scripts client de Windows Script Host (vbs,js, ..) c'est la
méthode Sleep de l'objet WScript qui est utilisée dans ce cas
de figure.


C'est vrai qu'il est bien pratique, ce Wscript.sleep, quand on l'a pas, il
nous manque ;-) !
Merci encore pour toutes ces infos :-)

--
Cordialement
Sympatix
(Antispam: Ôter les "toto" dans l'adresse, pour me répondre)
"Jean" <http:// a écrit dans le message de news:
e$

1 2