How Can I Create a Custom Dialog Box?

ScriptingGuy1

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I create a custom dialog box that presents the user with two options, and then runs the appropriate subroutine based on the option they chose?

— AM

SpacerHey, Scripting Guy! AnswerScript Center

Hey, AM. Well, today is another day, which is good; after all, yesterday was anything but a banner day here in the scripting world, at least not when it comes to important things like baseball and softball. Yesterday morning, for example, the Scripting Editor and her softball team were shellacked 14-2 in a game called after 4 innings due to the “mercy rule.” That was tough: the Scripting Editor is a tad bit competitive, so she wasn’t too pleased about getting beat. On the bright side, however, she did have a fantastic view of the game, particularly of all those ground balls that whizzed by her as she stood in the spot where a real second baseman would normally stand. Fortunately, she wasn’t hurt; she didn’t get close enough to any of those ground balls to actually get hit.

Note to the Scripting Editor. Just a little good-natured sports humor there. You know how much we all really love you.

Editor’s Note. The part about not getting close to those ground balls isn’t true; the Scripting Editor has the bruised shin to prove it. And the part about the good-natured sports humor, well … the Scripting Editor is well aware of what the rest of the Scripting team thinks of her. Rest assured the feeling is mutual.

Later that day the Scripting Son and his baseball team were shellacked in both ends of a doubleheader, 7-0 and 9-1. The Scripting Son didn’t have any ground balls whiz by him; unfortunately that’s about the only thing that went right for him and the team. (If you’re not a baseball fan we can tell you this much: getting a combined total of 5 hits in two games is not the recommended way to win a doubleheader.)

The net result? During the day the Scripting Editor was in a bad mood, so she didn’t have much to say and pretty much went the entire day without bugging the Scripting Guy who writes this column. That night, the Scripting Son was in a bad mood, so he didn’t have much to say and pretty much went the entire evening without bugging the Scripting Guy who writes this column

You know, come to think of it, maybe it wasn’t such a bad day after all.

Of course, when things are at their darkest there’s only one recourse: you must put your faith in a higher power. You know, a higher power like a Scripting Guy who writes a column that explains how you can create a custom dialog box that presents a user with multiple options and then runs the appropriate subroutine based on the option they chose:

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

Do While (objExplorer.Document.All.ButtonClicked.Value = “”) Wscript.Sleep 250 Loop

strSelection = objExplorer.Document.All.ButtonClicked.Value

objExplorer.Quit

Wscript.Sleep 250

Select Case strSelection Case “Option 1” Wscript.Echo “You selected Option 1.” Case “Option 2” Wscript.Echo “You selected Option 2.” Case “Option 3” Wscript.Echo “You selected Option 3.” Case “Cancelled” Wscript.Quit End Select

We’ll explain how this script works in just a moment; before we do that, however, we have a few other things to talk about. First, neither VBScript nor Windows Script Host provides a built-in method for creating custom dialog boxes; you can kind of, sort of create custom message boxes, but even then you’re limited to using a finite set of buttons. Therefore, we need to cheat a little in order to do this: we need to create an HTML file that displays our options, and then have our script call this HTML file rather than call a custom dialog box. In fact, that’s what this line of code is for:

objExplorer.Navigate “file:///c:\scripts\test.htm”

But more on that in a minute. For now, let’s take a look at that HTML file (C:\Scripts\Test.htm):

<SCRIPT language=”VBScript”>
    Sub OKClicked
        If UserOption(0).Checked Then
            ButtonClicked.Value = “Option 1”
        End If
        If UserOption(1).Checked Then
            ButtonClicked.Value = “Option 2”
        End If
        If UserOption(2).Checked Then
            ButtonClicked.Value = “Option 3”
        End If
    End Sub

Sub CancelClicked ButtonClicked.Value = “Cancelled” End Sub </SCRIPT>

<BODY> <input type=”radio” name=”UserOption” checked=True>Option 1<BR> <input type=”radio” name=”UserOption”>Option 2<BR> <input type=”radio” name=”UserOption”>Option 3<P> <input type=”Button” value=”OK” onClick=”OKClicked”> <input type=”Button” value=”Cancel” onClick=”CancelClicked”> <input type=”hidden” name=”ButtonClicked”> </BODY>

What we’ve got here is an HTML file that displays three radio buttons; that’s what these HTML tags do:

<input type=”radio” name=”UserOption”>Option 1<BR>
<input type=”radio” name=”UserOption”>Option 2<BR>
<input type=”radio” name=”UserOption”>Option 3<P>

In case you’re wondering, we decided to go with radio buttons for one simple reason: that gives us a little more flexibility (adding additional radio buttons makes for a cleaner user interface than adding a bunch of additional push buttons). Do you need just two options? That’s fine; simply delete the tag for the third radio button (the one labeled Option 3). Need four options? That’s also fine; just copy the tag for Option 3, paste it to the end of list, and change the label to Option 4. Pretty simple stuff when you get right down to it.

Note. OK, so if you haven’t done much work with HTML maybe this isn’t all that simple. In that case, you might want to check out the HTA Developers Center for an introduction to working with HTML.

In addition to our radio buttons we also have a pair of regular old buttons, one labeled OK and the other labeled Cancel:

<input type=”Button” value=”OK” onClick=”OKClicked”>
<input type=”Button” value=”Cancel” onClick=”CancelClicked”>

As you can see, if and when someone clicks the OK button we’re going to run a subroutine named OKClicked; if and when someone clicks the Cancel button we’re going to run a subroutine named CancelClicked. And don’t worry; we’ll discuss those two subroutines in just a second.

Before we can do that, however (and yes, there are a lot of twists and turns to today’s column, aren’t there?) we need to discuss this line of code:

<input type=”hidden” name=”ButtonClicked”>

What we’re doing here is adding a hidden control to our HTML page: the control won’t be visible onscreen, but we can still do things like assign it a value. Why do we need a hidden control on our page? Well, technically we don’t; we could have used a different approach in solving this problem. However, using a hidden control makes this whole task much easier to carry out. We have a hidden control that has no value. As you’ll see, our script periodically checks the value of this hidden control. As soon as a value does get assigned to the control the script knows that we’ve made a selection in our “dialog box” and then goes ahead and takes action based on that selection.

Which, again, is something we’ll explain in just a moment.

Let’s assume that a user has started your script, something which causes the “dialog box” to appear onscreen. He or she selects one of the radio button options and then clicks OK. What happens at that point?

Well, as we noted, clicking the OK button causes the OKClicked subroutine to run. Inside that subroutine we simply execute a series of If Then statements to determine which radio button was selected (or, in HTML parlance, which button was checked):

If UserOption(0).Checked Then
    ButtonClicked.Value = “Option 1”
End If

If you’re wondering how this works, all our radio buttons have the same name (UserOption); that’s how we ensure that the buttons work together as a group. In turn, each individual button in a group is automatically assigned an index number: the first button in the group is button 0, the second button is button 1, and so on. All we’re doing here is saying this: If the first button is checked then assign Option 1 to the value of our hidden control (ButtonClicked). We then repeat this same bit of code for each possible selection.

What if the user clicks the Cancel button? Well, in that case we run a different subroutine (CancelClicked) and assign the value Cancelled to the hidden control

Sub CancelClicked
    ButtonClicked.Value = “Cancelled”
End Sub

And that’s basically it for the HTML file. Now – finally! – let’s turn our attention to the script, which starts out by creating an instance of the InternetExplorer.Application object:

Set objExplorer = CreateObject(“InternetExplorer.Application”)

After we’ve created an instance of Internet Explorer we then use the Navigate method to open the file C:\Scripts\Test.htm; we configure the size of the Internet Explorer window (hiding the tool bar and status bar while we’re at it); then we make the whole thing appear on screen by setting the Visible property to 1:

objExplorer.Navigate “file:///c:\scripts\test.htm”
objExplorer.ToolBar = 0
objExplorer.StatusBar = 0
objExplorer.Width = 400
objExplorer.Height = 250
objExplorer.Visible = 1

At this point we start doing some real work. To begin with, we have to make sure the script pauses until the user makes a selection in the HTML file. With that in mind we use this line of code to periodically check the value of the ButtonClicked control:

Do While (objExplorer.Document.All.ButtonClicked.Value = “”)
    Wscript.Sleep 250
Loop

If ButtonClicked has no value (that is, if the value equals “”, an empty string) we simply pause the script for 250 milliseconds and then try again. This continues until the user finally clicks either the OK or the Cancel button.

Note. What if the user simply closes the Internet Explorer window? That’s going to generate an error and the script will terminate. If you’d prefer that the script come to a more graceful termination you could include some error handling to check for and respond to that condition. But that’s more than we wanted to do today.

As soon as the value of the ButtonClicked control has changed we store that value in a variable named strSelection, then call the Quit method to dismiss our instance of Internet Explorer:

strSelection = objExplorer.Document.All.ButtonClicked.Value

objExplorer.Quit

From there we pause for 250 milliseconds (giving Internet Explorer a chance to close), then use the following Select Case block to take action based on the user’s selection:

Select Case strSelection
    Case “Option 1” 
        Wscript.Echo “You selected Option 1.”
    Case “Option 2” 
        Wscript.Echo “You selected Option 2.”
    Case “Option 3” 
        Wscript.Echo “You selected Option 3.”
    Case “Cancelled”
        Wscript.Quit
End Select

Obviously these aren’t particularly exciting actions, but, needless to say, you can replace our code with pretty much anything you want.

And there you have it, AM. It’s a bit of a workaround and it’s not quite as elegant as creating a true custom dialog box. But it works.

For now, though, it’s time to head to Stanwood High School and another Scripting Son doubleheader. Will it be another quiet night at the Scripting Home? We’ll soon find out.

And no, we won’t discuss the Scripting Editor’s team and its chances of redeeming itself. After all, even a higher power is helpless in the face of some things.

0 comments

Discussion is closed.

Feedback usabilla icon