ask:
Hello, script expert! How to pause scripts in HTA?
-- TJ
answer:
Hello, TJ. You know, from ancient times to the present, people have spent a lot of time and energy to explore the meaning of life. The script experts never participated. Why? Well, let’s not talk about laziness for now, we know that doesn’t matter: even if you do find the meaning of life, no one cares about it. No one wants to know the reason for our existence; instead, they - like you - just want to know how exactly can we pause a script embedded in the HTML application (HTA). That is the career that script experts devote themselves to.
Now, if you are not familiar with HTA, the first thing you think of may be "use" is "just use". (By the way, if you are not familiar with HTA, you can browse HTA Developers Center (English).) This is a good idea, but it cannot be achieved. Why? Because the Wscript object is a slightly unique object; one of the reasons is that you cannot actually create an instance of this object. And as long as you run under Windows Script Host, Wscript will automatically provide you with it. The problem is here: When you run the code inside the HTA, you are not running under Windows Script Host. You are actually running under the script host provided by Internet Explorer. Because you are not running under Windows Script Host, you cannot access the Wscript object automatically, and because you cannot create your own Wscript object, you cannot access it. In high-tech technical terms, it is "paralyzed".
If Internet Explorer provides a similar method, this is not a big deal; unfortunately, it does not provide it. So is there some magical solution that we can use instead of the Sleep method? Is this necessary to ask?
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Our HTA is very simple: it consists of only one button, and when clicked, a subroutine called Test will be run. Very amazing, right? Well, let's take a look at the <SCRIPT> part of HTA first, and then determine if it's really amazing.
The first thing we do in the <SCRIPT> section is to declare a global variable called dtmStartTime:
Dim dtmStartTime
This actually has no effect on pausing scripts; we just use this variable to help us see if the script is indeed pausing as expected. If you don't understand its meaning yet, don't worry: it will be clear soon.
Next is the Test subroutine, which is called when we click the button:
Sub Test
dtmStartTime = Now
idTimer = ("PausedSection", 5000, "VBScript")
End Sub
Note that there are only two lines of code in this subroutine. In the first line, we just assign the current time and date (using the Now function) to the variable dtmStartTime. Next is the following line of code:
idTimer = ("PausedSection", 5000, "VBScript")
Believe it or not, this is how we implement the Sleep method function. We used the setTimeout method to create a timer with the ID of idTimer. As you can see, we pass three parameters to setTimeout:
? PausedSection. This parameter is the name of the subroutine we want to run after the timer has arrived.
? 5000. This parameter is the time we want the timer to wait before calling PausedSection (in milliseconds; 5000 milliseconds equals 5 seconds). In other words, this is the pause we need. If you need to pause the script for 30 seconds, you can set this parameter to 30000.
? VBScript. This parameter is required, it just tells the script that PausedSection is written in VBScript.
That is, when we click the button, the Test subroutine will run. When the Test subroutine is run, it will create a timer named idTimer. The only function of idTimer is to wait 5 seconds and then call the subroutine PausedSection. Do you understand? OK
So what operations does the subroutine PausedSection perform? Obviously, we can run any code we want; for simplicity, we only do two things here. First, a message box is displayed, which shows the time when we clicked this button and the time when the message box itself actually displays on the screen:
Msgbox dtmStartTime & vbCrLf & Now
If rounding errors are allowed, the interval between these two times should be 5 seconds. Is this important? Of course it is important. Remember that the first thing that happens inside the PausedSection subroutine is to display this message box. If this message box appears after we click the button 5 seconds, it means our script has been paused for 5 seconds. You may remember that this is our ultimate goal.
Another thing we need to do in the PausedSection subroutine is to call the clearTimeout method to effectively clear the timer:
(idTimer)
Why do this? The reason is simple: the timer is designed to run forever. If the timer is not cleared, the PausedSection subroutine will be called every 5 seconds, so our small message box will pop up on the screen every 5 seconds. We really don't want to see such a message box every 5 seconds, so we use clearTimeout to delete the timer.
We admit that this is really not as simple as using 5000; this suggests you may have to weigh it a little before you enable and disable the timer. Therefore, this may be a little challenge, but don’t forget, isn’t this the entire meaning of life?
No, this is not a rhetorical question. As we said, we have been committed to pausing HTA; other than that, we don’t know what life is.
Hello, script expert! How to pause scripts in HTA?
-- TJ
answer:
Hello, TJ. You know, from ancient times to the present, people have spent a lot of time and energy to explore the meaning of life. The script experts never participated. Why? Well, let’s not talk about laziness for now, we know that doesn’t matter: even if you do find the meaning of life, no one cares about it. No one wants to know the reason for our existence; instead, they - like you - just want to know how exactly can we pause a script embedded in the HTML application (HTA). That is the career that script experts devote themselves to.
Now, if you are not familiar with HTA, the first thing you think of may be "use" is "just use". (By the way, if you are not familiar with HTA, you can browse HTA Developers Center (English).) This is a good idea, but it cannot be achieved. Why? Because the Wscript object is a slightly unique object; one of the reasons is that you cannot actually create an instance of this object. And as long as you run under Windows Script Host, Wscript will automatically provide you with it. The problem is here: When you run the code inside the HTA, you are not running under Windows Script Host. You are actually running under the script host provided by Internet Explorer. Because you are not running under Windows Script Host, you cannot access the Wscript object automatically, and because you cannot create your own Wscript object, you cannot access it. In high-tech technical terms, it is "paralyzed".
If Internet Explorer provides a similar method, this is not a big deal; unfortunately, it does not provide it. So is there some magical solution that we can use instead of the Sleep method? Is this necessary to ask?
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Our HTA is very simple: it consists of only one button, and when clicked, a subroutine called Test will be run. Very amazing, right? Well, let's take a look at the <SCRIPT> part of HTA first, and then determine if it's really amazing.
The first thing we do in the <SCRIPT> section is to declare a global variable called dtmStartTime:
Dim dtmStartTime
This actually has no effect on pausing scripts; we just use this variable to help us see if the script is indeed pausing as expected. If you don't understand its meaning yet, don't worry: it will be clear soon.
Next is the Test subroutine, which is called when we click the button:
Sub Test
dtmStartTime = Now
idTimer = ("PausedSection", 5000, "VBScript")
End Sub
Note that there are only two lines of code in this subroutine. In the first line, we just assign the current time and date (using the Now function) to the variable dtmStartTime. Next is the following line of code:
idTimer = ("PausedSection", 5000, "VBScript")
Believe it or not, this is how we implement the Sleep method function. We used the setTimeout method to create a timer with the ID of idTimer. As you can see, we pass three parameters to setTimeout:
? PausedSection. This parameter is the name of the subroutine we want to run after the timer has arrived.
? 5000. This parameter is the time we want the timer to wait before calling PausedSection (in milliseconds; 5000 milliseconds equals 5 seconds). In other words, this is the pause we need. If you need to pause the script for 30 seconds, you can set this parameter to 30000.
? VBScript. This parameter is required, it just tells the script that PausedSection is written in VBScript.
That is, when we click the button, the Test subroutine will run. When the Test subroutine is run, it will create a timer named idTimer. The only function of idTimer is to wait 5 seconds and then call the subroutine PausedSection. Do you understand? OK
So what operations does the subroutine PausedSection perform? Obviously, we can run any code we want; for simplicity, we only do two things here. First, a message box is displayed, which shows the time when we clicked this button and the time when the message box itself actually displays on the screen:
Msgbox dtmStartTime & vbCrLf & Now
If rounding errors are allowed, the interval between these two times should be 5 seconds. Is this important? Of course it is important. Remember that the first thing that happens inside the PausedSection subroutine is to display this message box. If this message box appears after we click the button 5 seconds, it means our script has been paused for 5 seconds. You may remember that this is our ultimate goal.
Another thing we need to do in the PausedSection subroutine is to call the clearTimeout method to effectively clear the timer:
(idTimer)
Why do this? The reason is simple: the timer is designed to run forever. If the timer is not cleared, the PausedSection subroutine will be called every 5 seconds, so our small message box will pop up on the screen every 5 seconds. We really don't want to see such a message box every 5 seconds, so we use clearTimeout to delete the timer.
We admit that this is really not as simple as using 5000; this suggests you may have to weigh it a little before you enable and disable the timer. Therefore, this may be a little challenge, but don’t forget, isn’t this the entire meaning of life?
No, this is not a rhetorical question. As we said, we have been committed to pausing HTA; other than that, we don’t know what life is.