Hey, Scripting Guy! I know that, by using the WSH Popup method, you can time out a message box. Is it possible to do something similar with the InputBox function?
Hey, JR. Greetings from sunny Florida! Well, at least we assume it’s sunny Florida; it’s late Sunday night as the Scripting Guy who writes this column writes this column, and, at the moment, it’s pretty dang dark outside. However, it will soon be sunny again; after all, this is Florida, and it pretty much has to be sunny. Otherwise they have to give us our money back.
So far the Scripting Guys’ trip to TechEd Orlando is off to a good start: we spent most of our first day here researching the rides at Universal Studios Islands of Adventure. (Research is a very important part of being a Scripting Guy.) On top of that, we made an initial effort to determine if they really do sell margaritas at Jimmy Buffet’s Margaritaville. Those results were inconclusive, so we may have to go back and do additional research.
If you know what we mean.
As much fun as Sunday was, however, today promises to be an even more exciting day: today we’re going to go register for the conference; we’re going to do a “Tech Check” for our instructor-led lab; and we’re going to try to track down the boxes full of handouts and bobbleheads that we shipped to Orlando. Jealous? Understood
Although, the more we think about it, the less fun this all sounds; the truth is, it sounded way better in the guide book than it does now. And to think that we gave up a trip to Sea World for that.
Oh, well; easy come, easy go. In the meantime we have a question to answer. And here’s your answer, JR: as far as we know there’s no way to apply a timeout value to an InputBox. No way at all.
However (even when there’s no answer there’s almost always a however), there is a way that we can mimic this behavior: we can use an instance of Internet Explorer to stand in for the InputBox, and then apply a timeout to that instance of Internet Explorer. It’s not the most elegant solution in the world; for one thing, you’ll need two files (your script and a .HTM file). However (there’s that word again), it should do the trick.
So how will it do the trick? Before we explain that, let’s take a peek at the HTML file we need to create (C:\Scripts\Test.htm):
<SCRIPT language="VBScript"> Sub OKClicked ButtonClicked.Value = BasicTextBox.Value End Sub Sub CancelClicked ButtonClicked.Value = "Cancelled" End Sub </SCRIPT> <BODY> <input type="text" name="BasicTextBox" size="50" Value="Default value"><P> <input type="Button" value="OK" onClick="OKClicked"> <input type="Button" value="Cancel" onClick="CancelClicked"> <input type="hidden" name="ButtonClicked"> </BODY>
We’re not going to explain the HTML tagging in any detail today; that goes a bit beyond what we can do in a single column. Suffice to say that we have an HTML page that features a text box (the place where the user enters his or her input); an OK button and a Cancel button; and a hidden field. When this page pops up onscreen, the user can enter data into the text box (which has a default value of, well, Default value) and then click OK; alternatively, he or she can simply click Cancel. Either way, a value is assigned to the hidden field. What our .VBS file does is monitor the value of that hidden field. As soon as it has a value, the script closes the HTML page and then moves on to bigger and better things. Onscreen, our little HTML page will look something like this:
Note. Yes, you could create a page that looks a little more like an InputBox. We were too lazy – and still a bit damp from Popeye and Bluto’s Bilge Rat Barges – to do that ourselves.
Ah good point: how do we apply a timeout to this HTML page? Tell you what, let’s take a look at our actual script code, and then see if we can figure that out:
On Error Resume Next Set objExplorer = CreateObject("InternetExplorer.Application") objExplorer.Navigate "file:///c:\scripts\test.htm" objExplorer.ToolBar = 0 objExplorer.StatusBar = 0 objExplorer.Width = 400 objExplorer.Height = 250 objExplorer.Visible = 1 i = 0 Do While (objExplorer.Document.All.ButtonClicked.Value = "") Wscript.Sleep 250 i = i + 1 If i = 40 Then Exit Do End If Loop strValue = objExplorer.Document.All.ButtonClicked.Value If strValue = "" Then strValue = "Default value" End If objExplorer.Quit Wscript.Sleep 250 Wscript.Echo strValue
As you can see, we start things off by creating an instance of the InternetExplorer.Application object; that’s the object that lets us create – and manipulate – our very own instance of Internet Explorer. After we create the object, we use the Navigate method to open our “input box” (the file C:\Scripts\Test.htm):
We then assign values to several properties of our Internet Explorer instance: we set the ToolBar and StatusBar properties to 0 (which hides the tool bar and status bar from view), we define both the Width and Height of the Internet Explorer window. In addition, we set the Visible property to True. That’s important, by the way: if you don’t do that, you won’t be able to see your Web page. And let’s face it, an invisible Web page is of little use to anyone.
OK, maybe the Invisible Man. But no one else that we know of.
After assigning the value 0 to a counter variable named i we then hit this block of code:
Do While (objExplorer.Document.All.ButtonClicked.Value = "") Wscript.Sleep 250 i = i + 1 If i = 40 Then Exit Do End If Loop
You know, we had the very same question: what is going on here? What we’ve done here is set up a Do While loop that continues to run until our hidden field (objExplorer.Document.All.ButtonClicked) has a value. (When the HTML page first loads up, this field does not have a value.) What the script does is check to see if the Value of our hidden field is an empty string (“”). If it is empty, then the script sleeps for one-quarter of a second (250 milliseconds). Once that brief pause is over, we then increment our counter variable i by 1.
Why? Well, we’ve decided to apply a 10-second timeout to the HTML page: if 10 seconds have elapsed and the user still hasn’t entered something then we’re going to automatically dismiss the page. Admittedly, that sounds pretty straightforward; on the other hand, spending the day searching for boxes at the Convention Center sounded pretty exciting, too. For better or worse, however, it’s a little trickier than that. For example, we could just pause the script for 10 seconds and then proceed from there. That would work, but it wouldn’t make for a very good user experience.
Why not? Well, suppose the HTML page appears and the user immediately clicks Cancel. Despite that rapid response, however, nothing will happen until the 10-second timeout has elapsed: the user will click Cancel, but it will be 10 seconds before the HTM page disappears.
Fortunately, though, our approach ensures that only a split second (250 milliseconds) elapses before the HTML page disappears. We check the value of the hidden field, then pause for 250 milliseconds. We increment our counter variable by 1, then check to see if this counter variable is equal to 40. Why 40? Well, remember, we want to set a 10-second timeout on this page. If we pause for one-quarter of a second at a time, 40 such pauses will add up to 10 seconds. (40 x 250 = 10,000, and 10,000 divided by 1,000 equals 1.) If i equals 40, that means we’ve reached the 10-second time limit. As a result, we call the Exit Do statement to exit the loop.
Of course, if i isn’t equal to 40 we simply go back to the top of the loop and repeat the process, checking to see if the hidden field has a value. If this field does have a value, then we automatically exit the loop; after all, our Do loop is designed to function only as long as the hidden field has no value.
Sooner or later we’ll eventually exit the Do loop, either because the user entered a value and clicked OK, the user clicked Cancel, or the HTML page timed out. As soon as we exit the loop we use this line of code to grab the value of the hidden field and store it in a variable named strValue:
strValue = objExplorer.Document.All.ButtonClicked.Value
That’s nice, but what if the HTML page timed-out? After all, in that case, the hidden field won’t have a value. Consequently, we use this chunk of code to assign it the default value Default value:
If strValue = "" Then strValue = "Default value" End If
From there we call the Quit method to terminate our instance of Internet Explorer, then pause the script 250 milliseconds, giving Internet Explorer a chance to disappear from screen. At that point we can echo back the value of the variable strValue and then call it a day:
Elegant? Maybe not. But, like we said, it works.
We hope that answers your question, JR, because that’s the best we can do for now; it’s time for the Scripting Guy who writes this column to get some sleep. After all, he has a busy day ahead of him, and a busy day behind him: riding theme park rides all day is more tiring than you might think. Still, while it might have been tiring it was a good day all around. Well, maybe not for the Scripting Editor. She enjoyed the rides and everything, but we’re not sure if she liked all the people who came up to her and, motioning towards the Scripting Guy who writes this column, remarked on the fact that “… it’s just so wonderful that you brought your grandson to Islands of Adventure!” And hey, don’t think the Scripting Guy who writes this column doesn’t appreciate that, too … Grandma. (Editor’s Note: Obviously the Scripting Guy who writes this column was already asleep and dreaming when he wrote that last part. Goodnight Gramps.)