WinBatch User's Manual For IBM PC/XT, PC/AT, PS/2 and compatibles Wilson WindowWare 2701 California Ave SW ste 212 Seattle, WA 98116 Orders: (800) 762-8383 Support: (206) 937-9335 Fax: (206) 935-7129 Copyright 1988-1991 by Morrie Wilson. All rights reserved. No part of this manual may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying and recording, for any purpose without the express written permission of Wilson WindowWare, Inc. Information in this document is subject to change without notice and does not represent a commitment by Wilson WindowWare, Inc. The software described herein is furnished under a license agreement. It is against the law to copy this software under any circumstances except as provided by the license agreement. U.S. Government Restricted Rights Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subdivision (b)(3)(ii) of the Rights in Technical Data and Computer Software clause at 252.227-7013. Contractor/manufacturer is Wilson WindowWare, Inc./2701 California Ave SW /ste 212/Seattle, WA 98116 Trademarks IBM, PC/XT, PC/AT, and PS/2 are registered trademarks of International Business Machines Corporation. Microsoft and MS-DOS are registered trademarks of Microsoft Corporation. Windows, Word for Windows, and Excel are trademarks of Microsoft Corporation. Scramble is a trademark of Diana Gruber. Command Post, WinBatch, and WinEdit are trademarks of Wilson WindowWare, Inc. ii CONTENTS CONTENTS CONTENTS iii INTRODUCTION viii System Requirements viii About This Manual viii Notational Conventions ix Acknowledgements ix GETTING STARTED 1 TUTORIAL 2 WinBatch Basics 2 What is a Batch File? 2 Our First WinBatch File 2 Functions and Parameters 3 Displaying Text 5 Getting Input 6 Using Variables 7 Making Decisions 8 Branching 10 Exploring WinBatch 12 Running Programs 12 Display and Input 13 Manipulating Windows 15 Files and Directories 19 Handling Errors 21 Selection Menus 23 Nicer Display Boxes 26 Even Nicer Display Boxes 28 Running DOS Programs 28 Sending Keystrokes to Programs 29 Our Completed WinBatch File 30 DIALOG BOXES 31 WinMacro 39 Starting WinMacro 39 Macro Definition Files 39 Hotkeys 40 Recording Keystrokes 41 WinMacro Example 42 WBM files 42 Unrecordable Areas 43 WINBATCH LANGUAGE 44 iii CONTENTS Language Components 44 Constants 44 Identifiers 45 Variables 45 Keywords 46 Operators 46 Precedence and evaluation order 47 Comments 47 Statements 48 Substitution 48 Function Parameters 49 Command-Line Parameters 49 Error Handling 50 The Functions & Statements 51 Inputting Information 51 Displaying Information 51 File Management 52 Directory Management 53 Disk Drive Management 54 Window Management 54 Program Management 56 String Handling 56 Arithmetic Functions 58 Clipboard Handling 58 System Control 58 WBL FUNCTION REFERENCE 62 Introduction 62 Abs 63 AskLine 63 AskYesNo 64 Average 65 Beep 65 Call 66 CallExt 67 Char2Num 68 ClipAppend 69 ClipGet 70 ClipPut 70 DateTime 71 Debug 72 Delay 73 DialogBox 74 DirChange 75 DirGet 76 DirHome 77 DirItemize 77 DirMake 78 iv CONTENTS DirRemove 79 DirRename 79 DiskFree 80 Display 81 DOSVersion 81 Drop 82 EndSession 83 Environment 83 ErrorMode 84 Execute 85 Exit 86 Exclusive 86 FileAppend 87 FileClose 88 FileCopy 89 FileDelete 90 FileExist 90 FileExtension 91 FileItemize 92 FileLocate 93 FileMove 94 FileOpen 95 FilePath 96 FileRead 96 FileRename 97 FileRoot 98 FileSize 99 FileWrite 99 Goto 100 If...Then 101 IgnoreInput 101 IniRead 102 IniReadPvt 103 IniWrite 104 IniWritePvt 104 IsDefined 105 IsKeyDown 106 IsLicensed 106 IsNumber 107 ItemCount 108 ItemExtract 108 ItemSelect 109 LastError 110 LogDisk 111 Max 112 Message 112 Min 113 Num2Char 114 v CONTENTS ParseData 114 Pause 115 Random 116 Return 117 Run 117 RunHide 118 RunIcon 119 RunZoom 120 SendKey 121 SKDebug 123 StrCat 124 StrCmp 125 StrFill 126 StrFix 127 StriCmp 127 StrIndex 128 StrLen 129 StrLower 130 StrReplace 130 StrScan 131 StrSub 132 StrTrim 133 StrUpper 134 TextBox 134 Version 135 WallPaper 136 WinActivate 136 WinArrange 137 WinClose 138 WinCloseNot 139 WinConfig 139 WinExist 140 WinGetActive 141 WinHide 142 WinIconize 142 WinItemize 143 WinPlace 144 WinPosition 145 WinShow 146 WinTitle 147 WinVersion 148 WinWaitClose 149 WinZoom 150 Yield 150 APPENDIX A Predefined Constants 152 APPENDIX B Errors 153 vi CONTENTS Minor Errors 153 Moderate Errors 154 Fatal Errors 155 Index 157 vii INTRODUCTION INTRODUCTION WinBatch brings the power of batch language programming to the Windows environment. Although WinBatch can do everything that the familiar DOS batch language can do, the capabilities of WinBatch begin where the DOS batch language leaves off. With more than a hundred functions and commands, WinBatch can: * Run Windows and DOS programs. * Send keystrokes directly to applications. * Rearrange, resize, hide, and close windows. * Run programs either concurrently or sequentially. * Display information to the user in various formats. * Prompt the user for any needed input. * Present scrollable file and directory lists. * Copy, move, delete, and rename files. * Read and write files directly. * Copy text to and from the Clipboard. * Perform string and arithmetic operations. * Make branching decisions based upon numerous factors. And much, much more. Whether you are creating batch files for others, or looking for a way to automate your own work and eliminate the drudgery of repetitive tasks, you will find WinBatch to be a powerful, versatile, and easy- to-use tool. System Requirements WinBatch requires an IBM PC or compatible with a minimum of 640K memory running Microsoft Windows version 3.0 or higher. About This Manual This manual is divided into six sections: First is Getting Started (pg. 1), where we tell you how to install the program. Then we offer an extensive Tutorial (pg. 2), to get both beginning and advanced users quickly up to speed with creating WinBatch files, followed by separate sections on Dialog Boxes (pg. 31) and WinMacro (pg. 39). Then we describe the different elements of the WinBatch Language (WBL) viii INTRODUCTION (pg. 44). Finally, there is a comprehensive WBL Function Reference (pg. 62), which contains detailed information on each of the WinBatch functions and commands. Notational Conventions Throughout this manual, we use the following conventions to distinguish elements of text: ALL-CAPS Used for filenames. Boldface Used for important points, programs, function names, and parts of syntax that must appear as shown. system Used for menu items as they appear to the user. Small fixed-width Used for batch file sample code. Italics Used for emphasis, and to liven up the dull software documentation just a little. Acknowledgements WinBatch designed and written by Morrie Wilson. User's Manual designed by Richard Merit, written by Richard Merit and Morrie Wilson. Our thanks to the many beta-testers for their invaluable comments and suggestions. ix GETTING STARTED GETTING STARTED WinBatch is quite easy to install. You will find an appropriate diskette in your WinBatch package. Take the diskette and insert it into your floppy drive. The WinBatch installation program is itself a Windows application, so make sure Windows is running. From the Program Manager, doubleclick on the File Manager icon to run it. When File Manager starts, click on the A: or B: drive icon, depending on which floppy drive you used. A directory tree will appear for the WinBatch diskette. You should see a root directory icon. Doubleclick on this icon and a list of filenames will appear. Find the filename SETUP.EXE and doubleclick on it. Follow whatever instructions Setup gives you. Setup will create the necessary files and place them into a directory it will prompt you for. 1 TUTORIAL TUTORIAL WinBatch Basics What is a Batch File? A batch file, whether a DOS batch file or a WinBatch 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 many commands or even a single complex command, is a candidate for a batch file. 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. WinBatch files work basically the same way. Our First WinBatch File Our first Winbatch file will simply run our favorite Windows application: Solitaire. First, start up Notepad, or any other editor 2 TUTORIAL which is capable of saving text in pure ASCII format (may we suggest WinEdit, from Wilson WindowWare). Enter the following line of text: Run("sol.exe", "") Save the file with the name SOLITARE.WBT. Now, run SOLITARE.WBT by starting or switching to the File Manager (or MS-DOS Executive), and either moving the cursor to the file name and pressing Enter, or double-clicking on the file name with your mouse. Presto! It's Solitaire. Okay, that wasn't really so impressive. But it did serve to illustrate several important WinBatch points. They are: 1. WinBatch files must be edited and saved in ASCII format. 2. WinBatch files should be given a WBT extension. When WinBatch is first installed, it creates an entry in your WIN.INI file which causes files with a WBT extension to be associated with WinBatch. As long as WINBATCH.EXE is located in your DOS path, you can place WBT files in any directory and run them by simply selecting them, as we did above. 3. After you have created a WBT file, you run it by moving your cursor to it and pressing Enter, or double-clicking on it with your mouse (you can also add a WBT file to a program group and run it using the Program Manager; see your Windows manual for further information). Whatever method you use, we'll use the term Run to refer to selecting and running the file. Functions and Parameters Now, let's look more closely at the line we entered: Run("sol.exe", "") The first part, Run, is a WinBatch function. As you might have guessed, its purpose is to run a Windows program. There are over a hundred different functions and commands in WinBatch, and each has a certain syntax which must be used. The correct syntax for all WinBatch functions may be found in the WBL Function Reference (pg. 62). The entry for Run starts off as follows: Syntax: Run (program-name, parameters) 3 TUTORIAL Parameters: "program-name" = the name of the desired .EXE, .COM, .PIF, .BAT file, or a data file. "parameters" = optional parameters as required by the application. Like all WinBatch functions, Run is followed by a number of parameters, enclosed in parentheses. Parameters are simply additional 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 parameters to be passed to the program. WinBatch functions use several types of parameters. Multiple parameters are separated by commas. In the example Run("sol.exe", "") "sol.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 manual will use double quotes. 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 WBL Function Reference describes the second parameter -- "parameters" -- as being optional. Which is correct? Well, from a language standpoint, the second parameter is required. That is, if you omit it, you will get a syntax error, and your batch file will not run properly. However, the program that you are running may not need any parameters. Solitaire, for example, does not take any parameters. The way we handle this in our batch file 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. To illustrate this further, let's create a WinBatch file called EDIT.WBT, 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. You should now be in Notepad. Now edit the EDIT.WBT file as follows: 4 TUTORIAL Run("notepad.exe", "solitare.wbt") Save the file, exit Notepad, and run EDIT.WBT again. You should now be in Notepad, with SOLITARE.WBT 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 WinBatch. Before you leave Notepad, modify EDIT.WBT as follows: ; This is an example of the Run function in WinBatch Run("notepad.exe", "solitare.wbt") The semicolon 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 WinBatch files. In addition, you can place a comment on the same line as a function by preceding the comment with a semicolon. For example: Run("sol.exe", "") ; this is a very useful function Everything to the right of a semicolon is ignored. However, if a semicolon appears in a string delimited by quotes, it is treated as part of the string. Displaying Text Now, let's modify our SOLITARE.WBT file as follows. You might as well use the EDIT.WBT batch file you created earlier to start up Notepad: ; solitare.wbt Display(5, "Good Luck!", "Remember ... it's only a game.") Run("sol.exe", "") And run it. Notice the message box which pops up on the screen with words of encouragement. That's done by the Display function in the second line above. Here's the reference for Display: Syntax: Display (seconds, title, text) Parameters: seconds = integer seconds to display the message (1-15). "title" = Title of the window to be displayed. 5 TUTORIAL "text" = Text of the window to be displayed. Note that the Display function has three parameters. The first parameter -- in our example, 5 -- 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 WinBatch will automatically try to convert string variables to numeric variables when necessary, and vice versa). The second parameter is the title of the message box, and the third parameter is the actual text displayed in the box. Now, exit Solitaire (if you haven't already done so), and edit SOLITARE.WBT by placing a semicolon at the beginning of the line with the Run function. This is a handy way to disable, or "comment out," lines in your WinBatch files when you want to modify and test only certain segments. Your SOLITARE.WBT file should look like this: ; solitare.wbt Display(5, "Good Luck!", "Remember ... it's only a game.") ; Run("sol.exe", "") Now, experiment with modifying the parameters in the Display function. Try adjusting the value of the first parameter. If you look up Display in the WBL reference section, you will see that the acceptable values for this parameter are 1-15. If you use a value outside this range, WinBatch 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 15 as 15. Experiment. Also, try using a non-integer value, such as 2.5, and see what happens. 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 WinBatch function called AskYesNo: Syntax: AskYesNo (title, question) Parameters "title" = title of the question box. "question" = question to be put to the user. 6 TUTORIAL Returns: (integer) @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 (indicated by the quote marks), and tells us what each of the parameters means. You will notice that there is also a new section here, titled 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). We also see that the integer value returned by AskYesNo is either @YES or @NO. @YES and @NO are predefined constants in WinBatch. All predefined constants begin with an @ symbol, and we will distinguish them further by typing them in all caps. You will find a list of all predefined constants in Appendix A (pg. 152). 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 don't need to remember it). Now, let's modify our SOLITARE.WBT file as follows: AskYesNo("Really?", "Play Solitaire now?") Run("sol.exe", "") and run it. You should have gotten a nice dialog box which asked if you wanted to play Solitaire, 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 X+X=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 X+X is now equal to 8. 7 TUTORIAL 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 batch file. First, we need to give this variable a name. In WinBatch, 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 typing them in all lowercase letters; we will type function and command names starting with a capital letter. However, in WinBatch, the case is not significant, so you can use all lowercase, or all uppercase, or whatever combination you prefer). 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 WinBatch processes this line is to first evaluate the result of the AskYesNo function. The function returns a value of either @YES or @NO. Then, WinBatch 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 WinBatch provides a way to conditionally execute a statement, and that is by using the If ... Then command. Actually, there are two separate parts to this construct: If and Then. The format is: If condition Then statement (We refer to If ... Then as a command, rather than a function, because functions are followed by parameters in parentheses, while commands are not. Commands are used for system control.) The use of If ... Then can easily be illustrated by going back to our SOLITARE.WBT file, and making these modifications: response = AskYesNo("Really?", "Play Solitaire now?") If response == @YES Then Run("sol.exe", "") 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, then the statement following the Then keyword is 8 TUTORIAL performed. If the condition following the If keyword is false, then anything following the Then keyword is ignored. There is something extremely important that you should note about the syntax of the If ... Then command: the double equal signs (==). In WinBatch, 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("sol.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 WinBatch. The statement above is saying, in English: "If the value of the variable named response is equal to @YES, then run the program SOL.EXE." If you used a single equal sign (=) here by mistake, you would get an error message, which is WinBatch'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 WinBatch files, 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 condition following the Then keyword is true. But what happens when it is false? Remember we said that when the If condition is false, the Then statement is 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 Then Run("sol.exe", "") If response == @NO Then Display(5, "", "Game canceled") In this case there are two If statements being evaluated, with one and only one of them possibly being true (unless the user selects Cancel, which would abort the batch file entirely). However, this is 9 TUTORIAL inefficient from a processing standpoint. Furthermore, 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("sol.exe", "") Clearly, there must be a better way of handling this. Branching Enter the Goto command. Goto, in combination with If ... Then, gives you the ability to redirect the flow of control in your WinBatch files. Goto does exactly what it says -- it causes the flow of control to go to another point in the batch file. You must specify where you want the flow of control to be transferred, and you must mark this point with a label. A label is simply a destination address, or marker. The form of the Goto command is: Goto label where label is an identifier that you specify. The same rules apply to label names as to variable names (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 from 1 to 30 characters long). In addition, the label is preceded by a colon (:) at the point where it is being used as a destination address. Here's an example: response = AskYesNo("Really?", "Play Solitaire now?") If response == @NO Then Goto quit Display(5, "", "On your mark ...") Display(5, "", "Get set ...") Display(5, "", "Go!") Run("sol.exe", "") :quit If the If condition is true (that is, if the user answers No), then the Goto statement is performed. The Goto statement is saying, in English "go to the line marked :quit, and continue processing from there." Notice how the label quit is preceded by a colon on the last line, but not on the line where it follows the Goto keyword. This is important. Although you can have multiple lines in your batch file which say Goto quit, you can have only one line marked :quit (just like you can have several people going to your house, but can have 10 TUTORIAL only one house with a particular address). Of course, you can use many different labels in a batch file, just as you can use many different variables, as long as each has a unique name. For example: response = AskYesNo("Really?", "Play Solitaire now?") If response == @NO Then Goto quit Display(5, "", "On your mark ...") Display(5, "", "Get set ...") Display(5, "", "Go!") Run("sol.exe", "") Goto done :quit Display(5, "", "Game canceled") :done This is a little more complicated. It uses two labels, quit and done. If the user answers No, then the If condition is true, control passes to the line marked :quit, and a message is displayed. If, on the other hand, the user answers Yes, then the If condition is false, and the Goto quit line is ignored. Instead, the next four lines are processed, and then the Goto done statement is performed. The purpose of this line is to bypass the Display line which follows, by transferring control to the end of the batch file. There is another way to keep your batch file processing from "falling through" to unwanted lines at the end of a program, and that is with the Exit command. Exit causes a batch file to end immediately. So, for example, we could rewrite the above batch file as follows: response = AskYesNo("Really?", "Play Solitaire now?") If response == @NO Then Goto quit Display(5, "", "On your mark ...") Display(5, "", "Get set ...") Display(5, "", "Go!") Run("sol.exe", "") Exit :quit Display(5, "", "Game canceled") Since the Run function is the last thing we want to do if the user answers Yes, the Exit command simply ends the program at that point. Note that we could put an Exit command at the end of the program as well, but it isn't necessary. An Exit is implied at the end of a WinBatch program. This concludes the first part of our tutorial. You now have the building blocks you need to create useful WinBatch files. In the second part, which follows, we will look in more detail at some of the WinBatch functions which are available for your use. 11 TUTORIAL Exploring WinBatch What follows is just a sample of the many functions and commands available in WinBatch. These should be sufficient to begin creating versatile and powerful batch files. For complete information on these and all WinBatch functions and commands, refer to the WBL Function Reference (pg. 62). Running Programs There are three functions which you can use to start an application, each of which shares a common syntax: Run (program-name, parameters) We've already seen the Run function. This function starts a program in a "normal" window. Windows 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, WinBatch looks first in the current directory, and then in the directories on your DOS path. If the file is not found, WinBatch will return an error. You can also specify a full path name for WinBatch to use, as in: Run("c:\windows\apps\winedit.exe", "") RunZoom (program-name, parameters) RunZoom is like Run, but starts a program as a full-screen window. 12 TUTORIAL Example: RunZoom("excel", "bigsheet.xls") RunIcon (program-name, parameters) RunIcon starts a program as an icon at the bottom of the screen. Example: RunIcon("clock", "") 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, "", "Loading Solitaire now") 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") 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 batch file exits. 13 TUTORIAL Example: Pause("Delete Backups", "Last chance to stop!") ; if batch file gets this far, the user pressed OK FileDelete("*.bak") 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 selects the Cancel button, the batch file is terminated. Example: response = AskYesNo("End Session", "Really quit Windows?") AskLine (title, prompt, default) 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") Run("notepad", yourfile) 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 14 TUTORIAL Delay (seconds) Pauses batch file execution. The Delay function lets you suspend batch file processing for 1 to 15 seconds. You can use multiple occurrences for a longer delay: Delay(15) Delay(15) Will insert a 30-second pause. 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 15 TUTORIAL 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: You probably don't want to have to hard-code this entire name into your batch file as: WinZoom("Notepad - SOLITARE.WBT") Instead, you can specify the partial windowname "Notepad": WinZoom("Notepad") If you have more than one Notepad window open, WinBatch will use the one which was most recently used or started. Note that WinBatch 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. 16 TUTORIAL 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. WinCloseNot (partial-windowname[, partial-windowname]...) Closes all application windows except those specified. This function lets you close all windows except the one(s) you want to remain open. For example: WinCloseNot("Program Man") would leave only the Program Manager open, and: WinCloseNot("Program Man", "Solit") would leave the Program Manager and Solitaire windows open. WinWaitClose (partial-windowname) Waits until an application window is closed. This function causes your WinBatch file to pause until you have manually closed a specified window. This is a convenient way to get WinBatch to open several windows sequentially, thereby not having unnecessary windows all over your desktop. For example: RunZoom("invoices.xls", "") ;balance the books WinWaitClose("Microsoft Ex") ;wait till Excel closed RunZoom("sol", "") ;you deserve a break WinWaitClose("Solitaire") ;wait until Solit closed Run("winword", "agenda.doc") ;more paperwork WinWaitClose("Microsoft Wor") ;wait until W4W closed Run("clock","") ;lunchtime yet? During the time that the batch file is suspended, the WinBatch icon will remain at the bottom of your screen. You can cancel the batch file at any time by selecting Terminate from the icon's control menu. WinExist (partial-windowname) Tells if a window exists. 17 TUTORIAL 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 SOLITARE.WBT file. First, trim out the excess lines so that it looks like this: Run("sol.exe", "") Now, let's use the WinExist function to make sure that WinBatch only starts Solitaire if it isn't already running: If WinExist("Solitaire") == @FALSE Then Run("sol.exe", "") And this should work fine. Run SOLITARE.WBT 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 batch file 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, along with a couple of Goto statements: If WinExist("Solitaire") == @FALSE Then Goto open WinActivate("Solitaire") Goto loaded :open Run("sol.exe", "") :loaded Note that we can change this to have WinExist check for a True value instead, by modifying the structure of the batch file: If WinExist("Solitaire") == @TRUE Then Goto activate Run("sol.exe", "") Goto loaded :activate WinActivate("Solitaire") :loaded 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. 18 TUTORIAL 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 WinBatch 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 when used 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) 19 TUTORIAL 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 Then FileCopy("win.ini", "win.bak", @FALSE) Run("notepad.exe", "win.ini") FileCopy (from-list, to-file, warning) Copies files. If warning is @TRUE, WinEdit 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. If warning is @FALSE, it will overwrite existing files with no warning. Example: FileCopy("cmdpost.cpm", "*.sav", @TRUE) Run("notepad.exe", "cmdpost.cpm") The asterisk (*) is a wildcard character, which matches any letter or group of letters in a file name. In this case, it will cause CMDPOST.CPM to be copied as CMDPOST.SAV. FileDelete (file-list) Deletes files. Example: If FileExist("win.bak") == @TRUE Then FileDelete("win.bak") FileRename (from-list, to-file) Renames files to another set of names. We can illustrate the use of these WinBatch file functions with a typical batch file application. Let's suppose that our word processor 20 TUTORIAL 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 the wonderful software manual we're writing. Here's a WinBatch file to accomplish this: If FileExist("winbatch.bak") == @TRUE Then Goto backup :edit Run("winword.exe", "winbatch.doc") Exit :backup FileDelete("winbatch.bk5") FileRename("winbatch.bk4", "winbatch.bk5) FileRename("winbatch.bk3", "winbatch.bk4) FileRename("winbatch.bk2", "winbatch.bk3) FileRename("winbatch.bk1", "winbatch.bk2) FileRename("winbatch.bak", "winbatch.bk1) Goto edit If the file WINBATCH.BAK exists, it means that we have made a change to WINBATCH.DOC. So, before we start editing, we delete the oldest backup copy, and perform several FileRename functions, until eventually WINBATCH.BAK becomes WINBATCH.BK1. Notice how the flow of control moves to the line labeled :backup, and then back to the line labeled :edit, and how we terminate processing with the Exit command. If we did not include the Exit command, the batch file would continue in an endless loop. However, this still isn't quite right. What would happen if the file WINBATCH.BK5 didn't exist? In the DOS batch language, we would get an error message, and processing would continue. But in WinBatch, the error would be fatal, and cause the batch file to abort. 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 batch file, and would become unwieldy with a larger one. Handling Errors Luckily, there is a WinBatch system function to help us here: ErrorMode. The ErrorMode function determines what happens if an error occurs during batch file processing. Here's the syntax: ErrorMode (mode) Specifies how to handle errors. 21 TUTORIAL Parameters: "mode" = @CANCEL, @NOTIFY, or @OFF. Returns: (integer) previous error setting. Use this command to control the effects of runtime errors. The default is @CANCEL, meaning the execution of the batch file 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 batch files where you anticipate errors occurring. This is just what we've done in our modified batch file: If FileExist("winbatch.bak") == @TRUE Then Goto backup :edit Run("winword.exe", "winbatch.doc") Exit :backup ErrorMode(@OFF) FileDelete("winbatch.bk5") FileRename("winbatch.bk4", "winbatch.bk5) FileRename("winbatch.bk3", "winbatch.bk4) FileRename("winbatch.bk2", "winbatch.bk3) FileRename("winbatch.bk1", "winbatch.bk2) FileRename("winbatch.bak", "winbatch.bk1) ErrorMode(@CANCEL) Goto edit Notice how we've used ErrorMode(@OFF) to prevent errors in the section labeled backup: from aborting the batch file, 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. 22 TUTORIAL Selection Menus So far, whenever we have needed to use a file name, we have hard-coded it into our WinBatch files. 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 batch files. And there is a way. Two ways, actually. Consider, first, a function that we have already seen, AskLine: file = AskLine("", "Enter Filename to edit?", "") Run("notepad.exe", file) This will prompt for a filename, and run Notepad on that file. 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 WinBatch certainly can. There are two new functions we need to use for our new, improved file selection routine: FileItemize and ItemSelect. FileItemize (file-list) Returns a space-delimited list of files. This function compiles a list of filenames and separates the names with spaces. 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. 23 TUTORIAL Of course, we need to be able to use this list, and for that we use: ItemSelect (title, list, delimiter) Displays a listbox filled with items from a list you specify in a string. The items are separated in your string by a delimiter character. This is the function which actually displays the list box. Remember that FileItemize returns a file list delimited by spaces, which would look something like this: FILE1.DOC FILE2.DOC FILE3.DOC When we use ItemSelect, we need to tell it that the delimiter is a space. We do this as follows: textfiles = FileItemize("*.doc *.txt") yourfile = ItemSelect("Select file to edit", textfiles, " ") Run("notepad.exe", yourfile) First, we use FileItemize to build a list of filenames with DOC and TXT extensions. We assign this list to the variable textfiles. Then, we use the ItemSelect function to build a list box, passing it the variable textfiles as its second parameter. The third parameter we use for ItemSelect is simply a space with quote marks around it; this tells ItemSelect that the variable textfiles 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. Finally, we assign the value returned by ItemSelect to the variable yourfile, 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, ItemSelect returns a null string. If you want, you can test for this condition: textfiles = FileItemize("*.doc *.txt") :retry yourfile = ItemSelect("Select file to edit", textfiles, " ") If yourfile == "" Then Goto retry Run("notepad.exe", yourfile) DirItemize (dir-list) Returns a space-delimited list of directories. 24 TUTORIAL 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. We can do this by first letting the user select the appropriate directory, using the DirItemize and ItemSelect combination: DirChange("\") subdirs = DirItemize("*") targdir = ItemSelect("Select dir", subdirs, " ") DirChange(targdir) files = FileItemize("*.*") file = ItemSelect("Select file", files, " ") Run("notepad.exe", file) First we change to the root directory. Then we use DirItemize to get a list of all the subdirectories off of the root directory. Next, we use ItemSelect to give us a list box of directories from which to select. Finally, we change to the selected directory, and use FileItemize and ItemSelect to pick a file. Although this batch file works, it needs to be polished up a bit. What happens if the file we want is in the \WINDOWS\BATCH directory? Our batch file 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 set up a loop to test when we are at the lowest level: DirChange("\") :getdir subdirs = DirItemize("*") If subdirs == "" Then Goto getfile targdir = ItemSelect("Select dir (OK = curr)", subdirs, " ") If targdir == "" Then Goto getfile DirChange(targdir) Goto getdir :getfile files = FileItemize("*.*") file = ItemSelect("Select file", files, " ") If file == "" Then Goto getfile Run("notepad.exe", file) After we use the DirItemize function, we test the returned value for a null string. If we have a null string, then we know that the current directory has no subdirectories, and so we proceed to select the filename from the current directory (Goto getfile) . If, however, 25 TUTORIAL DirItemize returns a non-blank list, then we know that there is, in fact, at least one subdirectory. In that case, we use ItemSelect to present the user with a list box of directories. Then, we test the value returned by ItemSelect. 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 (Goto getfile). On the other hand, a non-blank value returned by ItemSelect indicates that the user has selected a subdirectory from the list box. In that case, we change to the selected directory, and loop back to the beginning of the directory selection routine (Goto getdir). We continue this process until either (a) the user selects a directory, or (b) there are no directories left to select. Eventually, we get to the section of the batch file labeled :getfile. Nicer Display Boxes Have you tried displaying long messages, and found that WinBatch didn't wrap the lines quite the way you wanted? Here are a couple of tricks. Num2Char (integer) Converts a number to its character equivalent. We want to be able to insert a carriage return/line feed combination at the end of each line in our output, and the Num2Char function will let us do that. A carriage return has an ASCII value of 13, and a line feed has an ASCII value of 10 (don't worry if you don't understand what this sentence means). To be able to use these values, we must convert them to characters, as follows: cr = Num2Char(13) lf = Num2Char(10) Now, we need to be able to place the variables cr and lf in our message. 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: cr = Num2Char(13) lf = Num2Char(10) Message("", "This is line one cr lf This is line two") 26 TUTORIAL we would not get the desired effect. WinBatch would simply treat them as ordinary text. However, WinBatch does provide us with a method of performing variable substitution such as this, and that is by delimiting the variables with percentage signs (%). If we do this: cr = Num2Char(13) lf = Num2Char(10) Message("", "This is line one %cr% %lf%This is line two") we will get what we want. Note that there is no space after %lf%; 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). Now, wouldn't it be convenient if we could combine cr and lf into a single variable? We can. StrCat (string[, string]...) Concatenates strings together. The StrCat function lets us combine any number of string constants and/or string variables. Here's how we combine the variables cr and lf into the single variable crlf: crlf = StrCat(cr, lf) Note that the strings to be concatenated are separated by commas, within the parentheses. Now, we can rewrite our example, as follows: cr = Num2Char(13) lf = Num2Char(10) crlf = StrCat(cr, lf) Message("", "This is line one %crlf%This is line two") If we wanted to re-use this message a number of times, it would be quite convenient to use the StrCat function to make a single variable out of it: 27 TUTORIAL cr = Num2Char(13) lf = Num2Char(10) crlf = StrCat(cr, lf) line1 = "This is line one" line2 = "This is line two" mytext = StrCat(line1, crlf, line2) Message("", mytext) Even Nicer Display Boxes For fancy dialog boxes, complete with all the bells and whistles, see the separate manual section on the DialogBox function (pg. 31). Running DOS Programs WinBatch 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 WinBatch 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: 28 TUTORIAL coms = Environment("COMSPEC") and use it in our batch file: 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 WinBatch: the ability to send keystrokes to Windows programs, just as if you were typing them directly from the keyboard. SendKey (character-codes) Sends keystrokes to the active application. 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", "") SendKey("!FO") The parameter you specify for SendKey is 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 WBL Function Reference (pg. 121). 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. Here's another example: RunZoom("sol.exe", "") SendKey("!GC{RIGHT}{SP}~") This starts up Solitaire, brings up the Game menu (!G), and selects Deck (C) from that menu. Then it moves the cursor to the next card 29 TUTORIAL back style on the right ({RIGHT}), selects that card back ({SP}), and then selects OK (~). And voila! A different card design every time you play! Our Completed WinBatch File Here is the final working version of the SOLITARE.WBT file that we've slowly been building throughout this tutorial: ; solitare.wbt mins = AskLine("Solitaire", "How many minutes do you want to play?", "") If WinExist("Solitaire") == @TRUE Then Goto activate RunZoom("sol.exe", "") Goto loaded :activate WinActivate("Solitaire") WinZoom("Solitaire") :loaded SendKey("!GC{RIGHT}{SP}~") goal = mins * 60 timer = 0 :moretime remain = goal - timer WinTitle("Solitaire", "Solitaire (%remain% seconds left)") Delay(10) timer = timer + 10 If WinExist("Solitaire") == @FALSE Then Exit If timer < goal Then Goto moretime Beep WinClose("Solitaire") Message("Time's up", "Get back to work!") 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 the WinBatch Language (pg. 44). It can also be improved and customized in a number of ways. If you can understand and follow the structures and processes illustrated in this sample file, and can begin to incorporate them into your own WinBatch files, you are well on your way to becoming a true WinBatch guru! 30 DIALOG BOXES DIALOG BOXES The DialogBox function can be used to design complex dialog boxes for user interaction. These dialog boxes can contain data entry fields, file selection boxes, radio buttons, and check boxes. This is a somewhat advanced topic, which assumes a basic understanding of the WinBatch structures already presented. DialogBox Pops up a Windows dialog box defined by the WBD template file. Syntax: DialogBox ("title", "WBD file") Parameters: "title" = the title of the dialog box. "WBD file" = the name of the WBD template file. For each dialog box, you must first create a template file, with a (recommended) WBD extension, which will identify the structure of the dialog box, as well as the variables used by it. Unlike the other WinBatch functions, you do not actually pass variables to DialogBox as parameters. However, the DialogBox function does indeed have the ability to manipulate, and even create, variables. If you are familiar with programming, you may think of DialogBox as a subroutine, and all the variables it uses as being global. Let's start with a simple example. Suppose we want to write a WinBatch file which starts up Notepad, with two options which can be selected at runtime: 1. It can optionally zoom Notepad to full-screen. 2. It can optionally save a backup of the file to be edited. We could accomplish this with two AskYesNo statements: 31 DIALOG BOXES file = ItemSelect("", FileItemize("*.*"), " ") zoom = AskYesNo("", "Start Notepad zoomed?") backup = AskYesNo("", "Save a backup copy of %file%?") If backup == @NO Then Goto nobackup filebackupname = StrCat(FileRoot(file), ".", "bak") FileCopy(file, filebackupname, @TRUE) :nobackup If zoom == @NO Then Run("notepad.exe", file) If zoom == @YES Then RunZoom("notepad.exe", file) (The FileRoot function is new here: it simply returns the root of the filename, without the dot or the extension). This is fine, but DialogBox gives us another way of accomplishing the same thing. We will construct a template file called EDIT.WBD, in which the AskYesNo statements will be functionally replaced by check boxes. Here's what the template file will look like: [zoom+1Start editor zoomed] [backup+1Save backup of file] It is an ordinary ASCII file. Some explanation is in order. First, note the square brackets. Each element in a WBT file is enclosed in brackets; in this case, there are two distinct elements. Next, notice that the first items that appear inside the brackets are variable names. These variables -- zoom and backup -- are the same variables that we used in the AskYesNo statements, above. Immediately following the variable name is a plus sign (+), which identifies the elements as being check boxes. After the + symbol is the number 1, which represents the value that will be assigned to the variable if the box gets checked. Note that there is no space before or after the + symbol. Finally, we have the text which will be displayed next to the check box. Now, let's modify our WinBatch file to use this WBD template: file = ItemSelect("", FileItemize("*.*"), " ") DialogBox("Edit a file", "edit.wbd") If backup == 0 Then Goto nobackup filebackupname = StrCat(FileRoot(file), ".", "bak") FileCopy(file, filebackupname, @TRUE) :nobackup If zoom == 1 Then Run("notepad.exe", file) If zoom == 1 Then RunZoom("notepad.exe", file) 32 DIALOG BOXES The WBD template file should be in the current directory or in a directory on your path; otherwise, you must give a complete path specification for it when it appears in the DialogBox statement. Now, run the WinBatch file. After you select a file from the list box generated by the ItemSelect function, you will get the dialog box. Notice how WinBatch adds two buttons -- OK and Cancel -- to the bottom of the dialog box. Cancel terminates the batch file entirely. You may want to try running this with various combinations of boxes checked, just to confirm that it works properly. It should. Now, look again at the WinBatch file. Notice how the variables zoom and backup do not appear until after the DialogBox statement. In essence, these variables are created by the WBD template, and initialized with values of 0. If the user checks a box, the variable associated with that box is given the value which appears next to the + symbol in the template. So, if the first box is checked, then zoom will have a value of 1 after the DialogBox statement is executed. If it remains un-checked, it will still have a value of 0. These values can then be used in your WinBatch files, as we have done above. Suppose that you want a box to be checked, by default. All you need to do is to assign a non-zero value to the corresponding variable before you execute the DialogBox statement. For example: file = ItemSelect("", FileItemize("*.*"), " ") zoom = 1 DialogBox("Edit a file", "edit.wbd") If backup == 0 Then Goto nobackup filebackupname = StrCat(FileRoot(file), ".", "bak") FileCopy(file, filebackupname, @TRUE) :nobackup If zoom == 1 Then Run("notepad.exe", file) If zoom == 1 Then RunZoom("notepad.exe", file) When you run it this time, the first box will already be checked, because we first assigned a value of 1 to the variable zoom. The variable will still have a value of 1 after the DialogBox statement is executed -- unless the user un-checks the box, in which case it will have a value of 0. The variable associated with an unchecked box is always equal to 0; the variable associated with a checked box is equal to the value you specify for that box. For the most part, you would be fine simply using a value of 1 to indicate a checked box. You can change the layout of the WBD template to suit your taste. For example, this: 33 DIALOG BOXES [zoom+1Start editor zoomed] [backup+1Save backup of file] would put the two check boxes side by side. However, you may not put tab characters in a template file, so be sure to use spaces instead (unless your editor can convert tabs to spaces). Also, template files are limited to 15 lines, and to the first 60 columns The next element which you can use in a dialog box is the radio button. Whereas you can have several check boxes checked at one time, the radio button gets its name from the five-button car radio, which can only have one station selected at a time. You can have more than one group of radio buttons, but only one button in each group may be "pressed." Therefore, this is ideal for situations where the user must make a choice from multiple alternatives: Here's a group of four radio buttons: [editor^1Notepad] [editor^2WinEdit] [editor^3Write] [editor^4WinWord] Let's look at how these are different from check boxes. First, the symbol which identifies a radio button is a caret (^), instead of a +. Second, each of the buttons has the same variable name (editor). And third, each button has a unique value following the ^ symbol. This should make sense if you consider what we are trying to accomplish: we want to obtain a value for the variable editor. The user has four programs to choose from, and he must choose one, and only one. As you have probably guessed, the value associated with the button which the user "pushes" will be assigned to editor. Let's add this to our existing EDIT.WBD template: [zoom+1Start editor zoomed] [backup+1Save backup of file] [editor^1Notepad] [editor^2WinEdit] [editor^3Write] [editor^4WinWord] and expand our WinBatch file to take advantage of it: 34 DIALOG BOXES file = ItemSelect("", FileItemize("*.*"), " ") zoom = 1 DialogBox("Edit a file", "edit.wbd") If backup == 0 Then Goto nobackup filebackupname = StrCat(FileRoot(file), ".", "bak") FileCopy(file, filebackupname, @TRUE) :nobackup If zoom == 0 Then runcmd = "Run" If zoom == 1 Then runcmd = "RunZoom" If editor == 1 Then %runcmd%("notepad.exe", file) If editor == 2 Then %runcmd%("winedit.exe", file) If editor == 3 Then %runcmd%("write.exe", file) If editor == 4 Then %runcmd%("winword.exe", file) (We're using the variable runcmd to avoid having to code eight separate Run and RunZoom statements. Pretty clever, isn't it.) Look at how we are testing the value of editor to determine which program to run. When the DialogBox statement is executed, the first radio button in each group is selected, regardless of its value. In this case, the first button appearing in the template, in the editor group, has a value of 1, so, unless the user selects a different button, the variable editor will have a value of 1 after DialogBox finishes, and Notepad will be run. If the user selects the WinEdit button, editor will have a value of 2 , and Winedit will be run. Another important element which you can use in your templates is the file selection list box, which combines the functionality of DirItemize, FileItemize, and ItemSelect. It has the following form: [file\ ] [file\ ] [file\ ] [file\ ] [file\ ] Here, file is the variable name (you can use another name instead of file), and the backslash (\) is the symbol which identifies this as a file list element. The amount of space between the \ symbol and the right bracket will determine the width of the file selection list box. And the number of occurrences of this element (each must have an identical name) will determine the height of the list box. Let's add this to our template: 35 DIALOG BOXES [zoom+1Start editor zoomed] [backup+1Save backup of file] [editor^1Notepad] [editor^2WinEdit] [editor^3Write] [editor^4WinWord] [file\ ] [file\ ] [file\ ] [file\ ] [file\ ] and revise our batch file: zoom = 1 DialogBox("Edit a file", "edit.wbd") If backup == 0 Then Goto nobackup filebackupname = StrCat(FileRoot(file), ".", "bak") FileCopy(file, filebackupname, @TRUE) :nobackup If zoom == 0 Then runcmd = "Run" If zoom == 1 Then runcmd = "RunZoom" If editor == 1 Then %runcmd%("notepad.exe", file) If editor == 2 Then %runcmd%("winedit.exe", file) If editor == 3 Then %runcmd%("write.exe", file) If editor == 4 Then %runcmd%("winword.exe", file) All we did was remove the first line from the earlier example, which used FileItemize and ItemSelect to retrieve a file name. By default, the file selection list box uses *.* as a file mask. If you want to limit the selection to, say, DOC files, assign a value to the appropriate variable before executing the DialogBox statement: file = "*.doc" DialogBox("Edit a file", "edit.wbd") Another element, the file mask edit box, allows the user to change the file mask interactively. It's format is: [file# ] Where the variable name, in this case file, must be the same as the one used in the file selection list box, and is followed by a number sign (#). If the user enters a valid wild card mask in the file mask edit box, the file display in the file selection list box will be updated accordingly. For example, if DOC files are currently shown, and the user types *.TXT, the display will change to show TXT files. 36 DIALOG BOXES You can optionally display the current directory (whose contents are being listed) by including an additional element in the template: [file$ ] This is identical to the file list element, except the symbol for the directory element is a dollar sign ($). The variable name must be the same as the one used in the file selection list box: [file$ ] File mask [file# ] [file\ ] [file\ ] [file\ ] [file\ ] [file\ ] Note that we have included the descriptive text "File mask" next to the file mask edit box. You may place explanatory text anywhere in the template file, as long as it doesn't appear inside square brackets. You can also display a WinBatch variable in your dialog box by using an element of this form: [varname$] Where the name of the variable is followed by a dollar sign ($). WinBatch will replace this with the current value of the variable. Finally, we have the edit box, which allows us to assign user-supplied text to a variable. The edit box element has the form: [input# ] The variable name (in this case, input) is followed a number sign (#), and the width of the area between the brackets determines the width of the edit box which gets displayed. Whatever the user types in the box gets assigned to the associated variable. Here is a sample RENAME.WBD template: 37 DIALOG BOXES Select file to be renamed [oldname$ ] [oldname\ ] [oldname\ ] [oldname\ ] [oldname\ ] Type new name for the file [newname# ] Which could be used with this WinBatch file: DialogBox("File Rename", "rename.wbd") FileRename(oldname, newname) You will have noticed that there are two symbols -- $ and # -- which have dual meanings, depending on whether or not there is a file list selection variable in the template with the same name. The three file elements -- [file\], [file$], and [file#] -- are a "set", and share a common variable name. All other variables in your template should have unique names. 38 WinMacro WinMacro WinMacro is a standalone companion program included in the WinBatch package, which lets you create macro files and "attach" them to the control menu of any Windows application. These macros can then be executed, either by selecting them from the control menu, or through the use of a "hotkey." WinMacro also has the ability to "record" keystrokes, which can later be "played back" virtually anywhere in the Windows environment. Starting WinMacro You can run WINMACRO.EXE just like any other Windows program, using your favorite Windows-program-starting method (keyboard, mouse, Program Manager, File Manager, MS-DOS Executive, Command Post, WinBatch, etc.). However, if you will be using WinMacro on a regular basis, you may wish to have it load automatically when you start up Windows. You can do this by adding WINMACRO.EXE to the LOAD= line in your WIN.INI file (consult your Microsoft Windows manual for more information). If you are wise enough to be using Command Post as your primary shell , you can just add a RunIcon("winmacro.exe, "") line to the "autoexec" section of your user menu (if you're not yet a convert to Command Post, consider contacting the nice folks at Wilson WindowWare for more information on this outstanding program). WinBatch starts up as an icon, and remains active until you either close it or end your Windows session (whichever comes first). Macro Definition Files WinMacro definition (WDF) files are plain ASCII files which you create and edit. They must have a WDF extension, and they must be located in the same directory as WINMACRO.EXE. A WDF file contains any number of definition lines, each of which represents an individual command. Each line has the following format: Title [\ optional hotkey] : program to be executed Title is the name which will appear on the application's control menu to identify the command. The hotkey is optional; if it is included, it must be preceded by a backslash (\). This is followed by a colon (:), and then the program which should be executed when the command is selected, with any required parameters. This can be any Windows or 39 WinMacro DOS EXE, COM, PIF, or BAT file, and you must include the appropriate file extension. If the program isn't located either in the current directory or on your DOS path, you must include a path specification for it. To run a WinBatch file, run WINBATCH.EXE, with the name of the WBT file as a parameter. Let's create a WinMacro definition file, named GLOBAL.WDF: Run Notepad : notepad.exe Play Solitaire \ ^F9 : winbatch.exe solitare.wbt (This second line assumes that you have created SOLITARE.WBT as part of the WinBatch tutorial. If not, just substitute any WBT file). GLOBAL.WDF is a special file name. When WinMacro starts up, it looks for this file. If present, WinMacro loads it, and attaches its contents to the control menu of every window currently running, as well as any windows that may subsequently be opened (the control menu is the menu that you access by typing Alt-Space, or by clicking the little box on the left side of the title bar of any window). Go ahead and start up WinMacro, then access the control menu of any open window. You should see that the two commands in your GLOBAL.WDF file have been attached to the control menu, and both are now available for your use. You can run these user-defined commands by selecting them from the menu. In addition, because you have defined a hotkey for the "Play Solitaire" command, you can run it from any window by pressing Ctrl-F9. Hotkeys You can assign a hotkey to any WinMacro definition line. A hotkey consists of the Ctrl key plus any letter (A - Z) or function (F1 - F16) key. In addition, you can optionally use the Alt and Shift keys: Key Char Ctrl ^ Alt ! Shift + Here are some examples of valid key combinations: Hotkey Equivalent keystrokes ^F5 Ctrl-F5 40 WinMacro ^!F5 Ctrl-Alt-F5 ^+F5 Ctrl-Shift-F5 ^!+F5 Ctrl-Alt-Shift-F5 ^D Ctrl-D ^!D Ctrl-Alt-D ^+D Ctrl-Shift-D ^!+D Ctrl-Alt-Shift-D In addition to GLOBAL.WDF, you can create application-specific WinMacro definition files. They have the form progname.WDF, where "progname" is the name of the application's COM or EXE file. So, if you wanted to have a WDF file which would apply only to Notepad, you would name it NOTEPAD.WDF. Its contents would be attached only to Notepad's control menu, and its hotkeys would be active only when Notepad was the active window. WinMacro loads application-specific WDF files after GLOBAL.WDF, so if you have, for example, a NOTEPAD.WDF file, it's contents will be attached to Notepad's control menu in addition to (not instead of) GLOBAL.WDF. If you define the same hotkey in GLOBAL.WDF and NOTEPAD.WDF, the one in NOTEPAD.WDF will apply. If you edit a WDF file while WinMacro is running, and want to see the changes reflected in the current menus, select About/Reload from the WinMacro icon's menu. All windows will be updated. Recording Keystrokes Another feature of WinMacro is the ability to record keystrokes to a file, which can be played back at a later time. To do this, make sure that WinMacro is running, and then type Ctrl-Shift-Home from any window, or select Begin Macro Record from the WinMacro icon's menu. WinMacro will present you with a menu of existing WBM files. If you want to overwrite an existing file, select its name from the menu; otherwise, enter a name for the file you wish to create in the edit box (a WBM extension will automatically be added), and press the Enter key or click on the OK button. At this point, the icon will begin flashing, indicating that you are in record mode. Once you are in record mode, every keystroke you type will be recorded to your WBM file. Mouse movement and mouse clicks are not recorded. To end record mode, type Ctrl-Shift-End from any window, or click on the flashing WinMacro icon and select End Macro Record from the menu. The icon will stop flashing. 41 WinMacro Once you have created a WBM keystroke macro file, you can assign it to a hotkey in a WDF file, using the steps outlined above. You use WinBatch to run WBM files, the same way you do with WBT files. WinMacro Example Let's create a macro for Solitaire which will cycle to the next deck back design (sound familiar?). First, WinMacro should be running. Next, start up Solitaire, and make sure that it is the current window. Now, activate keystroke record mode, as outlined above, and name the file SOLITARE.WBM. Once the WinMacro icon begins flashing, we're ready to record. Enter the following series of keystrokes: Alt-G C Cursor right Space Enter And end record mode. Now, create a WinMacro definition file named SOLITARE.WDF, containing the following entry: Change deck design \ ^C : winbatch.exe solitare.wbm Finally, select About/Reload from the WinMacro icon's menu. Your new command is now available from the Solitaire control menu, or simply by typing Ctrl-C when the Solitaire window is active. WBM files If you look at a WBM file, you will see that it is nothing more than a series of one or more SendKey statements. For example, the SOLITARE.WBM file that we just created looks something like this ; Recorded Macro D:\WINDOWS\BATCH\SOLITARE.WBM SendKey(`!gc{RIGHT} {ENTER}`) ; End Recorded Macro If you glance back at the SOLITARE.WBT file in the Tutorial section of this manual (pg. 30), you will find a line which looks amazingly like the middle one above (~ has the same meaning as {ENTER}). This demonstrates that WBM files are simply WBT files in disguise. 42 WinMacro So, why do we use different extensions for the two types of files? Consider, if you will, that a WBT file is a standalone program, which can be run from the Program Manager or File Manager. It starts up whatever other programs it needs, does its work, and cleans up after itself. A WBM file, on the other hand, is only a program fragment. When called, it sends a sequence of keystrokes to the active window, but it neither knows nor cares what window that may happen to be. In Solitaire, Alt-G selects the Game menu; in another program, it may trigger the Goodbye function. Needless to say, WBM files should be played back only in the window where they were recorded, and the easiest way to ensure this is to attach them to application-specific WDF files, as we have done here with Solitaire. That's why we distinguish them from regular WBT files. However, because SendKey is a perfectly respectable WinBatch function -- and because WinMacro does generate SendKey statements -- it is quite useful to be able to record a WBM file, and later incorporate it into a full-fledged WinBatch file. Suppose that we had a one-line WinBatch WBT file like this: RunZoom("sol.exe", "") and we wanted to follow that with a SendKey statement to change the deck design every time the file was run. Instead of laboring over the WinBatch manual to find the cryptic symbols necessary to accomplish such a feat, we could simply use the WinMacro record feature to create a WBM file, as we did above, and then paste the resulting SendKey statement into the WinBatch WBT file: RunZoom("sol.exe", "") SendKey(`!gc{RIGHT} {ENTER}`) You can also use your favorite editor to remove any accidental keystrokes you make when you are recording a WBM file. Unrecordable Areas WinMacro is unable to record keystrokes entered in Windows' System Modal Dialog Boxes. These include the dialog boxes in the MS-DOS Executive window, as well as dialog boxes generated by severe system errors. By the same token, WinBatch cannot play back keystrokes in these types of dialog boxes. 43 WINBATCH LANGUAGE WINBATCH LANGUAGE Language Components WinBatch language statements are constructed from constants, variables, operators, functions, commands, and comments. Each line in a WinBatch file can be up to 255 characters long. Constants The programming language supports both integer and string constants. Integer Constants Integer constants are built from the digits 0 through 9. They can range in magnitude from negative to positive 231 -1 (approximately two billion). Constants larger than these permissible magnitudes will produce unpredictable results. Examples of integer constants: 1 -45 377849 -1999999999 String Constants String constants are comprised of displayable characters bounded by quote marks. You can use double quotes ("), single quotes ('), or back quotes (`) to enclose a string constant, as long as the same type of quote is used to both start and end it. If you need to embed the delimiting quote mark inside the string constant, use the delimiting quote mark twice. Examples of string constants: "a" `Betty Boop` "This constant has an embedded "" mark" 'This constant also has an embedded " mark' 44 WINBATCH LANGUAGE Predefined Constants The programming language has a number of built-in integer constants that can be used for various purposes. These start with the @-sign, and are case-insensitive (although we prefer to use ALL CAPS). Some predefined constants: @FALSE @TILE @NO @TRUE @STACK @YES A list of all the predefined constants can be found in Appendix A (pg. 152). Identifiers Identifiers are the names supplied for variables, functions, and commands in your program. An identifier is a sequence of one or more letters or digits that begins with a letter. Identifiers may have up to 30 characters. All identifiers are case insensitive. Upper- and lowercase characters may be mixed at will inside variable names, commands or functions. For example, these statements all mean the same thing: AskLine(MyTitle, Prompt, Default) ASKLINE(MYTITLE, PROMPT, DEFAULT) aSkLiNe(MyTiTlE, pRoMpT, dEfAuLt) Variables A variable may contain an integer, a string, or a string representing an integer. Automatic conversions between integers and strings are performed as a matter of course during execution. If a function requires a string parameter and an integer parameter is supplied, the variable will be automatically modified to include the representative string. If a function requires an integer parameter and a string parameter is supplied, an attempt will be made to convert the string to an integer. If it does not convert successfully, an error will result. 45 WINBATCH LANGUAGE Keywords "Keywords" are the predefined identifiers that have special meaning to the programming language. These cannot be used as variable names. WBL keywords consist of the functions, commands, and predefined constants. Some examples of reserved keywords: Beep DirChange @Yes FileCopy Operators The programming language operators take one operand ("unary operators") or two operands ("binary operators"). Unary operators (integers only): - Arithmetic Negation (Two's complement) + Identity (Unary plus) ~ Bitwise Not. Changes each 0 bit to 1, and vice-versa. ! Logical Not. Produces 0 (@FALSE) if the operand is nonzero, else 1 (@TRUE) if the operand is zero. Binary arithmetic operators (integers only): * Multiplication / Division mod Modulo + Addition - Subtraction << Left Shift >> Right Shift & Bitwise And | Bitwise Or ^ Bitwise Exclusive Or (XOR) && Logical And || Logical Or Binary relational operators (integers and strings): > Greater-than >= Greater-than or equal 46 WINBATCH LANGUAGE < Less-than <= Less-than or equal == Equality != or <> Inequality Assignment operator (integers and strings): = Assigns evaluated result of an expression to a variable Precedence and evaluation order The precedence of the operators affect the evaluation of operands in expressions. Operands associated with higher-precedence operators are evaluated before the lower-precedence operators. The table below shows the precedence of the operators. Where operators have the same precedence, they are evaluated from left to right. Operator Description ( ) Parenthetical grouping ~ ! - + Unary operators * / mod Multiplication & Division + - Addition & Subtraction << >> Shift operators < <= == >= > != <> Relational operators & ^ | Bit manipulation operators && || Logical operators Comments A comment is a sequence of characters that are ignored when processing a command. A semicolon (not otherwise part of a string constant) indicates the beginning of a comment. All characters to the right of the semicolon are considered comments, and are ignored. Blank lines are also ignored. Examples of comments: ; This is a comment abc = 5 ; This is also a comment 47 WINBATCH LANGUAGE Statements Assignment Statements Assignment statements are used to set variables to specific or computed values. Variables may be set to integers or strings. Examples: a = 5 value = Average(a, 10, 15) location = "Northern Hemisphere" world = StrCat(location, " ", "Southern Hemisphere") Control Statements Control statements are generally used to execute system management functions and consist of a call to a command without assigning any return values. Examples: Exit Yield Substitution The batch language has a powerful substitution feature which inserts the contents of a string variable into a statement before the line is parsed. To substitute the contents of a variable in the statement, simply put a percent-sign (%) on both sides of the variable name. Examples: mycmd = "DirChange('c:\')" ; set mycmd to a command %mycmd% ; execute the command Or consider this one: IniWrite("PC", "User", "Richard") ... owner = IniRead("PC", "User", "somebody") message("", "Thank you, %user%") 48 WINBATCH LANGUAGE To put a single percent-sign (%) on a source line, specify a double percent sign(%%). This is required even inside quoted strings. Note: The length of a line, after any substitution occurs, may not exceed 255 characters. Function Parameters Most of the functions and commands in the language require parameters. These come in three types: Integer String Variable name WinBatch performs automatic conversions between strings and integers, so in general you can use them interchangeably. Integer parameters may be any of the following: An integer (i.e. 23) A string representing an integer (i.e. "23") A variable containing an integer A variable containing a string representing an integer String parameters may be any of the following: A string An integer A variable containing a string A variable containing an integer Command-Line Parameters WinBatch is run with the following command line: WINBATCH filename.WBT p1 p2 ... pn "filename.wbt" is any valid WinBatch file. "p1 p2 ... pn" are optional parameters to be passed to the WBT file on startup, delimited by spaces. 49 WINBATCH LANGUAGE Parameters passed to a WBT file are automatically parsed into variables named param1, param2, param3, etc. An additional variable, param0, is the total number of command-line parameters. Error Handling There are three types of errors that can occur while processing a batch file: Minor, Moderate, and Fatal. What happens when an error occurs depends on the current error mode, which is set with the ErrorMode function. There are three possible modes you can specify: @CANCEL User is notified when any error occurs, and then the batch file is canceled. This is the default. @NOTIFY User is notified when any error occurs, and has option to continue unless the error is fatal. @OFF User is only notified if the error is moderate or fatal. User has option to continue unless the error is fatal. The function LastError returns the code of the most-recent error encountered during the current batch file. Minor errors are numbered from 1000 to 1999. Moderate errors are numbered from 2000 to 2999. Fatal errors are numbered from 3000 to 3999. Error handling is reset to @CANCEL at the start of each batch file. 50 WINBATCH LANGUAGE The Functions & Statements Inputting Information AskLine (title, prompt, default) Lets user enter a line of information. AskYesNo (title, question) Lets user choose from Yes, No, or Cancel. ItemCount (list, delimiter) Returns the number of items in a list. ItemExtract (select, list, delimiter) Returns the selected item from a list. ItemSelect (title, list, delimiter) Chooses an item from a listbox. TextBox (title, filename) Fills a listbox from text strings in a file. Displaying Information Beep Beeps at the user. DialogBox (title, WBD file) Pops up a Windows dialog box defined by the WBD template file. Display (seconds, title, text) Momentarily displays a string. Message (title, text) Displays text in a message box. 51 WINBATCH LANGUAGE Pause (title, text) Displays text in a message box. File Management FileAppend (from-list, to-file) Appends one or more files to another file. FileClose (filehandle) Closes a file. FileCopy (from-list, to-file, warning) Copies files. FileDelete (file-list) Deletes files. FileExist (filename) Determines if a file exists. FileExtension (filename) Returns extension of file. FileItemize (file-list) Builds a list of files. FileLocate (filename) Finds a file within the current DOS path. FileMove (from-list, to-file, warning) Moves files to another set of pathnames. FileOpen (filename, open-type) Opens a STANDARD ASCII (only) file for reading or writing. 52 WINBATCH LANGUAGE FilePath (filename) Returns path of file. FileRead (filehandle) Reads data from a file. FileRename (from-list, to-file) Renames files to another set of names. FileRoot (filename) Returns root of file. FileSize (file-list) Adds up the total size of a set of files. FileWrite (filehandle,output-data) Writes data to a file. IniRead (section, keyname, default) Reads a string from the WIN.INI file. IniReadPvt (section, keyname, default, filename) Reads a string from a private INI file. IniWrite (section, keyname, string) Writes a string to the WIN.INI file. IniWritePvt (section, keyname, data, filename) Writes a string to a private INI file. Directory Management DirChange ([d:]path) Changes the current directory. 53 WINBATCH LANGUAGE DirGet ( ) Returns the current directory path. DirHome ( ) Returns the initial directory path. DirItemize (dir-list) Builds a list of directories. DirMake ([d:]path) Creates a new directory. DirRemove ([d:]path) Removes an existing directory. DirRename ([d:]oldpath, [d:]newpath) Renames a directory. Disk Drive Management DiskFree (drive-list) Returns the amount of free space on a set of drives. LogDisk (drive) Changes the logged disk drive. Window Management WinActivate (partial-windowname) Makes an application window the active window. WinArrange (style) Arranges all running application windows on the screen. 54 WINBATCH LANGUAGE WinClose (partial-windowname) Closes an application window. WinCloseNot (partial-windowname [, partial-windowname]...) Closes all application windows except those specified. WinConfig ( ) Returns WIN3 mode flags. WinExist (partial-windowname) Tells if window exists. WinGetActive ( ) Gets the title of the active window. WinHide (partial-windowname) Hides an application window. WinIconize (partial-windowname) Turns an application window into an icon. WinItemize ( ) Lists all the main windows currently running. WinPlace (x-ul, y-ul, x-br, y-br, partial-windowname) Changes the size and position of an application window on the screen. WinPosition (partial-windowname) Returns window position. WinShow (partial-windowname) Shows a currently-hidden application window. WinTitle (partial-windowname, new-windowname) Changes the title of an application window. 55 WINBATCH LANGUAGE WinWaitClose (partial-windowname) Waits until an application window is closed. WinZoom (partial-windowname) Maximizes an application window to full-screen. Program Management Run (program-name, parameters) Runs a program as a normal window. RunHide (program-name, parameters) Runs a program in a hidden window. RunIcon (program-name, parameters) Runs a program as an icon. RunZoom (program-name, parameters) Runs a program in a maximized window. String Handling Char2Num (string) Returns the ANSI code of a string's first character. IsNumber (string) Determines if a string represents a valid number. Num2Char (number) Converts a number to the ANSI character it represents. ParseData (string) Parses the passed string, just like passed parameters are parsed. 56 WINBATCH LANGUAGE StrCat (string[, string]...) Concatenates strings together. StrCmp (string1, string2) Compares two strings. StrFill (string, string-length) Builds a string from a repeated smaller string. StrFix (base-string, padding-string, length) Pads or truncates a string to a fixed length. StriCmp (string1, string2) Compares two strings, ignoring their case. StrIndex (main-str, sub-str, start, direction) Locates a string within a larger string. StrLen (string) Returns the length of a string StrLower (string) Converts a string to all lower-case characters. StrReplace (string, old, new) Replaces all occurances of a substring with another. StrScan (main-str, delims, start, direction) Finds an occurrence of one or more delimiter characters in a string. StrSub (string, start, length) Returns a substring from within a string. StrTrim (string) Trims leading and trailing blanks from a string. 57 WINBATCH LANGUAGE StrUpper (string) Converts a string to all upper-case characters. Arithmetic Functions Abs (number) Returns the absolute value of a number. Average (num [, num]...) Returns the average of a list of integers. Max (num [, num]...) Determines the highest number in a list. Min (num [, num]...) Determines the lowest number in a list. Random (max) Generates a positive random number. Clipboard Handling ClipAppend (string) Appends a string to the end of the Clipboard. ClipGet ( ) Returns the Clipboard contents into a string. ClipPut (string) Replaces the Clipboard contents with a string. System Control Call (filename.wbt, parameters) Calls another WBT file as a subroutine. 58 WINBATCH LANGUAGE CallExt (filename.wbt, parameters) Calls another WBT file as a separate subprogram. DateTime ( ) Returns the current date and time. Debug (mode) Turns Debug mode on or off. Delay (seconds) Pauses batch file execution. DOSVersion (level) Returns the version numbers of the current version of DOS. Drop (var [, var]...) Deletes variables to recover their memory. EndSession ( ) Ends the current Windows session. Environment (env-variable) Returns the value of a DOS environment variable. ErrorMode (mode) Sets what happens in the event of an error. Exclusive (mode) Controls whether or not other Windows program will get any time to execute. Execute statement Directly executes a WinBatch statement. Exit Exits the current batch file's operation. 59 WINBATCH LANGUAGE Goto label Changes the flow of control in a batch file. If condition Then statement Conditionally performs a function. IgnoreInput (mode) Turns off hardware input to windows. IsDefined (variable) Determines if a variable is currently defined. IsKeyDown (key-codes) Tells about keys/mouse. IsLicensed ( ) Tells if WinBatch is licensed. LastError ( ) Returns the last error encountered. Return ( ) Returns from a Call or a CallExt to the calling program. SendKey (character-codes) Sends keystrokes to the active application. SKDebug (mode) Controls how SendKey works Version ( ) Returns the version of WinBatch currently running. WallPaper (bmp-name, tile) Changes the Windows wallpaper. 60 WINBATCH LANGUAGE WinVersion (level) Returns the version of Windows that is currently running. Yield Pauses batch file processing so other applications can process some messages. 61 WBL FUNCTION REFERENCE WBL FUNCTION REFERENCE Introduction WinBatch gives you more than a hundred functions and commands, which we describe in detail in this section. We use a shorthand notation to indicate the syntax of the functions. Function names and other actual characters you type are in boldface. Optional parameters are enclosed in square brackets "[ ]". When a function takes a variable number of parameters, the variable parts will be followed by ellipses ("..."). Take, for example, string concatenation: StrCat (string[, string]...) This says that the StrCat function takes at least one string parameter. Optionally, you can specify more strings to concatenate. If you do, you must separate the strings with commas. For each function and command, we show you the Syntax, describe the Parameters (if any), the value it Returns (if any), a description of the function, Example code (shown in courier type), and related functions you may want to See Also. 62 WBL FUNCTION REFERENCE Abs Returns the magnitude of the argument. Syntax: Abs (integer) Parameters: integer = integer whose absolute value is desired. Returns: (integer) absolute value of argument. This function returns the absolute (positive) value of the integer which is passed to it, regardless of whether that integer is positive or negative. Example: dy = Abs(y1 - y2) Message("Years", "There are %dy% years 'twixt %y1% and %y2%") See Also: Average, Max, Min AskLine Prompts the user for one line of input. Syntax: AskLine (title, prompt, default) Parameters: "title" = title of the dialog box. "prompt" = question to be put to the user. "default" = default answer. 63 WBL FUNCTION REFERENCE Returns: (string) user response. Use this function to query the user for a line of data. The entire user response will be returned if the user presses the OK button or the Enter key. If the user presses Cancel, the batch file processing is canceled. Example: name = AskLine("Game", "Please enter your name", "") game = AskLine("Game", "Favorite game?", "Solitaire") message(StrCat(name,"'s favorite game is "), game) See Also: AskYesNo, Display, ItemSelect, Message, Pause, TextBox AskYesNo Prompts the user for a YES or NO answer. Syntax: AskYesNo (title, question) Parameters "title" = title of the question box. "question" = question to be put to the user. Returns: (integer) @YES or @NO, depending on the button pressed. This function displays a message box with three pushbuttons - Yes, No, and Cancel. If the user presses Cancel, the current batch file is ended, so there is no return value. Example: q = AskYesNo('Testing', 'Please press "YES"') If q == @YES Then Exit Display(3, 'ERROR', 'I said press "YES"') 64 WBL FUNCTION REFERENCE See Also: AskLine, Display, ItemSelect, Message, Pause, TextBox Average Provides the integer average of the arguments. Syntax: Average (integer [, integer]...) Parameters: integer = integers to get the average of. Returns: (integer) average of the arguments. Use this function to compute the mean average of a series of numbers, delimited by commas. This function returns an integer value, so there can be some rounding error involved. Example: avg = Average(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) Message("The average is", avg) See Also: Abs, Max, Min Beep Beeps once. Syntax: Beep Use this command to produce a short beep, generally to alert the user to an error situation. 65 WBL FUNCTION REFERENCE Example: Beep Pause("WARNING!!!", "You are about to destroy data!") Call Calls another WBT file as a subroutine. Syntax: Call (filename.wbt, parameters) Parameters: "filename.wbt" = the WBT file you are calling. The WBT extension is required. "parameters" = the parameters to pass to the file, if any, in the form "p1 p2 p3 ... pn". Returns: (integer) always @FALSE. This function is used to pass control temporarily to a secondary WBT file. The main WBT file can optionally pass parameters to the secondary WBT file. All variables are common (global) between the calling and the called WBT files, so that the secondary WBT file may modify or create variables. The secondary WBT file should end with a Return statement, to pass control back to the main WBT file. If a string of parameters is passed to the secondary WBT file, it will automatically be parsed into individual variables with the names param1, param2, param3, etc. The variable param0 will be a count of the total number of parameters in the string. Example: ; MAIN.WBT name = AskLine("", "What is your name?", "") age = AskLine("", "How old are you?", "") valid = @NO Call("chek-age.wbt", age) If valid == @NO Then Message("", "Invalid age") 66 WBL FUNCTION REFERENCE ; CHEK-AGE.WBT userage = param1 really = AskYesNo("", "%name%, are you really %userage%?") If really == @NO Then Return If (userage > 0) && (userage < 150) Then valid = @YES Return See Also: CallExt, ParseData, Return CallExt Calls another WBT file as a separate subprogram. Syntax: CallExt (filename.wbt, parameters) Parameters: "filename.wbt" = the WBT file you are calling. The extension is required. "parameters" = the parameters to pass to the file, if any, in the form "p1 p2 p3 ... pn". Returns: (integer) always @FALSE. This function is used to pass control temporarily to a secondary WBT file. The main WBT file can optionally pass parameters to the secondary WBT file. All variables are exclusive (local) to their respective files, so that neither WBT file "knows about" variables being used by the other. The secondary WBT file should end with a Return statement, to pass control back to the main WBT file. If a string of parameters is passed to the secondary WBT file, it will automatically be parsed into individual variables with the names param1, param2, param3, etc. The variable param0 will be a count of the total number of parameters in the string. 67 WBL FUNCTION REFERENCE Example: ; MAIN.WBT old = AskLine("RENAME", "File to rename", "") If !FileExist(old) Then Exit new = AskLine("RENAME", "New name for %old%", "") If FileExist(new) Then Exit CallExt("rename.wbt", "%old% %new%") ; RENAME.WBT old = param1 new = param2 FileRename(old, new) Return See Also: Call, ParseData, Return Char2Num Converts the first character of a string to its numeric equivalent. Syntax: Char2Num (string) Parameters: "string" = any text string. Only the first character will be converted. Returns: (integer) ANSI character code. This function returns the 8-bit ANSI code corresponding to the first character of the string parameter. Note: For the commonly-used characters (with codes below 128), ANSI and ASCII characters are identical. 68 WBL FUNCTION REFERENCE Example: ; Show the hex equivalent of entered character inpchar = AskLine("ANSI Equivalents", "Char:", "") ansi = StrSub(inpchar, 1, 1) ansiequiv = Char2Num(InpChar) Message("ANSI Codes", "%ansi% => %ansiequiv%") See Also: Num2Char ClipAppend Appends a string to the Clipboard. Syntax: ClipAppend (string) Parameters: "string" = text string to add to Clipboard. Returns: (integer) @TRUE if string was appended; @FALSE if Clipboard ran out of memory. Use this function to append a string to the Windows Clipboard. The Clipboard must either contain text data or be empty for this function to succeed. Example: ; The code below will append 2 copies of the ; Clipboard contents back to the Clipboard, resulting ; in 3 copies of the original contents with a CR/LF ; between each copy. a = ClipGet() crlf = StrCat(Num2Char(13), Num2Char(10)) ClipAppend(crlf) ClipAppend(a) ClipAppend(crlf) ClipAppend(a) 69 WBL FUNCTION REFERENCE See Also: ClipGet, ClipPut ClipGet Returns the contents of the Clipboard. Syntax: ClipGet ( ) Parameters: (none) Returns: (string) clipboard contents. Use this function to copy text from the Windows Clipboard into a string variable. Note: If the Clipboard contains an excessively large string a (fatal) out of memory error may occur. Example: ; The code below will convert Clipboard contents to ; uppercase ClipPut(StrUpper(ClipGet())) a = ClipGet() Message("UPPERCASE Clipboard Contents", a) See Also: ClipAppend, ClipPut ClipPut Copies a string to the clipboard. 70 WBL FUNCTION REFERENCE Syntax: ClipPut (string) Parameters: "string" = any text string. Returns: (integer) @TRUE if string was copied; @FALSE if clipboard ran out of memory. Use this function to copy a string to the Windows Clipboard. The previous Clipboard contents will be lost. Example: ; The code below will convert Clipboard contents to ; lowercase ClipPut(StrLower(ClipGet())) a = ClipGet() Message("lowercase Clipboard Contents", a) See Also: ClipAppend, ClipGet DateTime Provides the current Date and time. Syntax: DateTime ( ) Parameters: (none) Returns: (string) today's date and time 71 WBL FUNCTION REFERENCE This function will return the current date and time in a pre-formatted string. The format it is returned in depends on how it is set up in the international section of the WIN.INI file: ddd mm:dd:yy hh:mm:ss XX ddd dd:mm:yy hh:mm:ss XX ddd yy:mm:dd hh:mm:ss XX Where: ddd is day of the week (e.g. Mon) mm is the month (e.g. 10) dd is the day of the month (e.g. 23) yy is the year (e.g. 90) hh is the hours mm is the minutes ss is the seconds XX is the Day/Night code (e.g. AM or PM) Note: Windows provides even more formatting options than this. The WIN.INI file will be examined to determine which format to use. You can adjust the WIN.INI file via the International section of the Control Panel if the format isn't what you prefer. Example: ; assuming the current standard is U.S. ; (i.e. day dd/mm/yy hh:mm:ss AM) Message("Current Date & Time", DateTime()) Debug Controls the debug mode. Syntax: Debug (mode) Parameters: mode = @ON or @OFF Returns: (integer) previous debug mode 72 WBL FUNCTION REFERENCE Use this function to turn the debug mode on or off. The default is @OFF. When debug mode is on, WinBatch will display the statement just executed, its result (if any), any error conditions, and the next statement to execute. The statements are displayed in a special dialog box. As you can see in the Example section following, the dialog box gives the user four options: Next, Run, Cancel and Show Var. Next executes the next statement and remains in debug mode. Run exits debug mode and runs the rest of the program normally. Cancel terminates the current batch file. Show Var displays the contents of a variable whose name the user entered in the edit box. Example: Debug(@ON) a = 6 q = AskYesNo("Testing Debug Mode", "Is the Pope Catholic") Debug(@OFF) b = a + 4 See Also: ErrorMode, LastError Delay Pauses execution for a specified amount of time. Syntax: Delay (seconds) Parameters: seconds = integer seconds to delay (2 - 15) 73 WBL FUNCTION REFERENCE Returns: (integer) always @TRUE This function causes the currently-executing batch file to be suspended for the specified period of time. Seconds must be an integer between 2 and 15. Smaller or larger numbers will be adjusted accordingly. Example: Message("Wait", "About 15 seconds") Delay(15) Message("Hi", "I'm Baaaaaaack") See Also: Yield DialogBox Pops up a Windows dialog box defined by the WBD template file. Syntax: DialogBox ("title", "WBD file") Parameters: "title" = the title of the dialog box. "WBD file" = the name of the WBD template file. Returns: (integer) always 0. Each element in the template file is enclosed in square brackets, and consists of a variable name, followed by one of the following symbols: Symbol Meaning Example + check box [backup+1Save backup] # edit box [newfile# ] \ file selection listbox [editfile\ ] ^ radio button [prog^1Note] [prog^2Write] $ variable [var$] 74 WBL FUNCTION REFERENCE The number following the check box and radio button symbols is the value which will get assigned to the variable if its corresponding box is checked, or button is selected. Following the number is the descriptive text which will appear next to the box or button. When used in conjunction with a file selection list box variable with the same name, two of these symbols have special meanings: # file mask edit box [editfile# ] $ directory variable [editfile$ ] Anything not appearing within square brackets is displayed as text. Example: [editfile$ ] File mask [editfile# ] [editfile\ ] [editfile\ ] [editfile\ ] [editfile\ ] [editfile\ ] [backup+1Save backup of file] [prog^1Notepad] [prog^2WinEdit] See Also: Manual section on the DialogBox function (pg. 31). DirChange Changes the current directory. Can also log a new drive. Syntax: DirChange ([d:]path) Parameters: "[d:]" = an optional disk drive to log onto. "path" = the desired path. Returns: (integer) @TRUE if directory was changed; @FALSE if the path could not be found. 75 WBL FUNCTION REFERENCE Use this function to change the current working directory to another directory, either on the same or a different disk drive. Example: DirChange("c:\") TextBox("This is your CONFIG.SYS file", "config.sys") See Also: DirGet, DirHome, LogDisk DirGet Gets the current working directory. Syntax: DirGet ( ) Parameters: (none) Returns: (string) = current working directory. Use this function to determine which directory we are currently in. It's especially useful when changing drives or directories temporarily. Example: ; Get, then restore current working directory origdir = DirGet() DirChange("c:\") FileCopy("config.sys", "%origdir%xxxtemp.xyz", @FALSE) DirChange(origdir) See Also: DirHome 76 WBL FUNCTION REFERENCE DirHome Returns directory containing the WinBatch executable files. Syntax: DirHome ( ) Parameters: (none) Returns: (string) pathname of the home directory. Use this function to determine the location of WINBATCH.EXE. Example: a = DirHome() Message("WinBatch Executable is in ", a) See Also: DirGet DirItemize Returns a space-delimited list of directories. Syntax: DirItemize (dir-list) Parameters: "dir-list" = a string containing a set of subdirectory names, which may be wildcarded. Returns: (string) list of directories. This function compiles a list of subdirectories and separates the names with spaces. 77 WBL FUNCTION REFERENCE This is especially useful in conjunction with the ItemSelect function, which enables the user to choose an item from such a space-delimited list. DirItemize("*.*") returns all dirs Example: a = DirItemize("*") ItemSelect("Directories", a, " ") See Also: FileItemize, WinItemize, ItemSelect DirMake Creates a new directory. Syntax: DirMake ([d:]path) Parameters: "[d:]" = the desired disk drive. "path" = the path to create. Returns: (integer) @TRUE if the directory was successfully created; @FALSE if it wasn't. Use this function to create a new directory. Example: DirMake("c:\xxxstuff") See Also: DirRemove, DirRename 78 WBL FUNCTION REFERENCE DirRemove Removes a directory. Syntax: DirRemove (dir-list) Parameters: "dir-list" = a space-delimited list of directory pathnames. Returns: (integer) @TRUE if the directory was successfully removed; @FALSE if it wasn't. Use this function to delete directories. You can delete one or more at a time by separating directory names with spaces. You cannot, however, use wildcards. Examples: DirRemove("c:\xxxstuff") DirRemove("tempdir1 tempdir2 tempdir3") See Also: DirMake, DirRename DirRename Renames a directory. Syntax: DirRename ([d:]oldpath, [d:]newpath) Parameters: "oldpath" = existing directory name, with optional drive. "newpath" = new name for directory. 79 WBL FUNCTION REFERENCE Returns: (integer) @TRUE if the directory was successfully renamed; @FALSE if it wasn't. Example: DirRename("c:\temp", "c:\work") See Also: DirMake, DirRemove DiskFree Finds the total space available on a group of drives. Syntax: DiskFree (drive-list) Parameters: "drive-list" = at least one drive letter, separated by spaces. Returns: (integer) the number of bytes available on all the specified drives. This function takes a string consisting of drive letters, separated by spaces. Only the first character of each non-blank group of characters is used to determine the drives, so you can use just the drive letters, or add a colon (:), or add a backslash (\), or even a whole pathname, and still get a perfectly valid result. Example: size = DiskFree("c d") Message("Space Available on C: & D:", size) See Also: FileSize 80 WBL FUNCTION REFERENCE Display Displays a message to the user for a specified period of time. Syntax: Display (seconds, title, text) Parameters: seconds = integer seconds to display the message (1-15). "title" = title of the window to be displayed. "text" = text of the window to be displayed. Returns: (integer) always @TRUE. Use this function to display a message for a few seconds, and then continue processing without user input. Seconds must be an integer between 1 and 15. Smaller or larger numbers will be adjusted accordingly. The display box may be prematurely canceled by the user by clicking a mouse button, or hitting any key. Example: Display(3, "Current window is", WinGetActive()) See Also: Pause, Message DOSVersion Returns the version numbers of the current version of DOS. Syntax: DOSVersion (level) Parameters: level = @MAJOR or @MINOR. 81 WBL FUNCTION REFERENCE Returns: (integer) integer or decimal part of DOS version number. @MAJOR returns the integer part (to the left of the decimal). @MINOR returns the decimal part (to the right of the decimal). If the version of DOS in use is 4.0, then: DOSVersion(@MAJOR) == 4 DOSVersion(@MINOR) == 0 Example: i = DOSVersion(@MAJOR) d = DOSVersion(@MINOR) If StrLen(d) == 1 Then d = StrCat("0", d) Message("DOS Version", "%i%.%d%") See Also: Environment, Version, WinVersion Drop Removes variables from memory. Syntax: Drop (var, [var]...) Parameters: var = variable names to remove. Returns: (integer) always @TRUE. This function removes variables from the language processor's variable list, and recovers the memory associated with the variable (and possibly related string storage). 82 WBL FUNCTION REFERENCE Example: a = "A variable" b = "Another one" Drop(a, b) ; This removes A and B from memory EndSession Ends the Windows session. Syntax: EndSession ( ) Parameters: (none) Returns: (integer) always 0. Use this command to end the Windows session. This command is equivalent to closing the Program Manager window. Example: sure = AskYesNo ("End Session", "You SURE you want to exit Windows?") If sure == @No Then Goto cancel EndSession() :cancel Message("", "Exit Windows canceled") See Also: Exit, WinClose, WinCloseNot Environment Gets a DOS environment variable. 83 WBL FUNCTION REFERENCE Syntax: Environment (env-variable) Parameters: "env-variable" = any defined environment variable. Returns: (string) environment variable contents. Use this function to query the DOS environment. Example: ; Display the PATH for this DOS session currpath = Environment("PATH") Message("Current DOS Path", currpath) See Also: IniRead, Version, WinVersion ErrorMode Specifies how to handle errors. Syntax: ErrorMode (mode) Parameters: mode = @CANCEL or @NOTIFY or @OFF. Returns: (integer) previous error setting. Use this function to control the effects of runtime errors. The default is @CANCEL, meaning the execution of the batch file will be canceled for any error. @CANCEL: All runtime errors will cause execution to be canceled. The user will be notified which error occurred. 84 WBL FUNCTION REFERENCE @NOTIFY: All runtime errors will be reported to the user, and the user 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. In general, we suggest the normal state of the program should be ErrorMode(@CANCEL), especially if you are writing a batch file for others to use. You can always suppress errors you expect will occur and then re-enable ErrorMode (@CANCEL). Example: ; Delete xxxtest.xyz. If file doesn't exist, ; continue execution; don't stop prevmode = ErrorMode(@OFF) FileDelete("c:\xxxtest.xyz") ErrorMode(prevmode) See Also: Debug, LastError Execute Executes a statement in a protected environment. Any errors encountered are recoverable. Syntax: Execute statement Parameters: "statement" = is (hopefully) an executable statement. Use this command to execute computed or user-entered statements. Due to the built-in error recovery associated with Execute, it is ideal for interactive execution of user-entered commands. Note that the Execute command doesn't operate on a string, per se, but rather on a direct statement. If you want to put a code segment into a string variable, you must use the substitution feature of the language, as in the example below. 85 WBL FUNCTION REFERENCE Example: cmd = "" cmd = AskLine("WBL Interactive", "Command:", cmd) Execute %cmd% Exit Terminates the batch file being interpreted. Syntax: Exit Use this command to prematurely exit a batch file process. An exit is implied at the end of each batch file. Example: a = 100 Message("The value of a is", a) Exit See Also: Pause Exclusive Controls whether or not other Windows programs will get any time to execute. Syntax: Exclusive (mode) Parameters: mode = @ON or @OFF. Returns: (integer) previous Exclusive mode. 86 WBL FUNCTION REFERENCE Exclusive(@OFF) is the default mode. In this mode,WinBatch is well- behaved toward other Windows applications. Exclusive(@ON) allows WinBatch files to run somewhat faster, but causes WinBatch to be "greedier" about sharing processing time with other active Windows applications. For the most part, this mode is useful only when you have a series of WinBatch statements which must be executed in quick succession. Example: Exclusive(@ON) x = 0 start = DateTime() :add x = x + 1 If x < 1000 Then Goto add stop = DateTime() crlf = StrCat(Num2Char(13), Num2Char(10)) Message("Times", "Start: %start%%crlf%Stop: %stop%") Exclusive(@OFF) FileAppend Appends one or more files to another file. Syntax: FileAppend (source-list, destination) Parameters: "source-list" = a string containing one or more filenames, which may be wildcarded. "destination" = target file name. Returns: (integer) @TRUE if all files were appended successfully; @FALSE if at least one file wasn't appended. Use this function to append an individual file or a group of files to the end of an existing file. If "destination" does not exist, it will be created. 87 WBL FUNCTION REFERENCE The file(s) specified in "source-list" will not be modified by this function. "Source-list" may contain * and ? wildcards. "Destination" may not contain wildcards of any type; it must be a single file name. Examples: FileAppend("c:\config.sys", "c:\misc\config.sav") DirChange("c:\batch") FileDelete("allbats.fil") FileAppend("*.bat", "allbats.fil") See Also: FileCopy, FileDelete, FileExist FileClose Closes a file. Syntax: FileClose (filehandle) Parameters: filehandle = same integer that was returned by FileOpen. Returns: (integer) always 0. Example: ; the hard way to copy an ASCII file old = FileOpen("config.sys", "READ") new = FileOpen("sample.txt", "WRITE") :top x = FileRead(old) If x != "*EOF*" Then FileWrite(new, x) If x != "*EOF*" Then Goto top FileClose(new) FileClose(old) 88 WBL FUNCTION REFERENCE See Also: FileOpen, FileRead, FileWrite FileCopy Copies files. Syntax: FileCopy (source-list, destination, warning) Parameters: "source-list" = a string containing one or more filenames, which may be wildcarded. "destination" = target file name. warning = @TRUE if you want a warning before overwriting existing files; @FALSE if no warning desired. Returns: (integer) @TRUE if all files were copied successfully; @FALSE if at least one file wasn't copied. Use this function to copy an individual file, a group of files using wildcards, or several groups of files by separating the names with spaces. You can also copy files to any COM or LPT device. "Source-list" may contain * and ? wildcards. "Destination" may contain the * wildcard only. Examples: FileCopy("c:\config.sys", "d:", @FALSE) FileCopy("c:\*.sys", "d:devices\*.sys", @TRUE) FileCopy("c:\config.sys", "LPT1:", @FALSE) 89 WBL FUNCTION REFERENCE See Also: FileDelete, FileExist, FileLocate, FileMove, FileRename FileDelete Deletes files. Syntax: FileDelete (file-list) Parameters: "file-list" = a string containing one or more filenames, which may be wildcarded. Returns: (integer) @TRUE if all the files were deleted; @FALSE if a file didn't exist or is marked with the READ-ONLY attribute. Use this function to delete an individual file, a group of files using wildcards, or several groups of files by separating the names with spaces. Example: FileDelete("*.bak temp???.fil") See Also: FileExist, FileLocate, FileMove, FileRename FileExist Tests for the existence of files. Syntax: FileExist (filename) 90 WBL FUNCTION REFERENCE Parameters: "filename" = either a fully qualified filename with drive and path, or just a filename and extension. Returns: (integer) @TRUE if the file exists; @FALSE if it doesn't or if the pathname is invalid. This function is used to test whether or not a specified file exists. If a fully-qualified file name is used, only the specified drive and directory will be checked for the desired file. If only the root and extension are specified, then first the current directory is checked for the file, and then, if the file is not found in the current directory, all directories in the DOS path are searched. Examples: ; check for file in current directory fex = FileExist(StrCat(DirGet(), "myfile.txt")) tex = StrSub("NOT", 1, StrLen("NOT") * fex) Message("MyFile.Txt"," Is %tex%in the current directory") ; check for file someplace along path fex = FileExist("myfile.txt") tex = StrSub("NOT", 1, StrLen("NOT") * fex) Message("MyFile.Txt", " Is %tex% in the DOS path") See Also: FileLocate FileExtension Returns extension of file. Syntax: FileExtension (filename) Parameters: "filename" = [optional path]complete file name, with extension. 91 WBL FUNCTION REFERENCE Returns: (string) file extension. FileExtension parses the passed filename and returns the extension part of the filename. Example: ; prevent the user from editing a COM or EXE file allfiles = FileItemize("*.*") editfile = ItemSelect("Select file to edit", allfiles, " ") ext = FileExtension(editfile) If (ext == "com") || (ext == "exe") Then Goto noedit run("notepad.exe", editfile) exit :noedit Message ("Sorry", "You may not edit a program file") See Also: FileRoot, FilePath FileItemize Returns a space-delimited list of files. Syntax: FileItemize (file-list) Parameters: "file-list" = a string containing a list of filenames, which may be wildcarded. Returns: (string) space-delimited list of files. This function compiles a list of filenames and separates the names with spaces. 92 WBL FUNCTION REFERENCE This is especially useful in conjunction with the ItemSelect function, which lets the user choose an item from such a space-delimited list. Examples: FileItemize("*.bak") ; all BAK files FileItemize("*.arc *.zip *.lzh") ; compressed files ; Get which .INI file to edit ifiles = FileItemize("c:\windows\*.ini") ifile = ItemSelect(".INI Files", ifiles, " ") RunZoom("notepad", ifile) Drop(ifiles, ifile) See Also: DirItemize, WinItemize, ItemSelect FileLocate Finds file in current directory or along the DOS path. Syntax: FileLocate (filename) Parameters: "filename" = root name, ".", and extension. Returns: (string) fully-qualified path name. This function is used to obtain the fully qualified path name of a file. The current directory is checked first, and if the file is not found, the DOS path is searched. The first occurrence of the file is returned. 93 WBL FUNCTION REFERENCE Example: ; Edit WIN.INI winini = FileLocate("win.ini") If winini == "" Then Goto notfound Run("notepad.exe", winini) Exit :notfound Message("???", "WIN.INI not found") See Also: FileExist FileMove Moves files. Syntax: FileMove (source-list, destination, warning) Parameters: "source-list" = one or more filenames separated by spaces. "destination" = target filename. warning = @TRUE if you want a warning before overwriting existing files; @FALSE if no warning desired. Returns: (integer) @TRUE if the file was moved; @FALSE if the source file was not found or had the READ-ONLY attribute, or target filename is invalid. Use this function to move an individual file, a group of files using wildcards, or several groups of files by separating the names with spaces. You can also move files to another drive, or to any COM or LPT device. "Source-list" may contain * and ? wildcards. "Destination" may contain the * wildcard only. 94 WBL FUNCTION REFERENCE Examples: FileMove("c:\config.sys", "d:", @FALSE) FileMove("c:\*.sys", "d:*.sys", @TRUE) See Also: FileCopy, FileDelete, FileExist, FileLocate, FileRename FileOpen Opens a STANDARD ASCII (only) file for reading or writing. Syntax: FileOpen (filename, open-type) Parameters: "filename" = name of the file to open. open-type = READ or WRITE. Returns: (special integer) filehandle The "filehandle" returned by the FileOpen function is subsequently used by the FileRead, FileWrite, and FileClose functions. Examples: ; To open for reading: FileOpen("stuff.txt", "READ") ; To open for writing: FileOpen("stuff.txt", "WRITE") See Also: FileClose, FileRead, FileWrite 95 WBL FUNCTION REFERENCE FilePath Returns path of file. Syntax: FilePath (filename) Parameters: "filename" = fully qualified file name, including path. Returns: (string) fully qualified path name. FilePath parses the passed filename and returns the drive and path of the file specification, if any. Example: coms = Environment("COMSPEC") compath = FilePath(coms) Message("", "Your command processor is located in the %compath% directory") See Also: FileRoot, FileExtension FileRead Reads data from a file. Syntax: FileRead (filehandle) Parameters: filehandle = same integer that was returned by FileOpen. Returns: (string) line of data read from file. 96 WBL FUNCTION REFERENCE When the end of the file is reached, the string *EOF* will be returned. Example: handle = FileOpen("autoexec.bat", "READ") :top line = FileRead(handle) Display(4, "AUTOEXEC DATA", line) If line != "*EOF*" Then Goto top FileClose(handle) See Also: FileOpen, FileClose, FileWrite FileRename Renames files. Syntax: FileRename (source-list, destination) Parameters: "source-list" = one or more filenames, separated by spaces. "destination" = target filename. Returns: (integer) @TRUE if the file was renamed; @FALSE if the source file was not found or had the READ-ONLY attribute, or target filename is invalid. Use this function to rename an individual file, a group of files using wildcards, or several groups of files by separating the names with spaces. Note: Unlike FileMove, you cannot make a file change its resident disk drive with FileRename. "Source-list" may contain * and ? wildcards. "Destination" may contain the * wildcard only. 97 WBL FUNCTION REFERENCE Examples: FileRename("c:\config.sys", "config.old") FileRename("c:\*.txt", "*.bak") See Also: FileCopy, FileExist, FileLocate, FileMove FileRoot Returns root of file. Syntax: FileRoot (filename) Parameters: "filename" = [optional path]complete file name, with extension. Returns: (string) file root. FileRoot parses the passed filename and returns the root part of the filename. Example: allfiles = FileItemize("*.*") editfile = ItemSelect("Select file to edit", allfiles, " ") root = FileRoot(editfile) ext = FileExtension(editfile) lowerext = StrLower(ext) nicefile = StrCat(root, ".", lowerext) Message("", "You are about to edit %nicefile%.") Run("notepad.exe", editfile) See Also: FileExtension, FilePath 98 WBL FUNCTION REFERENCE FileSize Finds the total size of a group of files. Syntax: FileSize (file-list) Parameters: "file-list" = zero or more filenames, separated by spaces. Returns: (integer) total bytes taken up by the specified files. This function returns the total size of the specified files. Note that it doesn't handle wildcarded filenames. You can, however, use FileItemize on a wildcarded filename and use the resulting string as a FileSize parameter. Example: size = FileSize(FileItemize("*.*")) Message("Size of All Files in Directory", size) See Also: DiskFree FileWrite Writes data to a file. Syntax: FileWrite(filehandle, output-data) Parameters: filehandle = same integer that was returned by FileOpen. "output-data" = data to write to file. 99 WBL FUNCTION REFERENCE Returns: (integer) always 0. Example: handle = FileOpen("stuff.txt", "WRITE") FileWrite(handle, "Gobbledygook") FileClose(handle) See Also: FileOpen, FileClose, FileRead Goto Changes the flow of control in a batch file. Syntax: Goto label Parameters: "label" = user-defined identifier. Goto label causes an unconditional branch to the batch file line marked :label, where the identifier is preceded by a colon (:). Example: If WinExist("Solitaire") == @FALSE Then Goto open WinActivate("Solitaire") Goto loaded :open Run("sol.exe", "") :loaded See Also: If ... Then 100 WBL FUNCTION REFERENCE If...Then Conditionally performs a function. Syntax: If condition Then statement Parameters: "condition" = an expression to be evaluated. "statement" = any valid WinBatch function or command. If the condition following the If keyword is true, the statement following the Then keyword is executed. If the condition following the If keyword is false, the statement following the Then keyword is ignored. Example: sure = AskYesNo("End Session", "Really quit Windows?") If sure == @YES Then EndSession() See Also: Goto IgnoreInput Turns off hardware input to windows. Syntax: IgnoreInput(mode) Parameters: mode = @TRUE or @FALSE. Returns: (integer) previous IgnoreInput mode. IgnoreInput causes mouse movements, clicks and keyboard entry to be completely ignored. Good for self-running demos. 101 WBL FUNCTION REFERENCE Warning: If you are not careful with the use of IgnoreInput, you can lock up your computer! Example: username = AskLine("Hello", "Please enter your name","") IgnoreInput(@TRUE) Call("demo.wbt", username) IgnoreInput(@FALSE) IniRead Reads data from the WIN.INI file. Syntax: IniRead (section, keyname, default) Parameters: "section" = the major heading to read the data from. "keyname = the name of the item to read. "default" = string to return if the desired item is not found. Returns: (string) data from WIN.INI file. This function allows a program to read data from the WIN.INI file. The WIN.INI file has the form: [section] keyname=settings Most of the entries in WIN.INI are set from the Windows Control Panel program, but individual applications can also use it to store option settings in their own sections. Example: ; Find the default output device a = IniRead("windows", "device", "No Default") Message("Default Output Device", a) 102 WBL FUNCTION REFERENCE See Also: IniWrite, IniReadPvt, IniWritePvt, Environment IniReadPvt Reads data from a private INI file. Syntax: IniReadPvt (section, keyname, default, filename) Parameters: "section" = the major heading to read the data from. "keyname = the name of the item to read. "default" = string to return if the desired item is not found. "filename" = name of the INI file. Returns: (string) data from the INI file. Looks up a value in the "filename".INI file. If the value is not found, the "default" will be returned. Example: IniReadPvt("Main", "Lang", "English", "WB.INI") Given the following segment from WB.INI: [Main] Lang=French The batch file line above would return: French See Also: IniWritePvt, IniRead, IniWrite 103 WBL FUNCTION REFERENCE IniWrite Writes data to the WIN.INI file. Syntax: IniWrite (section, keyname, data) Parameters: "section" = major heading to write the data to. "keyname = name of the data item to write. "data" = string to write to the WIN.INI file. Returns: (integer) always @TRUE. This command allows a program to write data to the WIN.INI file. The "section" is added to the file if it doesn't already exist. Example: ; Change the list of pgms to load upon Windows ; startup loadprogs = IniRead("windows", "load", "") newprogs = AskLine("Add Pgm To LOAD= Line", "Add:", loadprogs) IniWrite("windows", "load", newprogs) See Also: IniRead, IniReadPvt, IniWritePvt IniWritePvt Writes data to a private INI file. Syntax: IniWritePvt (section, keyname, data, filename) Parameters: "section" = major heading to write the data to. "keyname = name of the data item to write. "data" = string to write to the INI file. 104 WBL FUNCTION REFERENCE "filename" = name of the INI file. Writes a value in the "filename".INI file. Example: IniWritePvt("Main", "Lang", "French, "WB.INI") This would create the following entry in WB.INI: [Main] Lang=French See Also: IniReadPvt, IniRead, IniWrite IsDefined Determines if a variable name is currently defined. Syntax: IsDefined (var) Parameters: "var" = a variable name. Returns: (integer) @YES if the variable is currently defined; @NO if it was never defined or has been dropped. A variable is defined the first time it appears at the left of an equal sign in a statement. It stays defined until it is explicitly dropped with the Drop function, or until the batch file ends. Example: def = IsDefined(thisvar) If def == @FALSE Then Message("ERROR!", "Variable not defined") See Also: Drop 105 WBL FUNCTION REFERENCE IsKeyDown Tells about keys/mouse. Syntax: IsKeyDown(keycodes) Parameters: keycodes = @SHIFT and/or @CTRL Returns: (integer) @YES if the key is down. @NO if the key is not down. Determines if the Shift key or the Ctrl key is currently down. Note: The right mouse button is the same as Shift, and the middle mouse button is the same as Ctrl. Examples: IsKeyDown(@SHIFT) IsKeyDown(@CTRL) IsKeyDown(@CTRL | @SHIFT) IsKeyDown(@CTRL & @SHIFT) IsLicensed Tells if WinBatch is licensed. Syntax: IsLicensed() Parameters: (none) 106 WBL FUNCTION REFERENCE Returns: (integer) @YES if current version of WinBatch is licensed. @NO if current version of WinBatch is not licensed. Returns information on whether or not the current version of WinBatch is a licensed copy. Example: IsLicensed() IsNumber Determines whether a variable contains a valid number. Syntax: IsNumber (string) Parameters: "string" = string to test to see if it represents a valid number. Returns: (integer) @YES if it contains a valid number; @NO if it doesn't. This function determines if a string variable contains a valid integer. Useful for checking user input prior to using it in computations. Example: a = AskLine("ISNUMBER", "Enter a number", "0") If IsNumber(a) == @NO Then Message("", "You didn't enter a number") See Also: Abs, Char2Num 107 WBL FUNCTION REFERENCE ItemCount Returns the number of items in a list. Syntax: ItemCount (list, delimiter) Parameters: "list" = a string containing a list of items to choose from. "delimiter" = a string containing the character to act as delimiter between items in the list. Returns: (integer) the number of items in the list. If you create the list with the FileItemize or DirItemize functions you will be using a space-delimited list. WinItemize, however, creates a tab-delimited list of window titles since titles can have embedded blanks. Example: a = FileItemize("*.*") n = ItemCount(a, " ") Message("Note", "There are %n% files") See Also: DirItemize, FileItemize, WinItemize, ItemExtract, ItemSelect ItemExtract Returns the selected item from a list. Syntax: ItemExtract (select, list, delimiter) Parameters: select = the position in "list" of the item to be selected. "list" = a string containing a list of items to choose from. 108 WBL FUNCTION REFERENCE "delimiter" = a string containing the character to act as delimiter between items in the list. Returns: (string) the selected item. If you create the list with the FileItemize or DirItemize functions you will be using a space-delimited list. WinItemize, however, creates a tab-delimited list of window titles since titles can have embedded blanks. Example: bmpfiles = FileItemize("*.bmp") bmpcount = ItemCount(bmpfiles, " ") pos = (Random(bmpcount - 1)) + 1 paper = ItemExtract(pos, bmpfiles, " ") Wallpaper(paper, @FALSE) See Also: DirItemize, FileItemize, WinItemize, ItemExtract, ItemSelect ItemSelect Allows the user to choose an item from a listbox. Syntax: ItemSelect (title, list, delimiter) Parameters: "title" = the title of dialog box to display. "list" = a string containing a list of items to choose from. "delimiter" = a string containing the character to act as delimiter between items in the list. Returns: (string) the selected item. This function displays a dialog box with a listbox inside. This listbox is filled with a sorted list of items taken from a string you provide to the function. 109 WBL FUNCTION REFERENCE Each item in the string must be separated ("delimited") by a character, which you also pass to the function. The user selects one of the items by either doubleclicking on it, or single-clicking and pressing OK. The item is returned as a string. If you create the list with the FileItemize or DirItemize functions you will be using a space-delimited list. WinItemize, however, creates a tab-delimited list of window titles since titles can have embedded blanks. Example: DirChange("c:\winword") alldotfiles = FileItemize("*.dot") dotfile = ItemSelect("W4W Templates", alldotfiles, " ") Run("winword.exe", dotfile) See Also: AskYesNo, Display, DirItemize, FileItemize, WinItemize, Message, Pause, TextBox, ItemCount, ItemExtract LastError Returns the most-recent error encountered during the current batch file. Syntax: LastError ( ) Parameters: (none) Returns: (integer) most-recent WBL error code encountered. WBL errors are numbered according to their severity. "Minor" errors go from 1000 through 1999. Moderate errors are 2000 through 2999. Fatal errors are numbered 3000 to 3999. 110 WBL FUNCTION REFERENCE Depending on which error mode is active when an error occurs, you may not get a chance to check the error code. See ErrorMode for a discussion of default error handling. Don't bother checking for "fatal" error codes. When a fatal error occurs, the batch file is canceled before the next WBL statement gets to execute (regardless of which error mode is active). Every time the LastError function is called, the "last error" indicator is reset to zero. A full listing of possible errors you can encounter in processing a batch file is in Appendix B (pg. 152). Example: ErrorMode(@OFF) FileCopy("data.dat", "c:\backups", @FALSE) ErrorMode(@CANCEL) If LastError() == 1006 Then Message("Error", "Please call Tech Support at 555-9999.") See Also: Debug, ErrorMode LogDisk Logs (activates) a disk drive. Syntax: LogDisk (drive-letter) Parameters: "drive-letter" = the disk drive to log into. Returns: (integer) @TRUE if the current drive was changed; @FALSE if the drive doesn't exist. Use this function to change the logged disk drive. 111 WBL FUNCTION REFERENCE This command produces the same effect as if you typed the drive name from the DOS command prompt. Example: LogDisk("c:") See Also: DirChange Max Returns largest number in a list of numbers. Syntax: Max (integer [, integer]...) Parameters: integer = an integer number. Returns: (integer) largest parameter. Use this function to determine the largest of a set of comma-delimited integers. Example: a = Max(5, -37, 125, 34, 2345, -32767) Message("Largest number is", a) See Also: Abs, Average, Min Message Displays a message to the user. 112 WBL FUNCTION REFERENCE Syntax: Message (title, text) Parameters: "title" = title of the message box. "text" = text to display in the message box. Returns: (integer) always @TRUE. Use this function to display a message to the user. The user must respond by selecting the OK button before processing will continue. Example: Message("Current directory is", DirGet()) See Also: Display, Pause Min Returns lowest number in a list of numbers. Syntax: Min (integer [, integer]...) Parameters: integer = an integer number. Returns: (integer) lowest parameter. Use this function to determine the lowest of a set of comma-delimited integers. 113 WBL FUNCTION REFERENCE Example: a = Min( 5, -37, 125, 34, 2345, -32767) Message("Smallest number is", a) See Also: Abs, Average, Max Num2Char Converts a number to its character equivalent. Syntax: Num2Char (integer) Parameters: number = any number from 0 to 255. Returns: (string) one-byte string containing the character the number represents. Use this function to convert a number to its ASCII equivalent. Example: ; Build a variable containing a CRLF combo crlf = StrCat(Num2Char(13), Num2Char(10)) Message("NUM2CHAR", StrCat("line1", crlf, "line2")) See Also: Char2Num ParseData Parses the passed string, just like passed parameters are parsed. 114 WBL FUNCTION REFERENCE Syntax: ParseData (string) Parameters: "string" = string to be parsed. Returns: (integer) number of parameters in "string". This function breaks a string constant or string variable into new sub-string variables named param1, param2, etc. Blank spaces in the original string are used as delimiters to create the new variables. Param0 is the count of how many sub-strings are found in "string". Example: username = AskLine("Hello", "Please enter your name","") ParseData(username) If the user enters: Joe Q. User ParseData would create the following variables: param1 == Joe param2 == Q. param3 == User param0 == 3 Pause Provides a message to user. User may cancel processing. Syntax: Pause (title, text) Parameters: "title" = title of pause box. "text" = text of the message to be displayed. 115 WBL FUNCTION REFERENCE Returns: (integer) always @TRUE. This function displays a message to the user with an exclamation point icon. The user may respond by selecting the OK button, or may cancel the processing by selecting Cancel. The Pause function is similar to the Message function, except for the addition of the Cancel button and icon. Example: Pause("Change Disks", "Insert new disk into Drive A:") See Also: Display, Message Random Computes a pseudo-random number. Syntax: Random (max) Parameters: max = largest desired integer number. Returns: (integer) unpredictable positive number. This function will return a random integer between 0 and "max". Example: a = Random(79) Message("Random number between 0 and 79", a) 116 WBL FUNCTION REFERENCE Return Used to return from a Call or a CallExt to the calling program. Syntax: Return If the program was not called, then an Exit is assumed. Example: Display(2, "End of subroutine", "Returning to MAIN.WBT") Return See Also: Call, CallExt, Exit Run Runs a program as a normal window. Syntax: Run (program-name, parameters) Parameters: "program-name" = the name of the desired .EXE, .COM, .PIF, .BAT file, or a data file. "parameters" = optional parameters as required by the application. Returns: (integer) @TRUE if the program was found; @FALSE if it wasn't. Use this command to run an application. If the drive and path are not part of the program name, the current directory will be examined first, and then the DOS path will be searched to find the desired executable file. 117 WBL FUNCTION REFERENCE If the "program-name" doesn't have an extension of .EXE, .COM, .PIF, or .BAT, it will be run in accordance with whatever is in the [extensions] section of the WIN.INI file. When this happens, any "parameters" you specified are ignored. Examples: Run("notepad.exe", "abc.txt") Run("clock.exe", "") Run("paint.exe", "pict.msp") See Also: RunHide, RunIcon, RunZoom, WinClose, WinWaitClose RunHide Runs a program as a hidden window. Syntax: RunHide (program-name, parameters) Parameters: "program-name" = the name of the desired .EXE, .COM, .PIF, .BAT file, or a data file. "parameters" = optional parameters as required by the application. Returns: (integer) @TRUE if the program was found; @FALSE if it wasn't. Use this command to run an application as a hidden window. If the drive and path are not part of the program name, the current directory will be examined first, and then the DOS path will be searched to find the desired executable file. If the "program-name" doesn't have an extension of .EXE, .COM, .PIF, or .BAT, it will be run in accordance with whatever is in the 118 WBL FUNCTION REFERENCE [extensions] section of the WIN.INI file. When this happens, any "parameters" you specified are ignored. Note: When this command launches an application, it informs it that you want it to run as a hidden window. Whether or not the application honors your wish is beyond RunHide's control. Examples: RunHide("notepad.exe", "abc.txt") RunHide("clock.exe", "") RunHide("paint.exe", "pict.msp") See Also: Run, RunIcon, RunZoom, WinHide, WinClose, WinWaitClose RunIcon Runs a program as an iconic (minimized) window. Syntax: RunIcon (program-name, parameters) Parameters: "program-name" = the name of the desired .EXE, .COM, .PIF, .BAT file, or a data file. "parameters" = optional parameters as required by the application. Returns: (integer) @TRUE if the program was found; @FALSE if it wasn't. Use this command to run an application as an icon. If the drive and path are not part of the program name, the current directory will be examined first, and then the DOS path will be searched to find the desired executable file. 119 WBL FUNCTION REFERENCE If the "program-name" doesn't have an extension of .EXE, .COM, .PIF, or .BAT, it will be run in accordance with whatever is in the [extensions] section of the WIN.INI file. When this happens, any "parameters" you specified are ignored. Note: When this command launches an application, it merely informs it that you want it to begin as an icon. Whether or not the application honors your wish is beyond RunIcon's control. Examples: RunIcon("notepad.exe", "abc.txt") RunIcon("clock.exe", "") RunIcon("paint.exe", "pict.msp") See Also: Run, RunHide, RunZoom, WinIconize, WinClose, WinWaitClose RunZoom Runs a program as a full-screen (maximized) window. Syntax: RunZoom (program-name, parameters) Parameters: "program-name" = the name of the desired .EXE, .COM, .PIF, .BAT file, or a data file. "parameters" = optional parameters as required by the application. Returns: (integer) @TRUE if the program was found; @FALSE if it wasn't. Use this command to run an application as a full-screen window. If the drive and path are not part of the program name, the current directory will be examined first, and then the DOS path will be searched to find the desired executable file. 120 WBL FUNCTION REFERENCE If the "program-name" doesn't have an extension of .EXE, .COM, .PIF, or .BAT, it will be run in accordance with whatever is in the [extensions] section of the WIN.INI file. When this happens, any "parameters" you specified are ignored. Note: When this command launches an application, it merely informs it that you want it to be maximized to full-screen. Whether or not the application honors your wish is beyond RunZoom's control. Examples: RunZoom("notepad.exe", "abc.txt") RunZoom("clock.exe", "") RunZoom("paint.exe", "pict.msp") See Also: Run, RunHide, RunIcon, WinZoom, WinClose, WinWaitClose SendKey Sends keystrokes to the active application. Syntax: SendKey (char-string) Parameters: "char-string" = string of regular and/or special characters. Returns: (integer) always 0. This function is used to send keystrokes to the current window, just as if they had been entered from the keyboard. Any alphanumeric character, and most punctuation marks and other symbols which appear on the keyboard, may be sent simply by placing it in the "char- string." In addition, the following special characters, enclosed in "curly" braces, may be placed in "char-string" to send the corresponding special characters: 121 WBL FUNCTION REFERENCE Key SendKey equivalent ~ {~} ! {!} ^ {^} + {+} Backspace {BACKSPACE} or {BS} Break {BREAK} Clear {CLEAR} Delete {DELETE} or {DEL} Down Arrow {DOWN} End {END} Enter {ENTER} or ~ Escape {ESCAPE} or {ESC} F1 through F16 {F1} through {F16} Help {HELP} Home {HOME} Insert {INSERT} Left Arrow {LEFT} Page Down {PGDN} Page Up {PGUP} Print Screen {PRTSC} Right Arrow {RIGHT} Space {SPACE} or {SP} Tab {TAB} Up Arrow {UP} To enter an Alt, Control, or Shift key combination, precede the desired character with one or more of the following symbols: Alt ! Control ^ Shift + To enter Alt-S: SendKey("!S") To enter Ctrl-Shift-F7: SendKey("^+{F7}") You may also repeat a key by enclosing it in braces, followed by a space and the total number of repetitions desired. To type 20 asterisks: 122 WBL FUNCTION REFERENCE SendKey("{* 20}") To move the cursor down 8 lines: SendKey("{DOWN 8}") It is possible to use SendKey to send keystrokes to a DOS application, but only if you are running Windows in 386 Enhanced mode. You would then transfer the keystrokes to the DOS application via the Clipboard. Examples: ; Start Notepad, and use *.* for filenames Run("notepad.exe", "") SendKey("!FO*.*~") ; run DOS batch file which starts our editor Run("edit.bat", "") ; wait 15 seconds for editor to load Delay(15) ; send Alt-F N to the clipboard ClipPut("!FN") ; paste contents of clipboard to DOS window SendKey("!{SP}EP") See Also: SKDebug SKDebug Controls how SendKey works Syntax: SKDebug(mode) Parameters: mode = @OFF Keystrokes sent to application. No debug file written. Default mode. @ON Keystrokes sent to application. Debug file written. @PARSEONLY Keystrokes not sent to application. Debug file written. 123 WBL FUNCTION REFERENCE Returns: (integer) previous SKDebug mode. This function allows you to direct the keystrokes generated by your SendKey statements to a disk file in addition to, or instead of, the application window. Normally, keystrokes are sent only to the application. If you specify SKDebug (@ON), keystrokes are sent to a disk file as well as to the application. If you specify SKDebug (@PARSEONLY), keystrokes are sent only to the disk file, and not to the application. SKDebug (@OFF) returns to the default mode. By default, the file which will receive the parsed keystrokes is named C:\@@SKDBUG.TXT. You can override this by making an entry in your WIN.INI file, under the heading [WinBatch]: [WinBatch] SKDFile=debug.fil where "debug.fil" is the filename, including complete path specification, that you want to receive the keystrokes. Example: Run("notepad.exe", "") SKDebug(@ON) SendKey("!FO*.*~") SKDebug(@OFF) See Also: SendKey StrCat Concatenates two or more strings. Syntax: StrCat (string1, string2[, stringN]...) Parameters: "string1", etc = at least two strings you want to "string" together (so to speak). 124 WBL FUNCTION REFERENCE Returns: (string) concatenation of the entire list of input strings. Use this command to stick character strings together, or to format display messages. Example: user = AskLine("Login", "Your Name:", "") Message("Login", StrCat("Hi, ", user)) ; note that this will do the same: Message("Login", "Hi, %user%") See Also: StrFill, StrFix, StrTrim StrCmp Compares two strings. Syntax: StrCmp (string1, string2) Parameters: "string1", "string2" = strings to compare. Returns: (integer) -1, 0, or 1; depending on whether string1 is less than, equal to, or greater than string2, respectively. Use this command to determine whether two strings are equal, or which precedes the other in an ANSI sorting sequence. Note: This command has been included for semantic completeness. The relational operators >, >=, ==, !=, <=, and < provide the same capability. 125 WBL FUNCTION REFERENCE Example: a = AskLine("STRCMP", "Enter a test line", "") b = AskLine("STRCMP", "Enter another test line", "") c = StrCmp(a, b) c = c + 1 d = StrSub("less than equal to greater than", c * 12, 12) ; Note that above string is grouped into 12-character ; chunks. ; Desired chunk is removed with the StrSub statement. Message("STRCMP", "%a% is %d% %b%") See Also: StriCmp, StrIndex, StrLen, StrScan, StrSub StrFill Creates a string filled with a series of characters. Syntax: StrFill (filler, length) Parameters: "filler" = a string to be repeated to create the return string. If the filler string is null, spaces will be used instead. length = the length of the desired string. Returns: (string) character string. Use this function to create a string consisting of multiple copies of the filler string concatenated together. Example: Message("My Stars", StrFill("*", 30)) See Also: StrCat, StrFix, StrLen, StrTrim 126 WBL FUNCTION REFERENCE StrFix Pads or truncates a string to a fixed length. Syntax: StrFix (base-string, pad-string, length) Parameters: "base-string" = string to be adjusted to a fixed length. "pad-string" = appended to "base-string" if needed to fill out the desired length. If "pad-string" is null, spaces are used instead. length = length of the desired string. Returns: (string) fixed size string. This function "fixes" the length of a string, either by truncating it on the right, or by appending enough copies of pad-string to achieve the desired length. Example: a = StrFix("Henry", " ", 15) b = StrFix("Betty", " ", 15) c = StrFix("George", " ", 15) Message("Spaced Names", StrCat(a, b, c)) See Also: StrFill, StrLen, StrTrim StriCmp Compares two strings without regard to case. Syntax: StriCmp (string1, string2) Parameters: "string1", "string2" = strings to compare. 127 WBL FUNCTION REFERENCE Returns: (integer) -1, 0, or 1; depending on whether string1 is less than, equal to, or greater than string2, respectively. Use this command to determine whether two strings are equal, or which precedes the other in an ANSI sorting sequence, when case is ignored. Example: a = AskLine("STRICMP", "Enter a test line", "") b = AskLine("STRICMP", "Enter another test line", "") c = StriCmp(a, b) c = c + 1 d = StrSub("less than equal to greater than", c * 12, 12) ; Note that above string is grouped into 12-character ; chunks. ; Desired chunk is removed with the StrSub statement. Message("STRICMP", "%a% is %d% %b%") See Also: StrCmp, StrIndex, StrLen, StrScan, StrSub StrIndex Searches a string for a substring. Syntax: StrIndex (string, sub-string, start, direction) Parameters: "string" = the string to be searched for a substring. "substring" = the string to look for within the main string. start = the position in the main string to begin search. The first character of a string is position 1. direction = the search direction. @FWDSCAN searches forward, while @BACKSCAN searches backwards. Returns: (integer) position of "sub-string" within "string"; 0 if not found. 128 WBL FUNCTION REFERENCE This function searches for a substring within a "target" string. Starting at the "start" position, it goes forward or backward depending on the value of the "direction" parameter. It stops when it finds the "substring" within the "target" string, and returns its position. A start position of 0 has special meaning depending on which direction you are scanning. For forward searches, zero indicates the search should start at the beginning of the string. For reverse searches, zero causes it to start at the end of the string. Example: instr = AskLine("STRINDEX", "Type a sentence:", "") start = 1 end = StrIndex(instr, " ", start, @FWDSCAN) If end == 0 Then Goto error Message("STRINDEX", StrCat("The first word is: ", StrSub(instr, start, end - 1)) Exit :error Message("Sorry...", "No spaces found") See Also: StrLen, StrScan, StrSub StrLen Provides the length of a string. Syntax: StrLen (string) Parameters: "string" = any text string. Returns: (integer) length of string. Use this command to determine the length of a string variable or expression. 129 WBL FUNCTION REFERENCE Example: myfile = AskLine("Filename", "File to process:", "") namlen = StrLen(myfile) If namlen > 13 Then Message("", "Filename too long!") See Also: StrFill, StrFix, StrIndex, StrScan, StrTrim StrLower Converts a string to lowercase. Syntax: StrLower (string) Parameters: "string" = any text string. Returns: (string) lowercase string. Use this command to convert a text string to lower case. Example: a = AskLine("STRLOWER", "Enter text", "") b = StrLower(a) Message(a, b) See Also: StriCmp, StrUpper StrReplace Replaces all occurances of a substring with another. 130 WBL FUNCTION REFERENCE Syntax: StrReplace (string, old, new) Parameters: "string" = string in which to search. "old" = target substring. "new" = replacement substring. Returns: (string) updated "string" with "old" replaced by "new" StrReplace scans the "string", searching for occurrences of "old" and replacing each occurrence with "new". Example: ; Copy all INI files to clipboard a = FileItemize("*.ini") crlf = StrCat(Num2Char(13), Num2Char(10)) b = StrReplace(a, " ", crlf) ClipPut(b) StrScan Searches string for occurrence of delimiters. Syntax: StrScan (string, delimiters, start, direction) Parameters: "string" = the string that is to be searched. "delimiters" = a string of delimiters to search for within "string". start = the position in the main string to begin search. The first character of a string is position 1. direction = the search direction. @FWDSCAN searches forward, while @BACKSCAN searches backwards. Returns: (integer) position of delimiter in string, or 0 if not found. 131 WBL FUNCTION REFERENCE This function searches for delimiters within a target "string". Starting at the "start" position, it goes forward or backward depending on the value of the "direction" parameter. It stops when it finds any one of the characters in the "delimiters" string within the target "string". Example: thestr = "123,456.789:abc" start = 1 end = StrScan(thestr, ",.:", start, @FWDSCAN) If end == 0 Then Goto error Message("The first parameter", StrSub(thestr, start, end - start + 1)) Exit :error Message("Sorry...", "No delimiters found") See Also: StrLen, StrSub StrSub Extracts a substring out of an existing string. Syntax: StrSub (string, start, length) Parameters: "string" = the string from which the substring is to be extracted. start = character position within "string" where the sub-string starts. (The first character of the string is at position 1). length = length of desired substring. If you specify a length of zero it will return a null string. Returns: (string) substring of parameter string. This function extracts a substring from within a "target" string. Starting at the "start" position, it copies up to "length" characters into the substring. 132 WBL FUNCTION REFERENCE Example: a = "My dog has fleas" animal = StrSub(a, 4, 3) Message("STRSUB", "My animal is a %animal%") See Also: StrLen, StrScan StrTrim Removes leading and trailing spaces from a character string. Syntax: StrTrim (string) Parameters: "string" = a string with unwanted spaces at the beginning and/or the end. Returns: (string) string devoid of leading and trailing spaces. Use this function to remove unwanted spaces from the beginning andition r. otrLen, Str start = Riwarl st0 (strpen tioIf you specify a length ihxample: thestrse thism Emrs in the "degth ihxample: u stion,th of a ading an 5xtr srDbe tLtioIf5 iT) eLtioIf5T tLtOi c ds any'erTriL "") fe i) SlowercasRth of strN.acb g withoo Ob subsSe firNt1ition che tion 1). trsO hin thortind u$b st0 (strpen tioIf you specify a length ihxample: thestrse thism Emrs in the "degth ihxample: u stion,th of a ading an 5xtr srDbe tLtioIf5 iT) eLtioIf5T tLtOi c ds any'erTriL "") fe i) 5StrTrim imal%casRth of hxample3e bf zero Als0EMample: b) eplaciand fe eeihxoS( li}Onn 17s t ds an "") fe i) Slo= any text string. L") SCAN) o8 Efc bsSei}On D Al8tion. iti O5xtSa(D Al8tion. itiion 1)r- oa imatrse (i c ds a = .gthe "degtdelim"etrSeuU 'ou5 iT) e hin thortiEcan imal%c devoid ero itlLower ( c 0 imatr Emrs8r "st ExM" a =g has stion,) 5.Vr EmpEmrsm aon 1)r- oa 0g. mrsm aon S kfR Efc db dpositEDS positiom1q text strSynf = Strxtri}Onn 17W beginntA&ihxoS(gin l pStrSubgSs = Sr3Eh thgSs = SNM" eaeKin l 1If5tringC StrSca[lipboard mTEgth lX dpositstrse "sBACullpOing. Ls B-= Forts. (Thny text - the end. Returns: (string) string devoid of leading and trailing spaces. Use this function to remove unwanted sp5 d s8r c devoid f ll S Sr3Eh t (str5 tLti See Also: Oingst a 0 N low7n 17s t ds nct ve istring o>7. 4 Ee unwan> a9Onn 1_rse "sBA rclipboar StrSub ' unnthism Emrs in the "degth ihxample: old, nZWE wit*oimal racts a sreploEh t (nnthismBrcasR leading and tratring devoidd/ol (Thnyinter unslu B ufom Lshxample: 4 =i, "Ebeginning andition r "su "st ExM" a =g has stion,) 5.Vr EmpEmrsm aon 1)r- oa 0g. mrsm aon S kfR Efc db dpositEDS positiom1q text strSynf = Strxtri}Onn 17W beginntA&ihxoS(gin l pStrSubgSs = Sr3Eh thgSs = SNM" eaeKin l 1If5tringC ith Emrs in th old, = Strxtrii (str5xtrib F4tiotC "degt lIsmBrcasR emove  R leaTri}OnncasrTrim nca ds any'r Strxtrii ( = SNM itstrsrScan, u t arRt2arRt2arRt2(gin ssm l8n w Ac+nd = a= ds nct ve istring o>7 5xtr srDbe tLtiB l 1 the Rr * ntri}Onn 17W beginntA&b]b 8eyl_d6tn ii (IsmBr =l ith Emrs in th old, = Strxtrii (str5xtrib dLtiB Stri = er iB Stri xtriL "") b]bb db dpositEDS the Rr * =l-R any'erTriL "") fe i) SlowerclD 5xtr t lIsn tioIf youRep fepecify fe i) SlowerclD 5xtr t lIsn tioIf youRep fepecify fe xtroFr Strxtrii ( DBI-fa lengtctionuRep l 1n within "string" where the S kD 5xtrve istrin hxoegikmb tLtie SlowerclD 5xtr t lIsn tioIf youRep fepecify fe i) SlowerclD 5xtr t lIsn tioIf youRep fepecify fe xtroFr Strxtrii ( DBI-fa lengtctionuRep l 1n within "string" where the S kD 5xtrve istriter in string, or 0 if not found. Use this command b = StrLithin trizAckward depending on the value of the "direction" parame ), ""Enter text", "") b = StrLower(a) Messaged tratr MesTPBrcasR emhQ(a, " ", crlf) ep fen tioIfn w G0blext", "") b = Sttring. ),r. oclD 5xtr t lIsn ti"str- = StrLo(rSu rM arg dpositEOdl 1n within "string ), ""Enter text", "") b = StrLower(a) Messaged tratr MesTPBrcasR emhQ(a, " ", crlf) ep fen tioIfn w G0blext", "") b = S MesTOb = SclD depending on the value oimaNH 4 =RENeginni Sr3Eh t:4' b afrSub Fr n tioIfm 1). hand tr' = SNM" Fr n ), 1n ' ahe bMesTPBrcasheNH 4 =REN WbgSsH 8i g Use this command b = SvalueR = SclDwithina afrSNng stringluAw)Edns: Embl Nn) e ep fen t a (string)gg), 4he "degtIsn ti"stAN)fssrdbSlowermoIfn wo b = St hxoS(gilsrDg ), Em _ im he RT tringlN.Vr Empak5xtr t lIsn tioIf youRep fepecify fe xtroFr Strxtrii ( DBI-fa lengtctionuRep l 1n within "string" whsr(giu aor=4 Str trigs. Use this function to remove unwanted spaces from the beginning ds any' rt" ep fen t a lr3Eeter. m 1). hand SNn -b = Sh Emrs in4 any' rt" ep4d feD P ep fen t -mrs in4 anon then t Ae "degtAngtctionon touAw)Ed WbgSsH ny'erTri1fR Q(a 4 =RENlhu)fa lengtcL6 lr3E ds a fe xtr this command b = SvEt R[ien ti"str a cs- 4 =RENlhu)fa lengtcL6 lr3E ds a fe nCrse ing ep fen t -mrs in4 anon then t8 ti"str T6B cs- 4 =RENlhu)fa lengtcL6 lr3E ds a S en4 anasR n8d angtcL6 SErLo(P t Ae "d"str Mrt"utr he smAfssrdbSlowANlhu)fa lengtcL6 lr3 dsca dgtcL6i Mdegth cify 5xtr n nteep fen sp5 tn4 engOt a 0 Nh EmrNlh 0 N tiob7 M OB ep f in th ols lr3E d lengt3ImIfm 1l anfe xtthDEEA At u ie'7LAn4 anasmmand b = SvEt R[ien ti"str a cs- 4 =RENlhu)fa lengtcL6 lr3E ds a fe nCrse ing ep fen t -mrs in4 anon then t8 ti"str T6B cs- 4 =RENlhu)fa lengtcL6 lr3tC fen suxtthDEOlengtsn tanonbNwANl4 lengtcL6g F Sllnwanted Ohin "sStrTr' n t -mu)fa lengt ti"str T6B c ", cDEEAify 5xtr l a lengt t8 Tn ouRep fsn tanot = SclDsn tanot = "st ExstO =RENlhu)d[ien a adsn tanot in th o Oingst a 0 N low7n 17s t ds nct ve istring o>7. 4 Ee unwan> a9Onn 1_rse "sBA rclipboar StrSub ' unnthism Emrs in the "degth ihxample: old, nZWE wit*oimal racts a sreploEh t enRep IH" eua)fa m unnthism Emr n tanoxt iFow7n 17s starunwatr' = SNM" in stringth xtroFrpI (str5 tLti See Also: Oingst a 0 N low7n 17s t starts. (The first character of the string is at anot fopi xtroFd-mrs in4 anon then t8 ti"str T6B cs- 4 =RENlhu)fa lengtcL6 lrrst StrSub Extracts a substring out oIan existing string. Syntax: StrSuter tex c 4 anon ractsh]F 1_rse Dify b0EMample: IrcasR emh2 olAngst a "string" where the sVL6 lrd 4 StrSuter clipboar non re "d'wA SyntaAmrs in theing. Mample: Irc1ce tion strinsTPBr Irc1ceFAc a F1ahihxPfom Lshxas s t nvl stpI = Sr3Eh thgSs = SNM" eaeKin l 1If5tringC ith Em. ia iT) d-mrs in[ero it will return a null string. t Returns: (string) substring of parameter string. This functiotaAmld SNn -Fiom1q cify 5xtrScan s = S G0bl (string) substring of trLen, r. ce the S lengtcL8 Ri (string this cmrsE Sr3Eh thgSs iaur40uKe. mal racts a sreploEh t en>e loEh t eneAng. (st iE upe'erTactsh]F Er iOerlf ravsy-msy-oed'wA i (string this coL6 a8Odeldhis funrrs in thr iOe0uKe.tOeT ), " hgSs tanr40uKmsy-oed g> I. m 1).OrDpetrinl~n>e .Oll~n>e iuoL6- 4dis cmrsErEt i leng starunwanni racts Tkr Tkt upe'elde Eunwafi EOll~n>es T7lem Tcts Tkrt8 then>e -hgSs Somatr ,cts EOTr not iE7s dETr e stri n tioIf->esr G0Cn"iing ed LS2-g,e'e.wer(a) Messaged tratr MesTPBrcasR emhQ(a, " ", crlf) ep fen tioIfn w G0blext", "") b = S MesTOb = SclD depending on ia iT)a iTbbleng t=en tistring) string devoid of leading and trailing spaces. tiohdntrDpet9 old, tion to remove unwanted spaces from the beginginning andition r. otrLen, Str start = Riwarl st0 (strpen)If you specify a length ihxample: s a rTrim tA& M iE7s 5- rt" ep4I Eunwafi Eilingmo Als0=ing%c devoi anaspen tioIf you specify a length ihxample: thestrse taces.=Onn "stAN)fssI G0Cn"i tratr ber( old, nZlf) ep fens Tkrt8 FAct anmove unwanted spaces from the beginginning andices fr01ip5 tnginemh r. ae "di LS2-g gin ng and trailing s8 d-mrs in[ero it will return a null string. t ReT imatr Emrs8r 5xtr srDbe tLtioIf5 iT) eLtioIf5T tLtOiiti string. t Eleng t=en t fe i) 5StrTrim imal%casRth of hxample3e bf zero Als0Ea: b) eplaciand fe eeihxoS( li}Onn 17s t ds ar- a len1$d b M iE7s P iEfy a lenCol ('eldecoen, Str start M" a =g se ing ep fen t -mrs in4 anonU1he t will rec< EO)Ed 7 ti"heingt*oimalring. h 1n wc- oa d iE7s 5- nFAc tnginls0=ing%c devoib emhrstrsrScan,D, " y 5xtanon t8 tieginning t=elext", " ti"str, d-mr ng. t kDbRo,ur- a len1$d b DNh Eilf)ingnt ds ReT imatr Emrs8r 5xr 0 if nb tp)-tLtioIf5 iT) 6- 4dis c l return a nu, c1ip5ext", "Lehere trizA t kutuofssI 1E7 1E7 1E7 rai eLtioIf5tthe begil,"hxamp ckbstri nFAc tnginrIrcasR ehtioIfn ed fy 5xtrScan p 7 s. (Thny text - the end. Returns: nd. Returns: [tuxt", " tiNe0ted spac Use this function to remove unwanted sp5 d s8r c devoid f ll S Sr3Eh t (str5 tLti See Also: Oingst a 0 N low7n 17s t ds nct t ds nct ve istring o>7. 4 Tkt upe'eld2k)Gep fepecipvs nct ve istring o>7. 4 Tkt upe'elU ks8r epecipvs in thfunrrs in thr idirecr Sr. b t ( = Extg. ing Iecipvan p dsR ao removes8r epecipvsks8t b = S MesTOb = Sclupe'eldi"stt tRi xtg. i c de nct mu)Tn4 ainginning anditn nct =nC ct urnTtt Ne08r he bePB l 1 (IsmBr ct urnTtt n=l5 7.>ol 0L6g Fhes ctr t pAct Dxart ng o>7.nteng sTPBrSaAmld SN3E t ds ng sTPBrSaAmld S c l tgth SaAm t8lZSnd F Er n ep t" at ne ct urnsmBr ("Ohii c de nct mu)Tn4 ainginning anditn nct =nC ct urnTtt Ne08r he bePB l 1 (IsmBr ct urnTtt n=l5 7.o mand b = SvEt R[ien ti"str a cstr z scipvs fet kDbRo,ur- a len1$d b bep f in xstO9tiod=t ur2 Mdegth a 2MesTPipr ia ii -g gin ne s ct -mrs int urnrlfe sMotion trs i rac) fet kDT 7S t" 5ile2ua8lZSn t 1r5r b = /r= Sc Ou5-n tioonLtigSet kTtt nEr tr n tu -afrSub tigSet kTtt -t8l tr n tu -afrSub tigSet kTtt -t8l tr n part Eleng t51ctsC1r5r ba ct ngt*oiL4n the Ttt T Ai7S Ohi tigsm7n he tu -afng akDbRo,ur- a len1$d mrcasR art t fen ti3I4ecr hat -n tmfet kDT :thism Eu ol od=t n s udT_>gsmr. n = S udT_>gsmrfTPBrSaAmld S c l tTPBrSeht A& u's wc-- am :tr ITtt T Ai7S Ohi tigsm7n h 4dis c alring dn t o>7.o first cui=yet characuS a leg. intuu*'s wc-- am :tm alring m :tro S le ds aoa l fe sMoti Re aigsw7n h 4lu fatuSfynt urn7n h 4lu fatO im he SoeCt Dxart anwan> a9Onn 1c l tTPBrSed existing string. uS a leg. intuu*'s wc-- am :tm alring m :tro S le ds aoa l fe sMoti Re aigsw7n h 4lu fatuSfynt urn7n h 4lu fatO imtAngtctionon touAw)Ed WbgSsH ny'erTri1fR Q(a | ndu faengpc l -- amsf intuu*'s wc-- am :tmol od= (s m :tro :tmoaengpc lgy'erTri1fRhGD existing u(a he SoeCt fe nCrseEst aI =g se ing ep fen t -mrs in4 anonU1he t willT-tanot =lhu)fa len) h:tmold2hT-tanotmolnfa lendLl (st's wc-- pI (sttO =RENlh upe'LLl (sspa(a, " ", ceg. intuu*'s wc-- am :tm alring m :tro S le ds aoa l A kE rn7n 4dis c nfatgkengesTOb = SaNlhn  'erTrirTrrirTrrihu4nfa gkeng fensspa(a, l --Op m ur kE rexisttiod=l anample:T E veart t f istrF G0blext", "") Ineldring o>7.>ol 0L6g Fhes ctr t pAct Dxart ng o>7.nteng sTPBrSaAmld SN3E t ds ng sTPBrSaAmld S c l tgth S1 tanot ng out oIRi (striro S$orIrcasR 3 drTri kTtt -blext", ""kTt 5- rt" EgA t51n7n 4gSet kTtt -t8l tr nros)1Fct ur) l xtg. ienge4l tr n part Eleng dsca d  'erTrirT dsca ds aoa l A a let EleTc b) eplaciand2l>olizAc b) (Thns aItrinl~n> A a Bdstingb existin b DNh Eill lF8s c ed. b DNh EiFAc ks8eturns: [tu ingb exi staample: [9$o9$oSr a cstr z scipvs fet kDbRo,uret kDbRo,urE7s HTn4 aingi iEf z kTt 5- r ng o>7 bEfi EOll~n>es T7l8t pActvs -hgu ingb exi staamp g-SRart = Rio t kDxRo,ur=t ursy-msyrs8r fm h A sA sA sA svl stpI kTt 5- r n tmf gEleg. ict ng sTfgA t5hart t It", "iEf z kTt 5- r ng o>7 bEf t -Moti Reivy t6Pr fm h5- r nnniGPr fm h5-i5at aRo,ur=t ( =i svl stpI kTt 5- r m gEleg. leg. r ng ofpSoeCtEleng o>7 bELbEf t -Moti Reivn touAw ai t -MotixfRu ingb esTfTfTfTfTfTfTfT b , ltlnCi hst eLttlnCi slen fm h A sp fdo Sing hxamtTc b) ( =,cts ittlnCi stTc b) (Emple:Tf. r ng oe n akDbR sp iasR ar kTt 5- r fi t -mrA sp tOct lEs functiurnTtt -t8l CdelTts ct -nct =nwf4lu 0F8s Aw)lD4>7n 4dis ol 0L6g f h A  =RbEf ttr nnniing string. uS a leg. intuu*'s ecicipvrn7n lextDbRE El4/DHvan s2I==t ( =i svl stpI kTt 5- r m gEleg. leg. r ng ofpSoeCtEleng o>7 bELbEf t -Moti Reivn touAw ai t -MotixfRu ingb esTfTfTfTfTfTfTfT b , ltlnCi hst eLttlnCi slen fm h A sp fdo Sing hxamtTc b) ( =,cts ittlnCi stEill lF8s c ed. i feno firsRatuSfyntou ingb esTf8-t8l CdelT)2string. th cu =strlnCtTc blTnCtixfRu4pvsEhl8t1lveart t fen touATitr t pAct lE)6lala =ste :tm ( =t5nxfRb) ( =,g ) =,cts it ofptixfRu4pvsEu9t urnT ng oe -geng o>7 m o>7X- Tk tngifm ki b EOll~n-Moti otioncTg-DbRE El4/ nnniing string. D4>7n (st's CMotixfRc nT nSSr fte :tm ucsEhl8t3e bf ze G0bID4>7n (st's CMotixfRc nT nSSr fte :tm ucsEhl8t3e bf ze G0bID4>7n (st's CMotixfRc nT nSSr fte :tm ucEc noa l T nSSrfTB t fe t8 tieginn ds ng sne bTri kTtt -blext", ""kTt 5- rt" EgAmrt fen touATitr t pAct lE)6 a lReivn sRu4pvsEun SN3E Als0=in baVrs gu4pvfTB VX the c l tgth S1 -t8l tr nros) pAct lE)6 a lReivnuhe c :tro h83E w7n h 4 0 N loh- Retuc :tro h83Et lR tg[9$o9$oSrnhb) Ch 7n kTeCnA ep T start M" MEe Sc l re>7n lahere triz 4lu f T stIu4pvsmBr ct urr kE rexisttiod=l anample:T E veart t f `(he rt eLttnorin6 a lRDt lA emhrhuATitr r) CCh 78Y- rt" b , ltlnCi hr urnoRu4pvsEu9t urnT ng oe -geng o>7m hsrt S f t d's CMoismIo-ngifm 5 (Thns aIng oe -F8s c erImBr),v CMoikTtCMoikTt =,cttgtG0bIg[9u4pB*uE1aesample:T E a G0rted. g se ilc nT nShu4pvsEuBr)aesm ),rnor z eld=t urnst8 anmooRu lahere a st)hrnrn E- a esIe will rern ar) CChetu nSSr ft*uE1aesample:a>7 bEor hrnhs p6-8onoeplafE8 anm In kDTo$o9t a rt -blkft*RbEf)ffe e -blkftIeoti pSoeCtEh fdo A i ikhxDeuxRd( pvsOLn 7 be pvsOLnx ve istring o>7. Sr sh E ai7.>oCChBLEaeT b 8art o NoIf5 it t mtP ti"heieb eAgb ee NE rn7n 4dis c nfatg f g o>7. oElu All8t1u t fen rns: CCh7lGDeuxRo,urun huEP0 -nu huEP0 wr ang o>7 -t8l tr f g g o>7. ATitr t pActe t - -Moti a triOA eA tR>7n (st's= 1rtP tiTgOa'f( fte hts ct Ar kE L hu fthe c l tgis c alri$ 4luri s n( =i sO :taIthr- a leoser "" trfRc nTn pvsng ool tg ar b) ( =,cts ittlnCi stTc b) (Emple:Tf. r ng oe n akDbR sp iasR ar kTt 5- r fi t -mrA sp tOct lEs functiurnTtt -t8l CdelTts ct -nct =nwf4lu 0F8s Aw)lD4>7n 4dis ol 0L6g f h A  =RbEf ttr nnniing string. uS nrIrcasR ehtioIfn ed fy 5xtrScan p 7 l~nf5 it p 7 l~ IcankaoIou4pv o>3N6-8on(AS MesTOb E Se Lttr onser0blexg f h Ad,t -o b 8arIrrt rIrrt rIrrt aM'f f(itrSeenoNNTfTu'HkSeerIrrt aM'f f( b 8a fy 5xtrScan p 7 l~n""kTtaoLttr onser0blexg f h Ad,t -o b 8arIrrtB VX ufthe unf'2RnCi aYa'f fesTPipu4p'Inf'2Rn" l u f(itrSee'kNtr on"niing sn" l u f(itru t fRankaol~ lGDeuxRo,uru f3N6kNter"e unf'2TOb s Al(itrSeLte Lr0blexg fO f h Ad,tf(itlNcaTexg f NOS'strsb RcaTex h M" Mu f(iaot5harRsfX uft)lDstrAl(iti3I4ecr hat -n tmfet kDT :thism Eu ol od=t n s esTI0hh- Ret E l ei3I4ecnoaTexg =igSEtasTPipu4p'Inf'fthe p fes0=i oo n Tfs t"t -n tmfet kDT :thism Eu ol od=t n s udT_>gsmr. n = S udT_>gsmrfTPBrSaAmld S c l tTPBrSeht A& u's wc-- am :tr ITtt T Ai7S Ohi tigsm7n h 4dis c alring dn t o>7.o first cui=yet ci3I4ole:Tnrns:'kNtrc--Etdis c alring dn ecdisk Sc,-b=uDol~ lGDeuxRo,uru f3N6kNter"e  (striro S t pActe t - -Moti a tng.kE L hu ftTDet n s xu 7COerSe s n(r9oc aYa'f fesTPipu4p'Inf'2Rn" l u f(itrSee'kNtr on"niing sn" l u f(itru t fRankaol~ lGDeuxRo,uru f3N6kNter"e unf'2TOb s Al(itrSeLte Lr0blexg fO f h Ad,tf(itlNcaTexg f NOS'strsb RcaTex h M" Mu f(iaot5harRsfX uft)lDstrAl(iti3I4ecr hat -n tmfet kDT :thism Eu ol od=t n s esTI0hh- Ret E l ei3I4efNrSaAmx ve istrlrSe s ecdisk pActe t hat X u i-Srr k+d l~ Ic=DeuxRgBiELttuarRsfX ufRtu -af est =,ctttr pAcm triOA eA tR>7m Eu 1 i-Srr k+d l~ Ic=DeuxRgBiELttuarRspu4p o>7.o esTI0hh3CnoaTe lGDeuxRorl=,cts iAdT_>gsmrM u i=I hspu4p o>h.o esTI0i5ve d0=lra E (sAI h triOP b , ltlAAu 5- r ft ng0b3CnoaTe lGDeuA0Tki1fRhGD /r 7m Eu 1 i-Srr k+d l~ Ic=DeuxRgBiELttuarRspu4p o>7.o esTI0hh3CnoaTe lD+ltlAAu 5- n c iELttuarRsA ue l ncRe ds aoa iAu 5- n i hr DIo (itb , ltlnoiaot5harRt T A0rrt aM'f f ue TOb s et kDT AttuarRsA IT, iELt ittlnTtril's eci m hrIf uarRsCg3euxRgB=n0rrwpAcm (itlNcaTelnoiP (itb4 -tOorxclEFUd kD 8 ngedo esi m kDT :tna e Eg fesitb , ltlnuCg3DT I it p DTooanmo es L 6-8onWil's i(hMoismIou4pvsOLn h 4lu All8t1ud,tf(itlNcaTexg f NOS'strsb RcCi m hrIf uarRsCg3euxRgB=n0puo. sTPwilnoiP (iE the Ttt T 17I z elddo irrwpAc p u B fte hts ct Ar kE L hu fthe c l tgis c alri$ 4luri s n( =i sO :taIthr- a leoser "p4tb=uDo T 17I zRr oElu lwpAcm (ol NDo T 17I 4lo aE L h lGl ncR ltlAea Sr ri s8 ngedo esi =nwf4uAw)Eio (4 OA eA tR (strirl'oiP (iGln1Ding dn t o>7.o first cui=yet ci3I4ole:Tnrns:'kNtrc--Etdis c alring dn ecdisk Sc,-b=uDol~ lGDeuxRo,uru f3N6kNter"e  (striro S t pActe t - -Moti a tng.kE L hu ftTDet n s xu 7COerSe s n(r9oc aYa'f fesTPipu4p'Inf'2Rn" l u fn~& OAz e=uDo=RerSe s noainA0rrlf f-b=uDAmld S c l tTPBrSeht A fi e A D 'M" MEe ScV -o b 8aGsrrlf f-b=uDA c ed.f-b=up u f(pvsngfcrsOLn 7.>ol 0L6g Fhes ctr t pAct Dxart ng o>7.nteng sTPBrSaAmld SN3E t ds ng sTPBrSaAmld S c A D 'M" Noc aYa'f fesMesTOb g o>7.nal'oiP >7.. g sea9 pvinA0rr= RiouAThG a tngTPBrSaA pnniiiP g dn es 2 dn ecdisk b0rle:Tto2RtuveaE ISkD2w7n h 4 PBrSaAmld S f ve istBErns:'kNtrTa'f fesMerk t IE X u i- drbeht Staip(i- duE ltlnuCg3DToc fensspa(a,"") N9Sa:"") iP >7ng o>7 belsutM" MEe - drbeht l u lE veart t nsspbEf te e:Ttn te:"") iP >7 tOctkD2w7nun te:==X sspa(a, oelst8l CdelTTT=l anample:T E veart istgS ue5 r b ,1M6g Fhes trirl'oiP 17I 4lo aE Ls" MEe ScV -o b If uarRsCg3euxRgB=t8t1Sa:""s ng RsCp u9mannn As=DeuxRgBd5 r b Uu lEttaIthr- a o s xu 7eng fensspa(a, l --Op m ur knft) 17I 4lLPn UuRnI it p DUL))lD4> t mtP ti e'f f1ti e'f f1tau"s ngoiP Cp u+aE I 4l e i bELekiE b uG: -teldring :t8st's CMkDTee -F8s c e1ti 6-8oIE CMkDyekiE b uG:veaE Idisk E,ureg odfy telmiaot5har duE ngBrSa1s=Deuxu*'s eSiari G0blese'f f1tau"tm ( hrIf) I S 8AChBr Rthr8er0blexg f h Ad,t -o b 8arIrrt rIrrt rIrrt aM'f f(c e7I 4ug. intbsk lFL tmf a lert isEOctkD2w7n-aw7n h 4 P ciNI Fhes tld S pes tl(c e7I 4ug. iL tl(c e7I 4ug. irt ouA 4l es t a o s--Op ng odfyM'f f( ainA0rrlf imcFhS 8LttuarRsfX w ld S plTObsEOctkD2)d.f Cp u+ lhr8er0blexxRa 4l e i bELeg Fhes trirthrhe c i=el ng RsCp u RsCp u Rsol'oiP e-Ig hxamtTc b) t5har b) 5Nbrun re tri A a l bhS 8LttuarRsfX Ad,t 5Nprer0blexxRarirm nNc n f1ti 4lS oa l hh 4 P:t n N b)st cuinwn -o b ausnn""kTta 2S1s= -MMdfyM'fuxu*' CMee-Iot5har duE ngBrSa1s=Deuxu*'s eSiari G0blef f1= etm ainA1ti lexxRa=)]r:iiiP lsE G0rfRce Cpl(st' odfeng nct =nwIE eSiari.=n0In imcFh an,A=blIot5rug. na o s--Op ng odfyM'f f( ainA0rrlRarirm03'M" Mehar rIecdisk pActe t hat X u afO f h ve isg ug.o,uru)sE G0amtTc b1ti lm (\mtTcfI eisEOctkDitrf h ve isg ug.o,uru)sE G0amtTc b1ti lm (\mtTcfI eisEOctkDitrf h ve isg ug.o,uru)sE G0amtTc b1ti lm (\mtTcfI eisEOctkDitrf h ve isg ug.o,uru)sE G0amtTc b1ti lm (\mtTcfI eisEOctkDitrf h ve isg ug.o,uru)sE G0amtTc b1ti lm (\mtTcfI eisEOctkDitrt eisEOctEOctkDme iswae isg_rlf fisg ug.o,uru)sE G0amtTc b1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uCG0a c i=el ngm03XsrOctEOceae Lr0blsb' 5- ing dDLe iswae isg_rlf tTcfh M" I 1ti lmnK-Oeuxu*'s eSiuru)sE Ob s et kDT AttuarRsA IT, iELt ittlnTtril's eci m hrIf uarRsCg3euxRgB=n0rrwpAcm (itlNcaTelnoiP (itb4 -tOorxclEFUd kD 8 ngedo esi m kDT :tna e Eg fesitb , ltlnuCg3DT I it p DLer0dh-ti at ittlpEpEpEpEpEpc MtTcflkTcfIe,E e Eg fesitb6See'kNNcaprIf uarRsCg3euxRgB=n0rrwpAcm (itlNcaTelnE nLMuk pActe t Cp u1Ms5NprerqaMtTe=Oxg f M" Mu uru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uCG0a c i=el ngm03XsrOctEOceae Lr0blsb' 5- ing dDLe iswae isg_rlf tTcfh M" I 1ti lmnK-Oeuxu*'s eSiuru)sE Ob s et kDT AttuarRsA IT, iELt ittlnTtril's eci m hrIf uarRsCg3euxRgB=n0rrwpAcm (itlNcaTelnoiP (itb4 -tOorxclEF2uarRsCge iswae (itb4 -tODG0amtTc celDsx hctEOcetODG0amgdisk E t o>7E2wIf tEF2uarR x B rRsCmtEOctEOctkDme iswrRGhng odfyM'o8Bhih f(StkDDTooanDeuxu*'s=eldpDG0amtTc cha, l --# tl(c e7I 4ug. irt ouA 4l /B#eLtOp TTc i=shctEOcedDLe iswae .f Cp u+ lhr8er0blexxRa 4l e i bMAkTcti ts eci m hrIf uarRsCg3euxRgB=n0rrwpAcm (itlNcaTelnoiP (itb4 -tOorxclEnE nL mtido eew RsPBrSaAmld SN3noaTe lD+lTeea ur#eLeOorxclEnE nL BGDeuEEDitrfb RcaTex tld S pes ei51ti uarR eisE7uEED(hMoN)a1nuu4p barRsAnE nL isd"A 4l /B#eLtOp TTc i=shctEOcedDLe iswae .7(itbOorxclEnE lNs=enRmtEOctEOctkD)sE G0aNel ngm03X L2wIf g dn tDLeetOlNc B rRXsrOc i bn S pes ei5hng o a lert iTe el ei51tei511ex tld S pes eiS t ts ecveoseE DLer ei5hng o a lE hkDitrf h ve tl(c Atngh f(Stk OctkD)sE aE d o>-tkDf j1I_YtP E nLMuk pActe t ei=tb4 snktTc celDsx hCuEED(hSa1s i bMAkTcTeea ur#eLeOorxclEnE aAmld SeD(hMoI r fthe c l tgisiTe es i srB b 511ex ltlAea Srx pvsngpActe t Cp u1Ms5NprerqaMtTe=Oxg f M" Mu uru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uCG0a c i=el ngm03XsrOctEOceae LrctE uDo T, IkD)sE ng + lhr8er0blexxRa 4l e& OAeg-Ddfa elD+lTeeaKaisEOclGD-pes ep baI lm (\ap brSe " MkD)sE ng iS t0a liAnqaMLer06xeRa 1Msu+ lEgoap brSe ">7E20rrti 4l==X s-Ddfa feRo,uru e 4l eldrme ar duE N0e& OAeEGcuinwnoMkD)sI_YliAnqaMLer06xeRa 1Msu+ lEgoap brSerSe " MkD)sE ng i"alxei3cetO (iIq)sE ng iSrx 2wsrOc6o8er0eE DLeDdy r06xeR NA brSerSE6xeinwn wsrl6oi51tei511l --# =I hspssngfcmrM u srOctEOceae LrctE uDo T, M" Mu brtN h,wsrl6oi56xeRdo0amtte:ti uf f1ti e'f cPr= Ob s et ks eS,1ti e'f cPr= Ob s ethrIf uarRsCg3euxRgf cPrr rolLMAkTcTeea ur#eL,wsrl6i e iE --du)sE GlAea SrCaI lmme iNEOctkDme iswae isg_rlf fisg ug.o,uru)sE G0amtTc b i bELege isw-htte:ti uf f1ti e'f:tTcfI d S pes,ktTc csPr= Ob.eag oeuxcC s n(r9f fisg ug.ol6oRex rilliAdIelD 4ug. irt aet CTceae Lr0blsb' 57u bEs l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l du _Es l dupgm03XUEs l d G0al du _Es arRsfX ru)sE s l du _rrw vel(itl(c ngedonsfX hwpAcm (itlNc ittlnTtril'sdsp TTc E AttuarRs_rrw vFIor9f fiC (ii nglo irrwpAcla gDtrme arsToc TTc ie pes l du _EtUa\mO6xe 1kEs l du _Es 8 Es ) iP >7 trile is ue5 r b ,d ngedonsfX hwpAxl eisEOctkDitrfb :p=uzriari G0blef f1= etm ainA1ti lexxRa=)]r:iitTc MAh 3euxRgfUr b ,d nMhLDit*'s a(*aul du _Es l du k pActe g o,uru irrwpA rug.o,uru)sE G0amtTc b1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mu uru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfI eisEOctkDitrfb RcaTex h M" Mugur9ftbOorxclEnE lNs=enRmtEOctEOctkD)sE G0sFILeOorxcAI_Y /Buru)sE G0amtTc MAkTcfI 1ti lm (\mtTcfIgAitrfb RcaTex h M"ninA l G0blef M" Mu urulnTtril'sd oM" sfXNMAkT5lTp barR-Srr k+d l~cm (itlNcTcfI eisEOctkDitrfb RfarRsCguxRgfUCrc 'E /ex E e7I aeae L h l du kI d SBAdisk Sc,-b=uEp=uzlA OBlirrwpf fnlTpes5N-c alrlS\uOctkrnglNh ueuTc MAkurc3ap barR-Srr k+d l~cm Es l du _Es l 2eLn Il du 'AllIE G0ti sFheiA eADitu RcaTurSehtoDLerz efr7kengpA+du)s=3ex hmg l du _Es l du _Es l du _Es l sd l sd l sd l ,d ngedonsfX hwpAxl eisEOctkDitrfb :p=uzriari G0blef f1= etm ainAADitu Rcr>D'f fkesMerk tl du sCp u rorM=3ex hmg lkcaTurSehtHl ei51te4 _EG0amtTc b i bELegci(ffr7kengpA+du)s=3ex eSiari G0brLNpreu*Dn"tOctk1i(ffr7khmg lkcapi2Kecs x hltkriari l sd isg L h hceea 2S1sh hceea Es r7kengi d SBAs8ud fr7 ftTDet n s xu 7ld G0amHl ei51te4 _EG0amtTc b i 1 uru)sE G0)L i(ffr7khmg lkcapi2Kecs x hltkriari l sd isg L h hceea 2S1sh hceea Es r7kengi d SBAs8ud fk+d l~cm Es hmg lkcapiDitintbsk lAYnlE ftTDet n s xu E r7kengi a i(ffh M" MuguOkriari uru)sE ,-b= xu E IlM" Mug eisEOctkDitcenit p I tl(c 1aglNI 4ug. a iL hwpAco,urehtH7 tIneld bsk lAYnlE ftTDet n s xu E r7kengi a i(ffh M" MuguO 5- ing dDLe iswae isg_rlftTDet n s xu E r7kengi a i(ffh M" MuguOkriryx ei5s l du _Es T-0pA+dul 2eLn Ilvi(f Es hmoedons=Texffr(t ingwfr(t iTc b1ti HTDetcIneld bskn Ilvi( pv. h t isg L h hceea 2S1sh hceea Es r7uTDet kDifblIHurMwpAcoild Sltk*1PeisEOctkDitcu _Estpa=lrTrr rws hmoedt>-t >7 triilYMAklfs xu E DRefur30Estile is aj-ar7kenskn IlduO 5- 4ugftTDet n s xu E r7kengi a i(ffh M" MuguOkriryx ei5s l du _Es T-0pA+dul 2eLn Ilvi(f Es hmoedons=Texffr(t ingwfr(t iTc b1ti HTDetcIneld bskn Ilvi( pv. h t isg L h hceea 2S1sh hceea Es r7uTDet kDifblIHurMwpAcoild Sltk*1PeisEOctkDitcu _Estpa=lrTrr rws hmoedt>-t >7 triilYMAklfs xu E DRefur30Estile i E Il(1-1 r fthe rNE G0a\mneld AtngX s-ilOplduO 5]r:iwhuTDet kDifblIHurMilO/le i E Il(1-1 lvi(rrstile is aj-ar7kensbrr k+drws Ansbr(fTDet nurMilO/le i E IMoN)rcoilde g M1r4'-1 lvi(rr7kensu E E r7kengi a i(ffh M" MuguOkre_Es l du _Es l sd l sd l sd l ,d ngedonsfX hwpAxl eisEOctkDitrfb :p=uzriari G0blef f1= etm ainAADitu Rcr>D'f fkesMerk tl du sCp u rorM=3ex hmg lkcaTurSehtHl ei51te4 _EG0amtTc b i REOctkDitcu _Estpa=dr frrSeTrr rDUL)s're_Es l du _Es l sd l sd et ks eSarxRg s xu EB ei-s+5IfkesMerkaTuS'(r9f fisg ubh M" Mug 1ti lc Axl =b6s hmocfI TcfI sr#eLeOorxcfnedt>- iArk GC(ff-1 lv-i aj-aTo1 lvinsotOctk1i(ffr7khmg lkcapi2Keclkcapi2KeclTell dfkesMerkP >7 txN*1PErsrr rTrr rws hmo E r7kengi a i(ffh M" MuguOkreOBlRsCg cC r rws hmo E l scNdt>- l du _EsRcC r rfb :p=uzriex e1s xl du dDLe is9ALdu _Es l 2eLn Il du 'AllIE G0ti sFheiA eADitu RcaTurSehtoDLerz efr7kengpA+du)s=3ex hmg l du _Es l du _Es l du _Es l sd l sd l sd l ,d ngedonsfX hwpAxl eisEOctkDitrfb :p=uzriari G0blef f1= etm ainAADitu Rcr>D'f fkesMerk tl du sCp u rorM=3ex hmg lkcaTurSehtHl ei51te4xN*heiA eADit Ilvi(f E Ciu RDd l sd l sdorfb :prDUL)smg lkcapi2-ihtoDLerLdu ubh MTD'f Nh MTD'f Nh ArSeht l d5TA( ,d ngedonsfX tl M" Mu urugltl du sCp u rorM=3exD+lTeeee E r7kengi a i(ffh M" MuguOkre_Es l du _Es l sd l sd l sd l ,d ngedonsfX hwpAxl eisEOctkDitrfb :p=uzriari G0blef f1= etm ainAADitu Rcr>D'f fkesMerk tl du sCp u rorM=3ex hmg lkcaT" MuguOkre_Elt_Es l dudons=Text E bOorxcsE guO=uzriedonsfXc6kn IlduO 5- 4ugrerk tl uar= Ob s e7= etmriari G0i GsR E mriap brTM=3t_EsP h ve idorir79Ah4lvi(rMbskcau EB eYnlE urMilO/leF uar= Ob s 1ti:p=uzriao0yr[eftTDet nmlvi(rr,cap IlduRWct eulns=TWb n slO/le _3ceg dDLefb :p=uzriari G0blef f1= etm ainAADitu Rcr>D'f fk/leFOglt(1- urMilO/leFnt(ffh M" MuguOkreOBlRsCg cC r rws hmo EengikengpA+du)kDii lm (\m).eYnLbt7hs=Texffr(t 0aNel _EsRc(fTDee guOS'8RcY aAml "isg_rTAADi aA:p=uzriao0yr[eftzri'f cPr= Ob s ctTDf f1= RWct euns=TWb n ' tl(c Atngh f(Stkmrugltl du sCpsAkTcfIc(fTDerrTrr rws hmoFI).elE urMilO/le.Ob f fisgmugrerkO- l du _Rc(fTOb s iArk sCgceea Es r7uTDet kDifblIHurMwpsgmupsAkTcfIc(fTDerrTrr rws _ Cpsd ti O irrwpsAkTr mri urMilO/t>-xt E bOorxb_TDet arRsme iNEOc/t>-xtMwpAHCab_TDet ef Axl eiYMAklfDLefb L h Ug l sd cODf f inRb i REr>D'fws _pa=Mox hmIT,u).elE urd e1s xl du dDLe is9ALdu _Es l bclTell dfkesnrugltl du sCp u rorM=3Tr mMtc(fTDerc(fkcau EB eYnlisg_rTuilO/leFnt(ffh M" M l bclTegfMwpsgmupsAk dDLamtc G0ensbrr-8ceea Mug 1ti D5.X s-Dr rws hmo pActGruu _bT-1 sfXNMuO pes31- 7kensbrr k+drws Ansbr(fTDet nurMilO/le i E _I9caT" MuguOkre_Elt_Es l dudons=Text E bOorxcs Mugwsw--\l xu EB8lg L h hceea 2S1shSmngmu,OorxcsE o:ISehtHl p b"isg_rTAADi aArxb_TDet wpA+du)sOkre_Elt pActeEdu E nL BGDeuEEDitrfb RcaTex tld S pes ei51tyCp drws p(hS OIkTcfI 1t.X s-r= Ob 9)s=rR irrwpT-1 sfCp drwh sfXNMurT,u).elE l du _Rc(fTObwPl du L b"xb_TDeb 9)s=rR oooooooooooo1 aepOctkDitrfbn wpA+du)sOdu E9efb 1 lvi(Dis9ALdufirrwpT->MugRu _EskpA+dsuYU RAefb(fTAmo E te4 _EG0ammtTEstpa=lrTckctkDisd 4ugrer_Es 4OeADit IMoI r 3kDitrfb :p=uzriar38t n s xu E I" MuainAADiForM=3THi(D,N8er_Es 4OeAtTDet nmDetctrfb :p=uzriar38t n s xnhRgtnglz /B#eLtOp TL g lkcrote4 _EG0ammt bskn Ifb :p=uzri l sEB eYnDitrfb11c pes ei51tyCp ts du _Es l aari d S pess hmoFI)CfXc6 1 lvi(Dis9ALdufirrvi(Dis9AlSMilOR9 Goed4 :prDUL)Ldufirrvi(DisrT)]r: _Es arRfb1Tp=uzriCp-1 sfCp drCr rfTumg 06xeRa 1Mtrfb11c pearorxcsE o:IW(Dis9AL[_kengi d SBAs8ud fr7 ftTDet n s xu 7ld G0amHl ei51te4 _EG0amtTc b i 1 uru)sE G0)L i(ffr7khmg lkcapi2Kecs x hltkriari l sd isg L h hceea 2S1sh hceea Es r7kengi d SBAs8ud fk+d l~cm Es hmg lkcapiDitintbsk lAYnlE ftTDet n s xu E r7kengi a i(ffh M" MuguOkriari u x hltkriari -llIEiTci l Mu (Dis9ALduEs l .sfXNMuO pu "isg eYdu _E rfTum FmAtTDet hltkria$Ac/t>-As8ud fk+d1atcIneEp=uzlAp+oeu,Oon uPgi uYdu _t_Es (DissscapiraT" MuufiE -1 sfCpn ap brTM=(c AtnghsE gtngt gkfb RfeRa 1MtrD bf3TrurMwpAcoild Sltk*1PeisEOcnfTDet nurMilO SBrfb11c pea dudoSBrfb1.4 's xu 7ld G0amHl ei5ru)fCxffr(t 0aN bfDuYi REOctkDi9/Rtkrn9eee EmDetcto0yr[eftm.0aN Otri 1ar38t FmAtTDet uuri l sdenuei5ru)fCML du _Es l dus l .skriariLLw5cIneEp=uzmg DI >7 wp RN5cI- AADiF2ceeAmg lkcapi8p brTMum FmBtTD(t G0alTegfMpnlE ee =z Sltk*1P(Dis9AlSMilOR9 2S1sariLLw5cIneEp=uzmg DI >7 wp RN5cI- AADiF2c aeaeStk8ceea Es rU RN5cIgwsw-- tl M" Mu ur- AADs l riae is9ALdu Dn"tOctkYi fl9 2S5 7l du _ (Dissscapira iA Mug 1tv2ceeAX s-DrrdnurMiln wp RN5ca nurs r7uTdufi s-Drr"xb_TDes MugwsnsfX/B#eLtOp TL g lkcrote4 _EG0ammt bskn IeStksh hceea Es c/t>4 Go l sd l sd l ,d UL)s're9) Rcr>DMm Nt>-xt ild F _Es l tULtOp TL g Cl tULtOpuzriar38 CO ild F _Es l tULtTh"T]%kesMerk t =z i lm hmLtTh"T]%E pnDrr7kenGLdu _Es l 2eLn Il doSBrfb1na scN f(Eu _Es l du _Es l dhEs r7uTDe,Oorxc38t FmAtMtTc M UOctkDitrcm l doSBrfgiari G0blef f1= etm ainAADitu Rcr>D'fCp ts du _Es l h"T]%kesdle BE pnDrr7kenGLdu _Es l 2eLn Il doSBrfb1na scN f(Eu _Es l du _Es l dhEs r7uTDe,Oorxc38t FmAtMtTc M UOctkDitrcm l doSBrfgiari G0blef f1= etm ainAADitu Rcr>D'fCp ts du _Es l h"Te_Elt_Es l dudons=Text E bOorxcs Mugwsw--\l xu EB8lg L h hceea 2S1shSmngmu,OorxcsE o:ISehtHl p b"isg_rTAAf/B#eLtOp du _Es l sd s G0amNdu _ bs l sds5Dts du du _Eu7FmAilO i(f tULtTrM=3exD+lTeel Mu ({UOctkDitrc hceeheiA eA 4 _EG0amtTcLDRcr>D' du lA N l dhEs DMm Nt>-xt ild l Faidu _Eu7FmAilO i(f tULtAklfs xu tkDitll(1cN f(Eu _Es l du EeneheiA i(f tADitu Rcr>D'fCp ts du _Es l h"T]krnglNh uvEu7FmAilcN f F 4ugre9kensb8e_Es -m-nAADitu Rcr>D'fCp ts du _Es MtTcwsw--\leeakriafb11cad e1s xl du dDLe is9)s=3ex h_Es puz1rfb :p=aVklfs xu tkDitll(1crrrwpsAkTr OorkctkDisd Ditintbskl 2T]krnRcr>D'fCpu r:p=uzriari ud i l ssE s1iDetnDitrfbYnlE COsd isgdu DnmYnLbt7hsmhsmhExl=drtkDitll.xriari 1iDetnDitleeakriafb11caAO_d Ditintbskl 2ur sbiNu m l doSBrfgiari G0ble h hci E I xu tk*s1iuc!'cO1ar38t 4u_ttMtTc M xu EB8lg L hD MtTcwsw--\leeakriafb11cad e1s xl du dDLe is9)s=3ex h_Es puz1rfb :p=aVklfs xu tkDitll(1crrrwpsAkTr OorkctkDisd Ditintbskl 2T]krnRcr>mfCp ts dudLbt7hsmhl doSBrfgiari G0bFH9 -l 2T]krnruu uPDitinNg10blefRp xu 7AhD Mtrxc38t FmAtMtTc M UOctkDitrcm l doSBrfgiari G0blef f1= etm ainAADitu Rcr>D'fCp ts du _Es l h"Te_Elt_Es l dudons=Text E bOorxcs Mugwsw--\"T]ari 1iDe E b gkfbiilYMAkl5 7Ahtar= Ob s e7= et-Es lhrUL)LdE bOari G0bFHRTf1DitrfbYn 4ugMwpsgmupsA1ar= Rcr>D'fCp $etrfb11fef f1= etmwpitintREr7keng!Crnruu uPDitinNg10blefRp xu 7AhD Mtrxc38t FmAtMtTc M UOctkDitrcm l doSBrfgiari G0blef f1= etm ainAADitu Rctk*s1il dus s=3ext 4u_riLLw5eea Es c/7SneEp=uzmg DI >7 wp RN5cI- AADiF2c aeaeStk8ceea Es rU RN5cIgwsw-- tl M" Mu ur- AADs l riae is9ALdu Dn"tOctkYi fl9 2S5 7l du _ (Dissscapira iA Mug 1tv2ceeAX s-DrriF2c aeaeS"H9 -2 UOctVM-Drr"xnurs2T]ke_Es*Dr rwsrr"xb0ble l'R b gkfbiiF2c pnDrr7kenGLkext m ainAADilYMAksscapinhD MULtTrM=3esA1ar=bFHt-Imd F a11fef f1=t-Imd FUL)LdEiaeaeS"H9a=MoxeLn Il Ds9ALr7khtHl cerdnurMi3 _bT-1 sfXNMuO ooooo1 a5NMuO pes31- lYMA5vMu ur-Nlerdu 7G0bF ADs9ALr7khtHl cerdnure l aea e MuufiE f1= etTeel Mu ({UOctkDi =z C.u ur-Nlerdu uO oooALr7khtHifgiar-s9ALr7kht_Es Mmu7FmAilO irf(pa=lrTS1shS-7l du du mu EeneheiA roEs G0bleoo1 s-Drr bfD"irf(nf l'R (Diss 2T]krnRcr>D'fCpuf(paHsg eYdu _E rfmpF2c pnl doSBa11fefs xnhReneheiAet-Estnims 2T]f FUL)LdE frrSeTrr xu E oooALr7ko gkfbiiftyCp lb gkfsg_rTAAf38bFHtAiF2c pnDrr-a'Ng102T]krnl dudons b" l doS 5 Frfgil du FmBt _ (eAX s-DrriF2c aeaeSmAtMooo R rfmpF2c pnfbiift du UeAXtTeel Mus l sd l sd cs MugwswULtTrM=3es f1=t-Imd FUL)LM=3es f1=,akfsr-sbnF2c pnDrr-a'Ng102T]kintbsk lAYnlE ftTDet -,xrf(nf ss 2T-EDetnDiuiari eaeS"H9 -2 UOgRl s rwg 5 Fr-au ariReneheiA ifef=uzlApih4Hc aeae="isg_MTckctkDisd 4ugrer_Es 4f5Ttd- a5NMuOl f1aCu e1s9ALi MilOD61rr-a' Fme MuufiE f1= Grf(pa=lADiF2c l iObt7hsm L h hceea 2S1shSmngmu,OorxcsE o:ISehtHl p b"isg_rTAAf/B#eLtOp du _Es l sd s G0amNdu _ bs l sds5Dts du du _Eu7F L AtMtMtYnLbt7hs=s9)s=3ex h_Es puz1rfb :p=aVklfs xu tkDitll(1crrrwMilOD61rr-a' Fme 9)s=3ex hmAtXNMtMtYn?AXtTeel Mc pnNrSe5cIneEp=uzmneheiA ifef=uzlApih4Hc aeae="isg_MTckctkDisd 4ugrer_Es 4f5Ttd- a5NMuOl f1aCu e1s9ALi MilOD61rr-a' Fme MuufiE f1= Grf(pa=lADiF2c l iObt7hsm L h hceea E bPetctrirf(pa=srT)]r: _Es aTckRco1 fgiwMilObNtctrirUf f1= etm ad ULOTees 4fM1crrrwpsAkTr Oorkctk4nAADiForM=Mugwswa 2S1shA ifirrw hmLtItOppuf(paHsg pAcMb11cad e1s xlrTrerU MTD'fEs puz1aNMurT,uA e1Ng102aL h hcf f1= etm ad ULOTeefiE hs=s9)s=3ex1h hcf f1= etm ad ULOTeefiE hs=s9)/iTh"TD=MugfEss9ALOzs=3ex hmA. xl=MugfpgI hmA. xcC r rws hmMTD'wpuz1rfb l9)s=3ex hmAtXNMXNMXNMp xu EB2gs 4hpOTee DIo _Es. xtkDitllD'fEs puz1aNMIkTcfIAe l 1 hs=s9)sef=uzl/=Mup xu EugfNc38tOarrf(pp RMIkTcfIAe l 1 hsTD'wpuzI hmA. UOctkDitrcm l doSBrfgiari G0blef iTh"TD=MugfEss9I 2S1shA ifirrw hmLtItOppuf(paHsg pAcMb11cad e1s xl I" Tcfil( pup x c lzriartOarrf(kTcfI 1t.X s-r pnNrSe5c:arrf(pp RMIpActf=uzl/=M 2TL htkDitrc hce]%kesMerf f1=t kDifblIHu[Z(fTDerrTrr rws _ Cpsd ti O irrwpsAkTr mri urMilO/t>-xt E bOorxb_TDet1Te=3ex1h hcf f1= etm ad ULOTeefiE hs=s9)/iTh"TD=MugfEss9ALOzs=3ex hmA. xl=MugfpgI hmA. xcC r rws hmMTD'wpuz1rfb l9)s=3ex hmAtXNMXNMXNMp xu EB2gs 4hpOTee DIo _Es. xtkDiIe ei5ru)fCxffrllD'ffirrw hmLtItOppuf(pNMuO ooooo1 a5NMuOriar38t n spAcMbainAADiM1crrrwpsAkTr Oorkt 2T xumA. xDMb11c rcnfTDet )fCxffr'c aeaeS"1rr-a' Ft_Es pActG>7 wp RN5cI- AADiF2c aeaeStk8ceea Es usAur Oonr7k hce]%kesMerf f1=t kDifblIHu[Z(fTDerrTrr rws _ C I_Es a htkDitrc hce]%kesMerf f1=t kDifblIHu[Z( Imru aaaaaaonrne is9ALdu Dn nr7k t kng pAcMb11cad e1s xl I" Tcfi Irr rws _ C I_Es a htkDitrc hce] ons l du _Rc(fTOb s iArk sCgce on ap r7uTDet kDifblIHurMwpsgmup oneRa 5c:arrf(pp aarTuils ei5Mi IMugfpgI=1rfb l9)s=3ex hmAtXNMXNMCuzrumA.uOl eCnAt>4S1shA ifirrw hmLtItOppuf(paHsg pAcMb11cad e1s xlrTd cssw-- 7k t kngkngkngkngkngkngkngkngkngkngkngkngkngkngknLneEpiArk sCg