The Complete WIL Tutorial

 

Late one evening around the flickering of the screensaver amidst greasy pizza boxes and crumpled diet soda cans, a haggard programmer relayed his vision for the future to his equally haggard teammates. They were astounded. Was it the late hour, the heaviness of the pepperoni turning somersaults in their gut or this ingenious theory which caused the sudden delirium in their minds? The next day the vision went public but is yet to be realized.

The myth of the infamous "paper-less" office may never be seen in our lifetimes. If you'd like to give it a try, pop over to Topic by Topic and click your way through the tutorial.

If you'd prefer to learn WIL with the tutorial in hand rather than on screen, you can select print button at the top and print the entire tutorial in one swell foop.

Approximate size; 33 pgs.

Creating WIL Scripts Files

WIL is a script file interpreter. Before you can do anything useful with the WIL interpreter, you must have at least one WIL script file to interpret.

Your program installation puts several sample scripts into a "samples" directory. Sample scripts are located in a "samples" subdirectory in the WinBatch directory.

WIL script files must be formatted as plain text files. You can create them with WinBatch Studio, the Windows Notepad or another text editor.

Word processors like WordPerfect, WordPro, and Word can also save scripts in plain text formatted files.

The .WBT (WinBatch) extension is used in this help file for batch file extensions, but, you can use others just as well. If you want to click on a batch file and have Windows run it, be sure that you associate it in Windows with your executable program file. When you installed your program, an association was automatically established between the interpreter and .WBT files.

Each line in a script file contains a statement written in WIL, Windows Interface Language.

A statement can be a maximum of 2048 characters long. Indentation does not matter. A statement can contain functions, commands, and comments.

A single WinBatch script cannot exceed 64 kilobytes in file size.

You can give each script file a name which has an extension of WBT (e.g. TEST.WBT). We'll use the terms WinBatch script files and WBT files interchangeably.

Running WIL Utilities

WIL system utilities are very versatile. They can be run from icons in the Windows Explorer.

  • from macros in word processors and spreadsheets.

  • from a command line entry such as the "Run..." from the Explorer Start button.

  • by double clicking.

  • from menu items via the Filemenu and Popmenu utilities.

  • from other WIL scripts to serve as single or multiple "agents", event handlers, or schedulers.

  • from any Windows application or application macro language that can execute another Windows program. Software suite macro languages and application builders like Visual Basic and PowerBuilder are examples of these.

Command Line Parameters

WIL utilities run like any other Windows program. They can be run from a command line, a shortcut or icon, in a shell program like the Windows Explorer, or a Start Menu selection.

WIL utilities are usually run as files with the extension .WBT. When some WIL utilities are used, they need information passed to them when they run. This is easily done by passing command line parameters to them.

This capability can be used from the command line in the Run menu .

Parameters can be also be passed through the command line entry included in the item properties of any icon. Finally, an application can send parameters to a WIL utility it launches from a command line or from a function in a macro language.

A command like this runs a WinBatch system utility from a command line or an icon:

 

WINBATCH.EXE filename.wbt p1 p2... p[n]

 

This command line can be entered into a Command Line text entry box like this one:

image\tutbut_shg.gif

The command line is longer than the dialog can show, but it can be easily edited with the arrow keys.

WINBATCH.EXE is the generic name of your WinBatch executable. The specific, or actual, name for the WinBatch application will change to reflect the operating system in use.

"filename.wbt" is any valid WBT file, and is a required parameter.

"p1 p2 ... p[n]" are optional parameters to be passed to the WBT file on startup. Each is delimited from the next by one space character.

Parameters passed to a WBT file will be automatically inserted into variables named param1, param2, etc. The WinBatch utility will be able to use these. An additional variable, param0, gives you the total number of command-line parameters.

Example:

Passing parameters on the command line to a WinBatch script.

Create a WinBatch script called "myscript.wbt" and put it in a temp directory. The contents of "myscript.wbt" should be the following:

 

Message(param1,param2)

Exit

 

Go to the Start Menu and Select Run. Enter the following commandline (all on a single line):

 

"c:\Program Files\WinBatch\System\WinBatch.exe" "c:\temp\myscript.wbt" "Example" "Hello World"

 

What is a WIL Program?

A WIL program, like a DOS batch file, is simply a list of commands for the computer to process. Any task which will be run more than once, or which requires entering multiple commands or even a single complex command, is a good candidate for automation as a WIL program. For example, suppose you regularly enter the following commands to start Windows:

First:

cd \windows

then:

win

and then:

cd \

Here, you are changing to the Windows directory, running Windows, and then returning to the root directory. Instead of having to type these three commands every time you run Windows, you can create a DOS batch file, called WI.BAT, which contains those exact same commands:

cd \windows
win
cd \

 

Now, to start Windows, you merely need to type the single command WI, which runs the WI.BAT batch file, which executes your three commands.

WIL programs work basically the same way.

 

 

Our First WIL Program

 

Tutor Example

  1. Open an editor, such as WinBatch Studio.

  2. Type in the line.

  3. Save the program with an appropriate extension. If you're using WinBatch, this extension will be .WBT. We will refer to this script as tutor.wbt.

  4. Run tutor.wbt by double-clicking on the filename

 

Our first WIL program will simply run our favorite Windows application: Solitaire. If you are using a menu script-based implementation of the WIL Interpreter, refer to the section on Menu Files for instructions on how to create and edit WIL menu items. If you are using a batch file-based implementation of the WIL Interpreter, you will be creating your batch files using an editor, such as the WinBatch Studio, that is capable of saving text in pure ASCII format. In either case, let's create a WIL program containing the following line of text:

 

Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

Save the program, and run it (refer to your product documentation, the User's Guide, for information on how to execute a WIL program). Presto! It's Solitaire.

 

Note: in order to run this script solitaire must be installed, make sure you installed GAMES with your windows platform .

 

 

Functions and Parameters

 

 

Now, let's look more closely at the line we entered:

 

Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

The first part, Run, is a WIL function. As you might have guessed, its purpose is to run a Windows program. There are a large number of functions and commands in WIL, and each has a certain syntax which must be used. The correct syntax for all WIL functions may be found in the WIL Function Reference (Introduction). The entry for Run starts off as follows:

Syntax:

Run (program-name, parameters)

Parameters:

(s) program-name the name of the desired .EXE, .COM, .PIF, .BAT file, or a data file.

(s) parameters optional parameters as required by the application.

 

Like all WIL functions, Run is followed by a number of parameters, enclosed in parentheses. Parameters are simply additional pieces of information which are provided when a particular function is used; they may be either required or optional. Optional parameters are indicated by being enclosed in square brackets. In this case, Run has two required parameters: the name of the program to run, and the arguments to be passed to the program.

WIL functions use several types of parameters. Multiple parameters are separated by commas. In the example

 

Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

Note: Strings are delimited by quotes, ("", "")

 

 

Note: (s) denotes the parameter requires a string

"C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe" and "" are both string constants. String constants can be identified by the quote marks which delimit (surround) them. You may use either double ("), single forward (') or single back (`) quote marks as string delimiters; the examples in this help file will use double quotes.

In our shorthand method for indicating syntax the (s) in front of a parameter indicates that it is a string parameter.

You may have noticed how we said earlier that the two parameters for the Run function are required, and yet the entry for Run in the WIL Function Reference describes the second parameter - "parameters" - as being optional. Which is correct? Well, from a WIL language standpoint, the second parameter is required. That is, if you omit it, you will get a syntax error, and your WIL program will halt. However, the program that you are running may not need parameters. Solitaire, for example, does not take parameters. The way we handle this in our programs is to specify a null string (two quote marks with nothing in between ) as the second parameter, as we have done in our example above.

 

Example 2
 

  1. Open WinBatch Studio.

  2. Type in the line.

  3. Save the file as notetest.wbt.

  4. Close WinBatch Studio

  5. Run the wbt by double-clicking on the filename.

To illustrate this further, let's create a WIL program containing the following line:

 

Run("notepad.exe", "")

 

This is just like our previous file, with only the name of the program having been changed. Save the file, and run it.

Is Notepad running? If it is - good. If not, check your script. WinBatch will look for Notepad.exe on the computer's search path. If it isn't there, you may need to locate it with the File Manager or the Windows Explorer. Add a complete pathname to the run statement and the script should work.

Now, edit the WIL program as follows:

 

Run("notepad.exe", "c:\autoexec.bat")

 

Save the program, exit WinBatch Studio, and run the WIL program again. You should now be in Notepad, with AUTOEXEC.BAT loaded. As we've just demonstrated, Notepad is an example of a program which can be run with or without a file name parameter passed to it by WIL.

 

It can often be helpful to add descriptive text to your WIL programs:

 

; This is an example of the Run function in WIL
Run("notepad.exe", "c:\autoexec.bat")

 

Note: semi-colons denote comments.

The semi-colon at the beginning of the first line signifies a comment, and causes that line to be ignored. You can place comment lines, and/or blank lines anywhere in your WIL programs. In addition, you can place a comment on the same line as a WIL statement by preceding the comment with a semi-colon. For example:

 

Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "") ;this is a very useful function

 

Everything to the right of a semi-colon is ignored. However, if a semi-colon appears in a string delimited by quotes, it is treated as part of the string.

 

 

Displaying Text

Tutor Example continued...
 

  1. Exit Solitaire.

  2. Activate or open your editor.

  3. Load tutor.wbt.

  4. Add the new lines.

  5. Save the file.

  6. Run the wbt by double-clicking on the filename.

Now, let's modify our original WIL program as follows:

 

; solitare.program
Display(5, "Good Luck!", "Remember, it's only a game.")
Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

And run it. Notice the little dialog box which pops up on the screen with words of encouragement:

image\tutbut1_shg.gif

 

That's done by the Display function in the second line above. Here's the reference for Display:

Syntax:

Display (seconds, title, text)

Parameters:

(i) seconds seconds to display the message (1 - 3600).

(s) title Title of the window to be displayed.

(s) text Text of the window to be displayed.

 

The Display function has three parameters. The first parameter is the number of seconds which the display box will remain on the screen (you can make the box disappear before then by pressing any key or mouse button). This is a numeric constant, and - unlike string constants - it does not need to be enclosed in quotes (although it can be, if you wish, as WIL will automatically try to convert string variables to numeric variables when necessary, and vice versa). In our example above, we are displaying the box for 5 seconds. The second parameter is the title of the message box, and the third parameter is the actual text displayed in the box.

Note: In our shorthand method for indicating syntax the (s) in front of a parameter indicates that it is a string. (a) indicates an array, an (i) indicates that it is an integer, (f) indicates a floating point number parameter, (r) indicates a COM object reference and (t) indicates special type information described in the function’s text

Tutor Example continued...

  1. Exit Solitaire.

  2. Edit tutor.wbt -Comment out the Run statement.

  3. Save the file.

  4. Run the wbt by double-clicking on the filename.

Now, exit Solitaire (if you haven't done so already), and edit the WIL program by placing a semi-colon at the beginning of the line with the Run function. This is a handy way to disable, or "comment out," lines in your WIL programs when you want to modify and test only certain segments. Your WIL program should look like this:

 

; solitare.program
Display(5,"Good Luck","Remember, it's only a game")
; Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

Feel free to experiment with modifying the parameters in the Display function. Try adjusting the value of the first parameter. If you look up Display in the WIL reference section, you will see that the acceptable values for this parameter are 1 3600. If you use a value outside this range, WIL will adjust it to "make it fit"; that is, it will treat numbers less than 1 as if they were 1, and numbers greater than 3600 as 3600.

Also, try using a non-integer value, such as 2.9, and see what happens (it will be converted to an integer). Play around with the text in the two string parameters; try making one, or both, null strings ("").

 

 

Getting Input

 

 

Now, let's look at ways of getting input from a user and making decisions based on that input. The most basic form of input is a simple Yes/No response, and, indeed, there is a WIL function called AskYesNo:

Syntax:

AskYesNo (title, question)

Parameters

(s) title title of the question box.

(s) question question to be put to the user.

Returns:

(i) @YES or @NO, depending on the button pressed.

 

You should be familiar with the standard syntax format by now; it shows us that AskYesNo has two required parameters. The Parameters section tells us that these parameters both take strings, and tells us what each of the parameters means.

You will notice that there is also a new section here, called Returns. This section shows you the possible values that may be returned by this function. All functions return values. We weren't concerned with the values returned by the Run and Display functions. But with AskYesNo, the returned value is very important, because we will need that information to decide how to proceed. We see that AskYesNo returns an integer value.

An integer is a whole (non-fractional) number, such as 0, 1, or 2 (the number 1.5 is not an integer, it is a floating point number). We also see that the integer value returned by AskYesNo is either @YES or @NO. @YES and @NO are predefined constants in WIL. All predefined constants begin with an @ symbol. Even though the words Yes and No are strings, it is important to remember that the predefined constants @YES and @NO are not string variables. (Actually, @YES is equal to 1, and @NO is equal to 0. Don't worry if this is confusing; you really don't need to remember or even understand it.)

 

Tutor Example continued...

  1. Edit tutor.wbt

  2. Delete the Display statement.

  3. Add AskYesNo statement.

  4. Delete semi-colon from the Run.

  5. Save the file.

  6. Run the wbt by double-clicking on the filename.

Now, let's modify our WIL program as follows:

 

AskYesNo("Really?", "Play Solitaire now?")

Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

and run it. You should have gotten a nice dialog box which asked if you wanted to play Solitaire:

 

image\tutbut2_shg.gif

 

but no matter what you answered, it started Solitaire anyway. This is not very useful. We need a way to use the Yes/No response to determine further processing. First, we need to explore the concept and use of variables.

 

 

Using Variables

 

 

A variable is simply a placeholder for a value. The value that the variable stands for can be either a text string (string variable) or a number (numeric variable). You may remember from Algebra 101 that if X=3, then XX=6. X is simply a numeric variable, which stands here for the number 3. If we change the value of X to 4 (X=4), then the expression XX is now equal to 8.

Okay. We know that the AskYesNo function returns a value of either @YES or @NO. What we need to do is create a variable to store the value that AskYesNo returns, so that we can use it later on in our WIL program. First, we need to give this variable a name. In WIL, variable names must begin with a letter, may contain any combination of letters or numbers, and may be from 1 to 30 characters long. So, let's use a variable called response. (We will distinguish variable names in this text by printing them in all lowercase letters; we will print function and command names starting with a capital letter. However, in WIL, the case is not significant, so you can use all lowercase, or all uppercase, or whatever combination you prefer.)

 

Tutor Example continued...

  1. Exit Solitaire.

  2. Edit tutor.wbt -Add variable name.

  3. Save the file.

  4. Run the wbt by double-clicking on the filename.

We assign the value returned by AskYesNo to the variable response, as follows:

 

response=AskYesNo("Really?", "Play Solitaire now?")

 

Notice the syntax. The way that WIL processes this line is to first evaluate the result of the AskYesNo function. The function returns a value of either @YES or @NO. Then, WIL assigns this returned value to response. Therefore, response is now equal to either @YES or @NO, depending on what the user enters.

Now, we need a way to make a decision based upon this variable.

 

 

Making Decisions

 

 

WIL provides a way to conditionally execute a statement, and that is by using the If ... Endif command. Actually, there are several forms of the If statement -- the structured form and the single statement form.

Structured Forms

 If expression
  series of statements
 Endif

 

 If expression
  series of statements
 Else
  series of statements
 Endif

 

Single Statement Forms

 If expression  Then statement.

 

 If expression  Then statement
   Else statement

 

(We refer to If ... Endif as a command, rather than a function, because functions are followed by parameters in parentheses, while commands are not. Commands tend to be used to control the flow of execution within the WIL interpreter.)

 

Tutor Example continued...

1. Exit Solitaire.

2. Edit tutor.wbt -Add If/Endif command to check return of the variable.

3. Save the file.

4. Run the wbt by double-clicking on the filename.

The use of If ... Endif can easily be illustrated by going back to our WIL program and making these modifications:

 

response=AskYesNo("Really?", "Play Solitaire now?")

If response == @YES

 Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

Endif

 

However, as this example is a single statement, rather than a series of statements, the single statement structure is more appropriate. There are generally many different ways to perform any task in WIL. With experience you will be able quickly decide the best way to do any task.

 

response=AskYesNo("Really?", "Play Solitaire now?")

If response == @YES Then Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

Experiment with additional If structures.

In this example, we are using If ... Then to test whether the value of the variable response is @YES. If it is @YES, we start Solitaire. If it isn't @YES, we don't. The rule is: if the condition following the If keyword is true or works out to a non-zero value, then the statement(s) following are performed. If the condition following the If keyword is false or works out to a zero value, then the statement(s) following are ignored.

There is something extremely important that you should note about the syntax of these If ... Endif commands: the double equal signs (==). In WIL, a single equal sign (=) is an assignment operator - it assigns the value on the right of the equal sign to the variable on the left of the equal sign. As in:

 

response=AskYesNo("Really?", "Play Solitaire now?")

 

This is saying, in English: "Assign the value returned by the AskYesNo function to the variable named response." But in the statement:

 

If response == @YES Then Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

we do not want to assign a new value to response, we merely want to test whether it is equal to @YES. Therefore, we use the double equal signs (==), which is the equality operator in WIL. The statement above is saying, in English: "If the value of the variable named response is equal to @YES, then run the program C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe." If you used a single equal sign (=) here by mistake, you would get an error message:

 

image\tutbut3_shg.gif

 

Note:

(=) this IS that

(==) this EQUALS that

Which is WIL's way of telling you to re-check your syntax.

If you've become confused, just remember that a single equal sign (=) is an assignment operator, used to assign a value to a variable. Double equal signs (==) are an equality operator, used to test whether the values on both sides of the operator are the same.

 

 

If you have a problem with one of your WIL programs, make sure to check whether you've used one of these symbols incorrectly. It's a very common mistake, which is why we emphasize it so strongly!

We've seen what happens when the statement(s) following the If condition are true. But what happens when the condition is false? Remember we said that when the If condition is false, the following statement(s) are ignored. There will be times, however when we want to perform an alternate action in this circumstance. For example, suppose we want to display a message if the user decides that he or she doesn't want to play Solitaire. We could write:

 

response=AskYesNo("Really?","Play Solitaire now?")

If response == @YES

 Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

Else

 Display(5, "", "Game canceled")

Endif

 

Using the single statement If...Then...Else structure the same code would look like:

 

response=AskYesNo("Really?", "Play Solitaire now?")

If response == @YES Then Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

Else Display(5, "", "Game canceled")

 

When you have only single statements to execute when conditions are true or false, the single statement form may be preferred. However, what would happen if you had several functions you wanted to perform if the user answered Yes? You would end up with something unwieldy:

 

response=AskYesNo("Really?", "Play Solitaire now?")
If response==@YES Then Display(5,"","On your mark")
If response==@YES Then Display(5,"", "Get set ...")
If response==@YES Then Display(5, "", "Go!")
If response==@YES Then Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")
If response==@NO Then Display(5,"","Game canceled")

 

Clearly, the best way of handling this is to use the If... Else... Endif structured form.

 

response=AskYesNo("Really?", "Play Solitaire now?")
If response == @YES
 Display(5, "", "On your mark ...")
 Display(5, "", "Get set ...")
 Display(5, "", "Go!")
 Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")
Else
  Display(5, "", "Game canceled")
Endif

 

 

Control of Program Flow

 

 

The linear flow of statements (executing one statement after another) is not always preferred or possible. WIL provides the standard set of flow control commands: For, While, Switch and GoSub. These commands give you the ability to redirect the flow of control in your WIL programs.

The For command controls the looping of a block of code based on an incrementing index. The While command conditionally and/or repeatedly executes a series of statements. The Switch statement allows selection among multiple blocks of statements. GoSub transfers control to another point in the WIL program and saves the location for a Return statement.

Let's explore the use of these commands further. Perhaps you need to break your Solitaire habit by limiting your time of play (it has, by now, become obvious to your boss and co-workers that, ever since you got this program, all you do is play solitaire).

Tutor Example continued...

First you need to ask yourself how long you would like to play by adding the following line to the top of your script.

 

mins=AskLine("Solitaire","How many mins do you want to play?","", 0)

 

 

 

 

  1. Exit Solitaire. (If it is running.)

  2. Edit tutor.wbt -Add AskLine to the top of the script.

  3. Save the file.

  4. Run the wbt by double-clicking on the filename.

This will display a message box which prompts you for the number of minutes you would like to play.

Once you enter the desired number of minutes, you could display an additional message as a response to the specific amount of time entered. Switch, as you remember, allows selection from among multiple blocks of statements. Each block of statements is called a case. In the sample below, there are several case statement blocks. Selection of one of the cases is determined by the number of minutes stored in the variable mins . If the number is 3, then case 3 will be executed. All numbers not accounted for will be executed by the default case, mins.

  1. Exit Solitaire.

  2. Edit tutor.wbt to add the Switch statement

Type the following code into tutor.wbt. Test the Switch statement by entering a number into the AskLine dialog box. Try running it several times using various numbers.

 

 

 

Your code should look like the code below. Remove extra statements.

 

mins = AskLine("Solitaire", "How many mins do you want to play?", "", 0)
mins = Int(mins)
Switch mins
  case 0
      Display(5, "", "Game canceled")
      exit
      break
  case 1
      Message("Only a minute?", "Wow! You've got willpower.")
      break
  case 2
      Message("2 Minutes?", "This isn't much of a break.")
      break
  case 3
      Message("3 Minutes?", "You've barely got time to shuffle.")
      break
  case 4
      Message("HA,HA,HA", "I dare you to try to beat me.")
      break
  case mins ;default case - must be last in the switch
      Message("THAT LONG!!!", "Where did you get all that time?")
      break
EndSwitch
Run
("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

 

 

In our example, each case statement block is composed of three parts; a case statement followed by a number, a series of one or more statements and the break command. If the number behind the case statement matches the number behind the switch statement, then the case block is executed. Once the correct message has been displayed, break terminates the case block and transfers control to the EndSwitch statement.

Now we need to create a timer to track the time elapsed and compare it to the time entered. The While command, which repeats execution of a series of statements by telling WIL, "Do the following while a condition is present," does this job nicely.

 

Tutor Example continued...

  1. Exit Solitaire.

  2. Edit tutor.wbt -
    Set up variables. Add the timing code below the Run statement.

  3. Save the file.

  4. Run the wbt by double-clicking on the filename.

First let's set up a couple of variables.

 

goal = mins * 60
timer = 0

 

Now for the While statement. The first line sets the condition, "While the timer is less than the goal execute this series of statements."

 

While timer < goal
  remain = goal - timer
  WinTitle("Solitaire","Solitaire (%remain% seconds left)")
  TimeDelay(10)
  timer = timer + 10
EndWhile

 

The rest of our series of statements include: a computation of the time remaining (remain) to be displayed, a line to display the time remaining in the Solitaire window title bar, a delay statement to allow time to pass, and a statement to calculate the time elapsed. EndWhile marks the end of statements. WIL marches through the While loop until the variable timer exceeds the value of the variable goal.

So what happens if suddenly your time is up and you're four moves away from winning? Can't have that happening.

 

 

We can give ourselves the opportunity to add more time by adding another Askline statement.

 

mins=AskLine("More Time?","Enter additional minutes.",0, 0)

 

If a time is entered the timer will need to be used again. Of course, it would be easy to copy that portion of the script and insert it after the new line. However, the same script can be utilized with the assistance of GoSub.

GoSub causes the flow of control to go to another point in the WIL program while remembering its point of origin. The name GoSub is an abbreviation of "Go To Subroutine". You must specify where you want the flow of control to be transferred -- the subroutine name, and you must mark this point with a label. A label is simply a destination address, or marker. The form of the GoSub command is:

 

GoSub label

 

where label is an identifier that you specify. (the first character must be a letter, the label name may consist of any combination of letters and numbers, and the label name may be up to 249 characters long). In addition, the label is preceded by a colon (:) at the point where it is being used as a destination address.

Tutor Example continued...

  1. Exit Solitaire.

  2. Edit tutor.wbt-
    Add :dumdedum label to bottom. Move timing loop below label.
    Add Return after loop. After
    Run statement add GoSub dumdedum.

  3. Save the file.

  4. Run the wbt by double-clicking on the filename.

In our sample script, we move the timing loop to the bottom of the script, add a label marked :dumdedum above the timing script as the destination address. After EndWhile, add the statement, Return to allow the flow of control to return from the bottom of the GoSub.

We'll add a GoSub statement in after the Run statement. The GoSub statement is saying, in English "go to the line marked :dumdedum, and continue processing from there, but remember where you came from." When Return is reached, control will be transferred back to the statement after the original GoSub.

Notice that the label dumdedum is preceded by a colon as the address, but not on the line where it follows the GoSub keyword. This is important. Although you can have multiple lines in your WIL program which say GoSub dumdedum, you can have only one line marked :dumdedum (just like you can have several people going to your house, but can have only one house with a particular address). Of course, you can use many different labels in a WIL program, just as you can use many different variables, as long as each has a unique name.

 

Tutor Example continued...

  1. Exit Solitaire.

  2. Edit tutor.wbt -
    Add check for return of
    AskLine.
    Add
    WinClose and Exit. (See code below)

  3. Save the file.

  4. Run the wbt by double-clicking on the filename.

In addition to changing the message displayed in the "mins=AskLine" statement, a default time has been added. The value returned will need to be checked. In the example below, "!=" signifies "not equal to". Therefore the line reads, "If mins is not equal to zero then GoSub dumdedum."

 

If mins!=0 then GoSub dumdedum

 

If a time is returned, GoSub will send execution to the :dumdedum label and the waiting process will begin again. After the time has elapsed, control will be returned to the statement following the GoSub.

The last thing we want to do is end the program with the WinClose function and display a final message.

The Exit command is used to keep the processing from "falling through" to the subroutine at the end of the program. In this case, the dumdedum subroutine sits at the end. Exit causes a WIL program to end immediately and not fall into the dumdedum loop.

 

Our altered script has the following appearance from the Run statement to the bottom.

 

Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

GoSub dumdedum

mins=AskLine("More Time?", "Enter additional minutes", 0, 0)
If mins!=0 then GoSub dumdedum

WinClose("Solitaire")
Message("Time's Up", "Get Back to Work!")

Exit

:dumdedum
goal = mins * 60
timer = 0

While timer < goal
   remain = goal - timer
   WinTitle("Solitaire", "Solitaire (%remain% seconds left)")
   TimeDelay(10)
   timer = timer + 10
EndWhile
Return

 

 

The sample script could be considered complete at this point. However, the For command has yet to be discussed. The For command is more complex than the previous commands. It controls the looping of a block of code based on an incrementing index. This command is handy if you want to perform a specific code block a particular number of times. The statement says, "Repeat the block of code for each value of a variable from the initial value to the final value, incrementing the variable after each pass of the loop".

In the sample below, the size of the Solitaire window is manipulated and displayed 10 times before the window is zoomed to full screen. Each time the loop is executed, the coordinate and size variables (j and k) are altered, and then used in a WinPlace statement ( it's time to start looking up functions in the reference yourself now) to affect the position and size of the Solitaire window.

 

Tutor Example continued...

  1. Edit tutor.wbt -
    Add code for the For statement directly after the Run statement.

  2. Save the file.

  3. Run the wbt by double-clicking on the filename.

 

Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe","")

for i = 0 to 9
   j=100-i*10
   k=300i*70
   WinPlace(j,j,k,k, "Solitaire")
next

WinZoom("Solitaire")

 

Note: the case of the window title 'Solitaire' is important. If Solitaire is spelled with a lower case 's', the program will not work.

This concludes the first part of our tutorial. You now have the building blocks you need to create useful WIL programs. In the second part, which follows, we will look in more detail at some of the WIL functions which are available for your use.

See the Completed WIL file, tutor.wbt, at the end of the WIL TUTORIAL.

 

 

Exploring WIL

 

If you take a moment and review the WIL Function Reference, you will notice that WIL uses a very convenient naming convention. WIL functions are named so that the object affected by the function is the first word in the function name -- any function dealing with Files starts with the word "File", and they can be found clumped together in the alphabetically arranged function reference. If you think you might want a function dealing with DDE, simply search this Help files DDE section and scan the available functions.

What follows is just quick overview of the many functions and commands available in WIL. These should be sufficient to begin creating versatile and powerful WIL programs. For complete information on these and all WIL functions and commands, refer to the WIL Function Reference (see Introduction).

 

 

Running Programs

 

There are several functions that you can use to start an application, most of which share a common syntax.

Windows can use file names with embedded spaces. For handling this possibility, use quotation marks like this:

Run(' "My Program" ',"")

Notice: the use of single quotation marks outside of the double quotation marks.

Run (program-name, parameters)

We've already seen the Run function. This function starts a program in a "normal" window. Windows, or the application itself, decides where to place the application's window on the screen.

Example:

 

Run("notepad.exe", "myfile.txt")

 

If the program has an EXE extension, its extension may be omitted:

 

Run("notepad", "myfile.txt")

 

Also, you can "run" data files if they have an extension in WIN.INI which is associated with an executable program. So, if TXT files are associated with Notepad:

 

Run("myfile.txt", "")

 

would start Notepad, using the file MYFILE.TXT.

When you specify a file to run, WIL looks first in the current directory, and then in the directories on your system path. If the file is not found, WIL will return an error. You can also specify a full path name for WIL to use, as in:

 

Run("c:\windows\apps\winbatch.exe", "")

 

RunZoom (program-name, parameters)

RunZoom is like Run, but starts a program as a full-screen window.

 
Example:

RunZoom("excel", "bigsheet.xls")

 

RunIcon (program-name, parameters)

RunIcon starts a program as an icon at the bottom of the screen.

 
Example:

RunIcon("notepad", "")

 

All these Run functions simply launch the program and continue with WIL processing. If you need to wait until the program exits before continuing, then there are a number of other suitable functions also available.

RunWait (program-name, parameters)

RunWait starts a program and waits for it to exit before continuing. This is often required when the "program" is a DOS batch file.

 

RunZoomWait (program-name, parameters)

RunZoomWait starts a program as a full screen window and waits for it to exit before continuing.

 

RunIconWait (program-name, parameters)

RunIconWait starts a program as an icon at the bottom of the screen and waits for it to exit before continuing.

If all these Run functions are too much for you, there is also the combination RunShell function, which combines all the capabilities of the Run functions and adds additional functionality.

 

RunShell (program-name, parameters, working dir, view, waitflag)

RunShell is an advanced form of the Run function that even allows the specification of a working directory, along with the window view mode and whether or not to wait for completion of the run program in a single function.

 

Display and Input

 

Here we have functions which display information to the user and prompt the user for information, plus a couple of relevant system functions.

 
Display (seconds, title, text)

Displays a message to the user for a specified period of time. The message will disappear after the time expires, or after any keypress or mouse click.

 
Example:

Display(2, "Please wait", "Loading Solitaire now")

 

image\tutbut4_shg.gif

 
Message (title, text)

This command displays a message box with a title and text you specify, which will remain on the screen until the user presses the OK button.

 
Example:

Message("Sorry", "That file cannot be found")

 

image\tutbut5_shg.gif

 
Pause (title, text)

This command is similar to Message, except an exclamation-point icon appears in the message box, and the user can press OK or Cancel. If the user presses Cancel, the WIL program ends (or goes to the label :cancel, if one is defined).

 

Example:

 

Pause("Delete Backups", "Last chance to stop!")
; if we got this far, the user pressed OK
FileDelete("*.bak")

 

image\tutbut6_shg.gif

 
AskYesNo (title, question)

Displays a dialog box with a given title, which presents the user with three buttons: Yes, No, and Cancel. If the user presses Cancel, the WIL program ends (or goes to the label :cancel, if one is defined). Otherwise, the function returns a value of @YES or @NO.

 
Example:

response = AskYesNo("End Session", "Really quit Windows?")



image\tutbut7_shg.gif

 
AskLine (title, prompt, default [, format])

Displays a dialog box with a given title, which prompts the user for a line of input. Returns the default if the user just presses the OK button.

 
Example:

yourfile = AskLine("Edit File", "Filename:", "newfile.txt", 0)
Run("notepad", yourfile)

 

image\tutbut8_shg.gif

 

If you specify a default value (as we have with NEWFILE.TXT), it will appear in the response box, and will be replaced with whatever the user types. If the user doesn't type anything, the default is used.

 
Beep

Beeps once.

Beep

And if one beep isn't enough for you:

Beep
Beep
Beep

 

TimeDelay (seconds)

Pauses WIL program execution.

The TimeDelay function lets you suspend processing for a fixed period of time, which can be anywhere from 1 to 3600 seconds.

 

 

 

 

 

Manipulating Windows

 

There are a large number of functions which allow you to manage the windows on your desktop. Here are some of them:

 
WinZoom (partial-windowname)

Maximizes an application window to full-screen.

 
WinIconize (partial-windowname)

Turns an application window into an icon.

 
WinShow (partial-windowname)

Shows a window in its "normal" state.

These three functions are used to modify the size of an already-running window. WinZoom is the equivalent of selecting Maximize from a window's control menu, WinIconize is like selecting Minimize, and WinShow is like selecting Restore.

The window on which you are performing any of these functions does not have to be the active window. If the specified window is in the background, and a WinZoom or WinShow function causes the size of the window to change, then the window will be brought to the foreground. The WinZoom function has no effect on a window which is already maximized; likewise, WinShow has no effect on a window which is already "normal."

Each of these functions accepts a partial windowname as a parameter. The windowname is the name which appears in the title bar at the top of the window. You can specify the full name if you wish, but it may often be advantageous not to have to do so. For example, if you are editing the file SOLITARE.WBT in a Notepad window, the windowname will be Notepad - SOLITARE.WBT.

 

image\tutbut9_shg.gif

 

You probably don't want to have to hard-code this entire name into your WIL program as:

WinZoom("SOLITARE.WBT - Notepad")

 

Instead, you can specify the partial windowname "Notepad":

WinZoom("~Notepad")

 

If you have more than one Notepad window open, WIL will use the one which was most recently used or started.

Note that WIL matches the partial windowname beginning with the first character, so that while

 

WinZoom("Note")

 

would be correct,

 

WinZoom("pad")

 

would not result in a match.

 

Also, the case (upper or lower) of the title is significant, so

 

WinZoom("~notepad")

 

would not work either.

 
WinActivate (partial-windowname)

Makes an application window the active window.

This function makes a currently-open window the active window. If the specified window is an icon, it will be restored to normal size; otherwise, its size will not be changed.

 
WinClose (partial-windowname)

Closes an application window.

This is like selecting Close from an application's control menu. You will still receive any closing message(s) that the application would normally give you, such as an "unsaved-file" dialog box.

 
WinExist (partial-windowname)

Tells if a window exists.

This function returns @TRUE or @FALSE, depending on whether a matching window can be found. This provides a way of insuring that only one copy of a given window will be open at a time.

If you've been following this tutorial faithfully from the beginning, you probably have several copies of Solitaire running at the moment. (You can check by pressing Ctrl-Esc and bringing up the Task Manager. You say you've got five Solitaire windows open? Okay, close them all.) Now, let's modify our WIL program. First, trim out the excess lines so that it looks like this:

Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

Now, let's use the WinExist function to make sure that the WIL program only starts Solitaire if it isn't already running:

If WinExist("Solitaire") == @FALSE Then Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")

 

Note: the tilde '~' character used in the WinExist statement, tells WinExist to search anywhere in the window title for the word 'Solitaire'. For more information see Partial Window Names

And this should work fine. Run the WIL program twice now, and see what happens. The first time you run it, it should start Solitaire; the second (and subsequent) time, it should not do anything.

However, it's quite likely that you want the WIL program to do something if Solitaire is already running - namely, bring the Solitaire window to the foreground. This can be accomplished by using the WinActivate function as follows:

 

If WinExist("Solitaire") == @TRUE
 WinActivate("Solitaire")
Else
 Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")
Endif

 

Note that we can change this to have WinExist check for a False value instead, by modifying the structure of the WIL program:

 

If WinExist("Solitaire") == @FALSE
 Run("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")
Else
 WinActivate("Solitaire")
Endif

 

Either format is perfectly correct, and the choice of which to use is merely a matter of personal style. The result is exactly the same.

 
EndSession ( )

Ends the current Windows session.

This does exactly what it says. It will not ask any questions (although you will receive any closing messages that your currently-open windows would normally display), so you may want to build in a little safety net:

 

sure = AskYesNo("End Session", "Really quit Windows?")
If sure == @YES Then EndSession( )

 

EndSession is an example of a WIL function which does not take any parameters, as indicated by the empty parentheses which follow it. The parentheses are still required, though.

 

 

 

Files and Directories

 
DirChange (pathname)

Changes the directory to the pathname specified.

Use this function when you want to run a program which must be started from its own directory. "Pathname" may optionally include a drive letter.

Example:

DirChange("c:\windows\winword")
Run("winword.exe", "")

 
DirGet ( )

Gets the current working directory.

This function is especially useful in conjunction with DirChange, to save and then return to the current directory.

Example:

origdir = DirGet( )
DirChange("c:\windows\winword")
Run("winword.exe", "")
DirChange(origdir)

 

FileExist (filename)

Determines if a file exists.

This function will return @TRUE if the specified file exists, and @FALSE if it doesn't exist.

Example:

If FileExist("win.bak") == @FALSE
 FileCopy("win.ini",  "win.bak", @FALSE)
endif
Run("notepad.exe", "win.ini")

 

FileCopy (from-list, to-file, warning)

Copies files.

If warning is @TRUE, WIL will pop up a dialog box warning you if you are about to overwrite an existing file, and giving you an opportunity to change your mind, along with selecting various options for copying the files. If warning is @FALSE, it will overwrite existing files with no warning.

Example:

FileCopy("win.ini", "*.sav", @TRUE)
Run("notepad.exe", "win.ini")

 

The asterisk (*) is a wildcard character, which matches any letter or group of letters in a file name. In this case, it will cause WIN.INI to be copied as WIN.SAV.

 
FileDelete (file-list)

Deletes files.

Example:

If FileExist("win.bak") == @TRUE Then FileDelete("win.bak")

 

FileRename (source-list, destination)

Renames files to another set of names.

We can illustrate the use of these WIL program functions with a typical WIL application. Let's suppose that our word processor saves a backup copy of each document, with a BAK extension, but we want a larger safety net when editing important files. We want to keep the five most recent versions of a document. Here's a WIL program to accomplish this:

 

If FileExist("wil.bak") == @TRUE

 FileDelete("wil.bk5")
 FileRename("wil.bk4", "wil.bk5")
 FileRename("wil.bk3", "wil.bk4")
 FileRename("wil.bk2", "wil.bk3")
 FileRename("wil.bk1", "wil.bk2")
 FileRename("wil.bak", "wil.bk1")

Endif
Run("winword.exe", "wil.doc")
Exit

 

If the file WIL.BAK exists, it means that we have made a change to WIL.DOC. So, before we start editing, we delete the oldest backup copy, and perform several FileRename functions, until eventually WIL.BAK becomes WIL.BK1.

However, what would happen if the file WIL.BK5 didn't exist? In the DOS batch language, we would get an error message, and processing would continue. In the WIL Language, processing of the FileDelete statement is ignored, if the file doesn't exist.

There are two ways that we can handle this. We could use an If FileExist test before every file operation, and test the returned value for a @TRUE before proceeding. But this is clumsy, even with such a small WIL program, and would become unwieldy with a larger one. The other way is by using the ErrorMode function.

 

 

 

Handling Errors

 

The ErrorMode function lets you decide what will happen if an error occurs during WIL processing. Here's the syntax:

 
ErrorMode (mode)

Specifies how to handle errors.

Parameters:

(i) mode  @CANCEL, @NOTIFY, or @OFF.

Returns:

(i) previous error setting.

 

Use this command to control the effects of runtime errors. The default is @CANCEL, meaning the execution of the WIL program will be canceled for any error.

@CANCEL: All runtime errors will cause execution to be canceled. The user will be notified which error occurred.

@NOTIFY: All runtime errors will be reported to the user, and they can choose to continue if it isn't fatal.

@OFF: Minor runtime errors will be suppressed. Moderate and fatal errors will be reported to the user. User has the option of continuing if the error is not fatal.

As you can see, the default mode is @CANCEL, and it's a good idea to leave it like this. However, it is quite reasonable to change the mode for sections of your WIL program where you anticipate errors occurring. This is just what we've done in our modified WIL program:

 

If FileExist("wil.bak") == @TRUE
 ErrorMode(@OFF)   ;turn ErrorMode off
 FileDelete("wil.bk5")
 FileRename("wil.bk4", "wil.bk5)
 FileRename("wil.bk3", "wil.bk4)
 FileRename("wil.bk2", "wil.bk3)
 FileRename("wil.bk1", "wil.bk2)
 FileRename("wil.bak", "wil.bk1)
 ErrorMode(@CANCEL)  ;reset ErrorMode to default

Endif

Run("winword.exe", "wil.doc")
Exit

 

Notice how we've used ErrorMode(@OFF) to prevent errors in the If statement section from aborting the WIL program, and then used ErrorMode(@CANCEL) at the end of the that section to change back to the default error mode. This is a good practice to follow.

Note: Pay close attention when suppressing errors with the ErrorMode function. When an error occurs, the processing of the ENTIRE line is canceled. Setting the ErrorMode( ) to @OFF or @NOTIFY allows execution to resume at the next line. Various parts of the original line may have not been executed.

e.g.

ErrorMode(@OFF)
; The FileCopy will cause a file not found error,
; canceling the execution of the whole line.
; The variable A is set to @FALSE by default
 A = FileCopy( "xxxxxxxxx", "*.*", @FALSE)
;
;
; Now there is a NOT symbol in front of the FileCopy.
; Nonetheless, if an error occurs A is still set to @FALSE
; not @TRUE as might be assumed. When an error is suppressed
; with ErrorMode the line is canceled, and any assignment is
; simply set to the default @FALSE value.
;
 A = !FileCopy("yyyyyyyyy", "*.*", @FALSE)

 

For this reason, ErrorMode( ) must be used with a great deal of care. The function for which the errors are being suppressed should be isolated from other functions and operators as much as possible.

e.g.

; INCORRECT USAGE of ErrorMode( )
; In this instance, when the copy has an error, the entire if
; statement is canceled.
; Execution begins (erroneously) at the next line, and states
; that the copy succeeded. Next a fatal error occurs as the
; "else" is found, since it does not have a matching if

ErrorMode(@OFF)
if FileCopy(file1,file2,@FALSE) == @TRUE 
 Message("Info", "Copy worked")
else
 Message("Error", "Copy failed")
endif

 

; CORRECT USAGE
; In this case, the FileCopy is isolated from other statements
; and flow control logic. When the statement fails, execution
; can safely begin at the next line. The variable "a" will
; contain the default value of zero that a failed assignment
; returns.
; Results are not confused by the presence of other operators.
;
ErrorMode(@OFF)
a = FileCopy(file1,file2,@FALSE)
ErrorMode(@CANCEL)
if a == @TRUE
 Message("Info", "Copy worked")
else
 Message("Error", "Copy failed")
endif

 

 

Debug WIL Scripts

 

Apparently, there have been sightings of bug free code. However, chances are you will need to exterminate at least one of your WIL scripts. Luckily, WIL has a handy debug utility which comes with the WIL Interpreter.

DebugTrace, a WIL function, is invaluable in determining logic errors. When DebugTrace is initialized, a file is created which logs the execution of each statement. DebugTrace works line by line through the script, logging the current statement and its return value.

Initialize DebugTrace by adding DebugTrace(1,"trace.txt") or DebugTrace(@ON,"trace.txt") to a specific point in your script.

Example:

DebugTrace(@ON,"trace.txt")

a=TimeYmdHms( )

b=TimeJulianDay(a)

c=(b+5) mod 7

day=ItemExtract(c+1, "Sun Mon Tue Wed Thu Fri Sat", " ")

line=StrCat("Julian Date= ",b,@CRLF,"Day of week= ",day)

Message(TimeDate( ), line)

 

 

Selection Methods

 

So far, whenever we have needed to use a file name, we've hard-coded it into our WIL programs. For example:

Run("notepad.exe", "agenda.txt")

 

Naturally, there should be a way to get this information from the user "on the fly", so that we wouldn't have to write hundreds of different WIL programs. And there is a way. Three or four ways, actually. Consider, first, a function that we have already seen, AskLine:

file = AskLine("", "Enter Filename to edit?", "", 0)
Run("notepad.exe", file)

 

This will prompt for a filename, and run Notepad on that file:

 

image\tutbut11_shg.gif

There are only three problems with this approach. First, the user might not remember the name of the file. Second, the user might enter the name incorrectly. And finally, modern software is supposed to be sophisticated and user-friendly enough to handle these things the right way. And WIL certainly can.

There are several functions we can use for an improved file selection routine.

 

FileItemize (file-list)

Returns a delimited list of files.

This function compiles a list of filenames and separates the names with a delimiter. There are several variations we can use:

FileItemize("*.doc")

 

would give us a list of all files in the current directory with a DOC extension,

FileItemize("*.com *.exe")

 

would give us a list of all files in the current directory with a COM or EXE extension, and

FileItemize("*.*")

 

would give us a list of all files in the current directory.

Of course, we need to be able to use this list, and for that we have:

 
AskItemList (title, list, delimiter, sort mode, select mode [, selection-required] )

Displays a list box filled with items from a list you specify in a string. The items are separated in your string by a delimiter.

This is the function which actually displays the list box. Remember that FileItemize returns a file list delimited by a character. If the delimiter is a TAB, the list will look something like this:

FILE1.DOC{TAB}FILE2.DOC{TAB}FILE3.DOC

 

When we use AskItemList, we need to tell it that the delimiter is a TAB. We do this as follows:

files = FileItemize("*.doc|*.txt")
afile = AskItemList("Select File to edit", files, @TAB,@unsorted, @single, @false)
Run("notepad.exe", afile)

 

which produces:

image\tutbut12_shg.gif

 

First, we use FileItemize to build a list of filenames with DOC and TXT extensions. We assign this list to the variable files. Then, we use the AskItemList function to build a list box, passing it the variable files as its second parameter. The third parameter we use for AskItemList is simply a space with quote marks around it; this tells AskItemList that the list in variable files is delimited by spaces. (Note that this is different from the null string that we've seen earlier - here, you must include a space between the quote marks.) Using the fourth parameter set the sort mode to choose how to display the text, sorted or unsorted. The fifth parameter sets the select mode allowing you to choose a single item or multiple items from the list. Finally, we assign the value returned by AskItemList to the variable afile, and run Notepad using that file.

In the list box, if the user presses Enter or clicks on the OK button without a file being highlighted, AskItemList returns a null string. If you want, you can test for this condition:

 

IntControl(29, " ", 0, 0, 0)

files = FileItemize("*.doc *.txt")
while @TRUE
 afile = AskItemList("Select File to edit", files, " ",         @unsorted, @single, @false)
 If afile != "" Then break

 ;break terminates the While structure transferring control to the  ;statement following the endwhile.
endwhile
Run("notepad.exe", afile)

 
DirItemize (dir-list)

Returns a delimited list of directories.

This function is similar to FileItemize, but instead of returning a list of files, it returns a list of directories. Remember we said that FileItemize only lists files in the current directory. Often, we want to be able to use files in other directories as well. One way we can do this by first letting the user select the appropriate directory, using the DirItemize and AskItemList combination:

IntControl(29, " ", 0, 0, 0)
DirChange("C:\")
subdirs = DirItemize("*.*")
targdir = AskItemList("Select dir", subdirs, " ", @sorted, @single,@false)
if targdir != "" then DirChange(targdir)
files = FileItemize("*.*")
afile = AskItemList("Select File", files, " ", @sorted, @single, @false)
Run("notepad.exe", afile)

 

First we change to the root directory. Then we use DirItemize to get a list of all the sub-directories off of the root directory. Next, we use AskItemList to give us a list box of directories from which to select. Finally, we change to the selected directory, and use FileItemize and AskItemList to pick a file.

Although this WIL program works, it needs to be polished up a bit. What happens if the file we want is in the \WINDOWS\BATCH directory? Our WIL program doesn't go more than one level deep from the root directory. We want to continue down the directory tree, but we also need a way of telling when we're at the end of a branch. As it happens, there is such a way: DirItemize will return a null string if there are no directories to process. Given this knowledge, we can improve our file selection logic:

IntControl(29, " ", 0, 0, 0)
DirChange("C:\")
; Directory selection loop
while @TRUE   ; Loop forever til break do us part
 dirs = DirItemize("*")
 If dirs == "" Then break
 targ = AskItemList("Select dir", dirs, " ", @sorted, @single, @false)
 If targ == "" Then break
 DirChange(targ)
endwhile
;
; File selection loop
while @TRUE   ; Loop forever til break do us part
 files = FileItemize("*.*")
 afile = AskItemList("Select File", files, " ", @sorted, @single, @false)
 If afile != "" Then break
endwhile
Run("notepad.exe", afile)

 

First of all, we set up a repeating while loop. The "While @TRUE" will repeat the loop forever. In the loop itself we use the break statement to exit the loop. After we use the DirItemize function to try to get a list of the directories at the current level, we test the returned value for a null string. If we have a null string, then we know that the current directory has no sub-directories, and so we proceed to the file selection logic by breaking out of the directory selection loop. If, however, DirItemize returns a non-blank list, then we know that there is, in fact, at least one sub-directory. In that case, we use AskItemList to present the user with a list box of directories. Then, we test the value returned by AskItemList. If the returned value is a null string, it means that the user did not select a directory from the list, and presumably wants a file in the current directory. We happily oblige by breaking out of the directory selection loop. On the other hand, a non-blank value returned by AskItemList indicates that the user has selected a sub-directory from the list box. In that case, we change to the selected directory, and the endwhile causes the directory selection loop to be repeated. We continue this process until either (a) the user selects a directory, or (b) there are no directories left to select. Eventually, we move to the file selection loop.

 
Nicer File Selection

The function AskFileName is the equivalent of a standard Common Dialog FileOpen or a FileSave dialog box.

An even more elegant way of selecting a file name is provided by the Dialog Editor, which also allows the user to select various options via check boxes and radio buttons from a custom designed dialog box. The Dialog Editor is installed in the directory with the Winbatch.exe.

 
Nicer Messages

Have you tried displaying long messages, and found that WIL didn't wrap the lines quite the way you wanted? Here are a couple of tricks.

§         @CRLF

§         @TAB

 

@CRLF and @TAB are string constants containing, respectively, a carriage-return line-feed pair and a tab character.

We want to be able to insert a carriage return/line feed combination at the end of each line in our output, and the @CRLF string constant will let us do that.. For example, let's say we want to do this:

Message("", "This is line one This is line two")

 

If we just inserted the variables into the string, as in:

Message("", "This is line one %@crlf% This is line two")

 

we would not get the desired effect. WIL would simply treat it as ordinary text:

 

image\tutbut13_shg.gif

 

However, WIL does provide us with a method of performing variable and string constant substitution such as this, and that is by delimiting the variables or string constants with percentage signs (%). If we do this:

Message("", "This is line one%@crlf%This is line two")

 

we will get what we want:

image\tutbut14_shg.gif

 

Note that there is no space after %@crlf%; this is so that the second line will be aligned with the first line (every space within the delimiting quote marks of a string variable is significant).

 

 

Running DOS Programs

 

WIL can run DOS programs, just like it runs Windows programs:

DirChange("c:\game")
Run("scramble.exe", "")

 

If you want to use an internal DOS command, such as DIR or TYPE, you can do so by running the DOS command interpreter, COMMAND.COM, with the /c program parameter, as follows:

Run("command.com", "/c type readme.txt")

 

Everything that you would normally type on the DOS command line goes after the /c in the second parameter. Here's another example:

Run("command.com", "/c type readme.txt | more")

 

These examples assume that COMMAND.COM is in a directory on your DOS path. If it isn't, you could specify a full path name for it:

Run("c:\command.com", "/c type readme.txt | more")

 

Or, better still, you could use the WIL Environment function.

 
Environment (env-variable)

Gets a DOS environment variable.

Since DOS always stores the full path and filename of the command processor in the DOS environment variable COMSPEC, it is an easy matter to retrieve this information:

coms = Environment("COMSPEC")

 

and use it in our WIL program:

coms = Environment("COMSPEC")
Run(coms, "/c type readme.txt")

 

To get a DOS window, just run COMMAND.COM with no parameters:

coms = Environment("COMSPEC")
Run(coms, "")

 

 

Sending Keystrokes to Programs

 

Here we come to one of the most useful and powerful features of WIL the ability to send keystrokes to your programs, just as if you were typing them directly from the keyboard.

SendKeysTo (parent windowname, sendkey string)

Activates the specified window and sends keystrokes to it.

This is an ideal way to make the computer automatically type the keystrokes that you enter every time you start a certain program. For example, to start up Notepad and have it prompt you for a file to open, you would use:

Run("notepad.exe", "")
SendKeysTo("~Notepad", "!fo")

 

The parameters you specify for SendKeysTo are the window-name (or at least the first unique part of it), and the string that you want sent to the program. This string consists of standard characters, as well as some special characters which you will find listed under the entry for SendKey in the WIL Function Reference (see SendKey). In the example above, the exclamation mark (!) stands for the Alt key, so !f is the equivalent of pressing and holding down the Alt key while simultaneously pressing the F key. The o in the example above is simply the letter O, and is the same as pressing the O key by itself:

image\tutbut15_shg.gif

 

Here's another example:

RunZoom("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")
SendKeysTo("Solitaire", "!gc{RIGHT}{SP}~")

 

This starts up Solitaire, brings up the Game menu (!g), and selects Deck (c) from that menu:

image\tutbut16_shg.gif

 

Then it moves the cursor to the next card back style on the right ({RIGHT}), selects that card back ({SP}), and then selects OK (~). (The tilde sign (~) is SendKey shorthand for the enter key.

image\tutbut17_shg.gif

 

And walla! A different card design every time you play!

 

 

Our Completed WIL File

 

Here is the final working version of the WIL program that we've slowly been building throughout this tutorial.

It incorporates many of the concepts that we've discussed so far, as well as using some arithmetic (*, -, ) and relational (<) operators that are covered in the section on Operators.

It can also be improved and customized in a number of ways, but we'll leave that up to you.

If you can understand and follow the structures and processes illustrated in this sample file, and can begin to incorporate them into your own WIL programs, you are well on your way to becoming a true WIL guru!

; tutor.wbt
mins = AskLine("Solitaire", "How many mins do you want to play?", "", 0)
mins = Int(mins)

Switch mins
case 0
 Display(5, "", "Game canceled")
 exit
 break
case 1
 Message("Only a minute?", "Wow! You've got willpower.")
 break
case 2
 Message("2 Minutes?", "This isn't much of a break.")
 break
case 3
 Message("3 Minutes?", "You're barely got time to shuffle")
 break

case 4
 Message("HA,HA,HA", "I dare you to try to beat me.")
 break
case mins ;default case - must be last in the switch
 Message("THAT LONG!!!", "Where did you get all that time?")
 break 

EndSwitch

 

    ;;ADDED to demonstrate checking for the existence of a program

    ;;before running a second occurrence.

 

If WinExist("Solitaire") == @TRUE
WinActivate("Solitaire")
 WinShow("Solitaire")
Else
Run
("C:\Program Files\Microsoft Games\Solitaire\Solitaire.exe", "")
Endif

for i = 0 to 9
 j=100-i*10
 k=300+i*70
 WinPlace(j,j,k,k,"Solitaire")
next

WinZoom("Solitaire")

    ;;ADDED to show an example of sending keystrokes.

 

SendKeysTo("Solitaire", "!gc{RIGHT}{SP}~")

GoSub dumdedum

mins=AskLine("More Time?", "Enter additional minutes", 0, 0)
If mins!=0 then GoSub dumdedum

      ;;ADDED as an example of a while loop.

 

while WinExist("Solitaire")
 WinClose("Solitaire")  ;Make sure it closes
endwhile
Message("Time's Up", "Get Back to Work!")

Exit

 

:dumdedum
goal = mins * 60
timer = 0
While timer < goal
 remain = goal - timer
 if WinExist("Solitaire")
  WinTitle("Solitaire", "Solitaire (%remain% seconds left)")
 else
  exit
 endif
 TimeDelay(10)
 timer = timer + 10
EndWhile
Return