Using the Windows Registry to Configure Script Settings

Overview

So far, all of the scripts that you have worked with in this book have collected configuration information and input from two places, the user and from within the script itself. In this chapter, I'll show you how to externalize script settings by storing and retrieving configuration data using the Windows registry. As a bonus, in the chapter's game project, I'll also demonstrate how to retrieve input data from files. Specifically, you will

Project Preview Part 2 of the Hangman Game

In this chapter, you will enhance the Hangman game that you began developing in Chapter 8. You will begin by creating a new setup script that uses the Windows registry to store the location of the folder where new external word files are stored. You'll then modify the Hangman script by removing the array that stores game words within the script and tweaking the script so that it retrieves words from the external word files. You will also modify the game to allow the player to select the category of words in which he or she wishes to play. For example, you may wish to create different word files for categories such as Foods or Places.

Figures 9.1 through 9.6 demonstrate the overall flow of the game from beginning to end.

Figure 9.1: First, you'll need to run the Hangman setup script once to establish the game's new registry setting.

Figure 9.2: The Hangman game begins exactly as it did before, by inviting the user to play a game.

Figure 9.3: Now a list of word categories is dynamically generated, allowing the player to select a category of words from which he or she would like to play.

Figure 9.4: The flow of the game runs exactly as it did before, by randomly selecting a word from whichever word category the player selected.

Figure 9.5: When the game ends, the results are displayed and the player is invited to try to guess a new word.

Figure 9.6: Eventually, the game's closing splash screen is displayed, providing information about the game and its author.

By the time you have finished writing the new Hangman setup script and modifying the original Hangman game, you will have a basic understanding of the Windows registry and what it means to access and modify its contents. You will also have learned how to retrieve data stored in external files in order to use it as input in your VBScripts.

Introducing the Windows Registry

Since the introduction of Windows 95, the registry has been the central repository for configuration information on all Microsoft operating systems. Windows uses it to store information that affects every component of the computer, including the operating system.

Because the registry is a very reliable repository for storing and retrieving information, many applications developers take advantage of it by storing their applications settings there. In a similar fashion, you can migrate settings from your VBScripts into the registry.

Definition

The Windows registry is a built-in database that the operating system uses to store configuration information about itself, as well as the computer's software, hardware and applications.

You can also create VBScripts that can manipulate registry contents in order to affect virtually every aspect of the operation of your computer.

How Is the Registry Organized?

The registry is organized as a collection of five root or parent keys, which are defined in Table 9.1. All of the data in the registry is stored in a tree-like fashion under one of these keys.

Table 9.1: REGISTRY ROOT KEYS

Key

Short Name

Description

HKEY_CLASSES_ROOT

HKCR

Stores information about Windows file associations

HKEY_CURRENT_USER

HKCU

Stores information about the currently logged on user

HKEY_LOCAL_MACHINE

HKLM

Stores global computer settings

HKEY_USERS

-

Stores information about all users of the computer

HKEY_CURRENT_CONFIG

-

Stores information regarding the computer's current configuration

Data is stored within the registry as values, which are located within keys stored under the root keys using the following format:

Key : key_type : value

Key specifies the name of a registry key. Key_type defines the type of data that is stored in the key. A number of different types of data can be stored in the registry, as shown in Table 9.2. Value represents the actual data that is being stored.

Table 9.2: DATA TYPES SUPPORTED BY THE WINDOWS REGISTRY

Data Type

Description

REG_BINARY

Stores a binary value

REG_DWORD

Stores a hexadecimal DWORD value

REG_EXPAND_SZ

Stores an expandable string

REG_MULTI_SZ

Stores multiple strings

REG_SZ

Stores a string

Definition

Within the context of a discussion of the Windows registry, a value represents the name of an element to which data is assigned. Therefore, a registry value acts in many ways like a file, which is a container for storing data on a Windows file system.

Definition

A registry key is a container that stores other registry keys and values. You can think of a key as being akin to a folder on the Windows file system.

Accessing Registry Keys and Values

You can manually view the contents of the Windows registry using the Regedit utility supplied with every version of Windows. In addition, if you're using Windows NT, 2000, or XP, you can also use the Regedt32 utility, which looks and works like the Regedit utility. For example, Figure 9.7 provides a high-level view of the registry using the Regedit utility. As you can see, the five root keys are visible, and one of the root keys has been partially expanded to reveals its tree-like structure.

Figure 9.7: Examining the Windows registry using the Regedit utility

  TRAP

One of the easiest ways to mess things up on a computer is to modify the Windows registry without knowing what you're doing. The Windows registry stores extremely critical system information. Incorrectly configuring keys and values stored in the registry can have a disastrous affect on the computer, and could potentially disable Windows from starting. I recommend that, unless you're absolutely sure of the effects of making a change to the registry, you avoid doing it.

Creating a Key and Value to Store Script Settings

The WSH WshShell object supplies three methods that provide VBScript with the ability to access, modify, and delete registry keys and values. These methods are demonstrated in the sections that follow.

Creating or Modifying Registry Keys and Values

The first step in creating a new registry key and value is to instantiate the WshShell object within your VBScript. Then, using the WshShell object's RegWrite() method, all you have to do is provide the name of a new key or value and its location within one of the five registry root keys. For example, the following statements create a new key called GameKey under the HKEY_Current_User root key and then create a value called HomeFolder and assign it a string of "C:VBSCriptGames".

Set WshShell = WScript.CreateObject("WScript.Shell") WshShell.RegWrite "HKCUGameKeyHomeFolder", "C:VBScriptGames"

You can later modify the registry value by simply changing its assignment like this:

Set WshShell = WScript.CreateObject("WScript.Shell") WshShell.RegWrite "HKCUGameKeyHomeFolder", "C:MyGamesVBScript"

A single registry key can be used to store any number of values. For example, the following statements establish a second value named FileType under the GameKey key and assign it a string of ".txt".

Set WshShell = WScript.CreateObject("WScript.Shell") WshShell.RegWrite "HKCUGameKeyFileType", ".txt"

Accessing Information Stored in the Registry

Once a registry key and one or more values have been established, you can read them using the WshShell object's RegRead() method. For example, the following statements read and then display the value stored in the previous example:

Set wshObject = WScript.CreateObject("WScript.Shell") results = wshObject.RegRead("HKCUGameKeyFileType") MsgBox results

Deleting Keys and Values

Now let's delete one of the two registry values that we have just created using the WshShell object's RegDelete() method, as follows:

Set wshObject = WScript.CreateObject("WScript.Shell") wshObject.RegDelete "HKCUGameKeyFileType"

In similar fashion, you can delete the GameKey key, thus deleting all the values that it stores, like this:

Set wshObject = WScript.CreateObject("WScript.Shell") wshObject.RegDelete "HKCUGameKey"

Take note of the character that follows the word GameKey in the previous statement. This character tells the RegDelete() method that the specified element is a registry key and not a value.

How to Retrieve System Information Stored in the Registry

Now that you know the basics of reading, writing, modifying, and deleting registry keys and values, let's look at an example. In this example, the ProcessorInfo.vbs script shows how to retrieve information about the processor (that is, the CPU) of the computer on which the script is run.

'************************************************************************* 'Script Name: ProcessorInfo.vbs 'Author: Jerry Ford 'Created: 12/13/02 'Description: This script collects CPU information about the computer that 'it is running on '************************************************************************* 'Initialization Section Option Explicit Dim WshShl, Response, CpuSpeed, CpuVendor, CpuID 'Set up an instance of the WshShell object Set WshShl = WScript.CreateObject("WScript.Shell") 'Main Processing Section 'Prompt for permission to continue Response = MsgBox("This VBScript gathers information about your " & _ "processor from the Windows registry." & vbCrLf & vbCrLf & _ "Do you wish to continue?", 4) 'Call the function that collects CPU information If response = 6 Then GetProcessorInfo() End If WScript.Quit() 'Procedure Section Function GetProcessorInfo() 'Get the processor speed CpuSpeed = WshShl.RegRead("HKLMHARDWAREDESCRIPTIONSystem CentralProcessor~MHz") 'Get the manufacturer name CpuVendor = WshShl.RegRead("HKLMHARDWAREDESCRIPTIONSystem CentralProcessorVendorIdentifier") 'Get processor ID information CpuID = WshShl.RegRead("HKLMHARDWAREDESCRIPTIONSystem CentralProcessorIdentifier") MsgBox "Speed: " & CpuSpeed & vbCrLf & "Manufacturer: " & CpuVendor & _ vbCrLf & "ID: " & CpuID End Function

The script's Initialization section defines its variables and instantiates the WshShell object. The main processing section prompts the user for confirmation before continuing, and then calls the GetProcessorInfo() function before executing the WScript.Quit() method, thus terminating the script's execution.

The GetProcessorInfo() function performs three registry-read operations using the WshShell object's RegRead() method. Each read operation retrieves a different piece of information about the computer's processor. The function then uses the VBScript MsgBox() function to display a text string displaying the information that it has collected about the computer's processor.

For additional examples of how to use VBScript to interact with the Windows registry, refer to the "Desktop Administration" section in Appendix A "WSH Administrative Scripting." There you will find two scripts that demonstrate how to perform desktop administration by manipulating registry settings that configure the Windows desktop and screen saver.

Back to Part 2 of the Hangman Game

Now that you've had a review of the Windows registry, including its overall structure and design, let's return to the Hangman game and modify it to work with the registry. Before I begin, you may want to take a few minutes to review the design of the Hangman script as shown at the end of Chapter 8.

As you already have the basic Hangman script written, all you'll have to do to complete this chapter's project is to focus on the creation of the new Hangman setup script, and on modifying the parts of the original Hangman script affected by the changes. You'll want to tackle this project in two stages.

Creating the Setup Script

In stage 1 you'll create a VBScript called HangmanSetup.vbs. This script will create and store a registry key called Hangman in the HKEY_CURRENT_USER root key (referred to in the script as HKCU). Within this key, a value called ListLocation will be created and assigned a string identifying the location where you plan to store your Hangman word files. The HangmanSetup.vbs script will be developed in three steps.

  1. Create a new script, adding your VBScript template and defining the variables and objects used by this VBScript.
  2. Set up the controlling logic in the main processing section, first prompting for confirmation before continuing, and then finally calling the procedure that creates the registry key and value.
  3. Set up the Procedure section by adding the SetHangmanKeyAndValue() function, which performs the actual modification of the registry.

Defining Variables and Objects

By now, this step should be very familiar to you. Begin by copying over your VBScript template and filling in information about the new script.

'************************************************************************* 'Script Name: HangmanSetup.vbs 'Author: Jerry Ford 'Created: 12/14/02 'Description: This script configures registry entries for the Hangman.vbs 'game '************************************************************************* 'Initialization Section Option Explicit

Next, define the variables and objects required by the script. As you can see below, this is a very simple script, with only a few items that need to be defined.

Dim WshShl, Response Set WshShl = WScript.CreateObject("WScript.Shell")

The first variable will be used to represent the WshShell object, and the second variable will be used to store the user's response when asked if he or she wishes to make the registry change.

Get Confirmation First

The main processing section prompts the user for confirmation before proceeding. It then tests the results returned by the InputBox() function before proceeding. If the value returned is equal to 6, then the user elected to continue. Otherwise, the WScript object's Quit() method terminates script execution.

'Main Processing Section 'Ask for confirmation before proceeding Response = MsgBox("This VBScript establishes registry settings for the " & _ "Hangman game. Do you wish to continue?", 4) If Response = 6 Then SetHangmanKeyAndValue() End If WScript.Quit()

Modify the Registry

The final step in creating this script is to define a function that creates the new registry key and value. As you saw earlier in this chapter, this operation is accomplished using the WshShell object's RegWrite() method.

  TRAP

When deciding what registry key and value to create in situations like this, it's critical that you take steps to ensure that you don't accidentally overwrite an existing key or value of the same name that may already exist. Otherwise, you might accidentally disable another application or even a Windows component. In the case of this script, it is virtually certain that the key and value I defined will not be in use. However, if there is any doubt, you can add logic to your VBScripts that will first check and see if the key and value already exist before attempting to do anything.

'Procedure Section Function SetHangmanKeyAndValue() WshShl.RegWrite "HKCUVBGamesHangmanListLocation", "c:Hangman" End Function

Assembling the Entire Setup Script

Ok, now let's put the three sections of this script together; then run the script and click on Yes when prompted for confirmation. If you want to, you can use the Regedit utility to go behind your script and make sure that it created the new registry key and value as expected.

'************************************************************************* 'Script Name: HangmanSetup.vbs 'Author: Jerry Ford 'Created: 12/14/02 'Description: This script configures registry entries for the Hangman.vbs 'game '************************************************************************* 'Initialization Section Option Explicit Dim WshShl, Response Set WshShl = WScript.CreateObject(WScript.Shell) 'Main Processing Section 'Ask for confirmation before proceeding Response = MsgBox("This VBScript establishes registry settings for the " & _ "Hangman game. Do you wish to continue?", 4) If Response = 6 Then SetHangmanKeyAndValue() End If WScript.Quit() 'Procedure Section Function SetHangmanKeyAndValue() WshShl.RegWrite "HKCUVBGamesHangmanListLocation", "c:Hangman" End Function

You only need to run this script one time to set up a computer to play the Hangman game. However, you will need to modify and rerun this script if you decide to change the location of the folder in which you plan to store your Hangman word files.

Updating the Hangman Game

In this second part of the project's development, you will modify the original Hangman script so that it retrieves from the registry the location of the folder that stores the Hangman word files. You will also add logic that enables the script to open and read the contents of the word files. To accomplish this goal, the original Hangman script will need to be modified in five steps.

  1. Open the Hangman script and modify its initialization section to include additional variables and object references required to support the script's new functionality.
  2. Delete the FillArray() function, which was responsible for retrieving a randomly selected word from an internal array, from the script.
  3. Modify the RetrieveWord() function to call two new functions, GetWordFile Location() and SelectAWordCategory(). Then add logic that processes the word file specified by the player in order to randomly select a game word.
  4. Create the GetWordFileLocation() function, which will retrieve the location of the folder where the word files are stored from the Windows registry.
  5. Create the SelectAWordCategory() function, which will present the player with a list of word categories based on the word files that it finds in the folder.

      TRICK

    I recommend that you make a copy of your current Hangman script and that you modify the copy instead of the original script. This way, if something goes wrong, you'll still have your original working version of the game to play.

Updating the Initialization Section

There are a number of changes you'll need to make to the Hangman script's initialization section. These include defining new variables used by new portions of the script. These variables appear in boldface in the following:

'Initialization Section Option Explicit Const cTitlebarMsg = "VBScript HANGMAN" Dim Choice, GameWord, NoMisses, NoRight, SplashImage, PlayOrNot, MsgText Dim PlayAgain, WrongGuesses, RightGuesses, WordGuessed, LetterCounter Dim TempStringTwo, WordLetter, DisplayString, FlipCounter, TempStringOne Dim RandomNo, ProcessGuess, GameStatus, CheckAnswer, WshShl, GameFolder Dim FsoObject, GameFiles, Selection, FileString, CharactersToRemove Dim ValidResponse, SelectCatagory, InputFile, WordFile, NoWordsInFile Dim LinesInFile, WordList

In addition, you will want to delete the following statement because the array that held the game words used in the original version of the script will no longer be supported:

Dim WordList(9) 'Define an array that can hold 10 game words

Finally, you will need to instantiate both the FileSystemObject and the WshShell object like this:

'Set up an instance of the FileSystemObject Set FsoObject = CreateObject("Scripting.FileSystemObject") 'Set up an instance of the WshShell object Set WshShl = WScript.CreateObject("WScript.Shell")

Methods and properties belonging to the FileSystemObject object will be required to read and process the words stored in the game's word files. In addition, the WshShell object's RegRead() method will be needed to retrieve the location of the folder where the game's word files are stored.

Removing Obsolete Statements

The next thing to do is to delete the FillArray() function, shown below, from the VBScript. Before doing so, copy and paste each of the words defined by this array into a blank Notepad file, each on its own separate line. Save the file in a folder called Hangman on your computer's C: drive and give it a filename of General.txt (that is, save it as C:HangmanGeneral.txt). This text file will now be used to retrieve game words for the new and improved version of the game.

FillArray() Function FillArray() 'Add the words to the array WordList(0) = "AUTOMOBILE" WordList(1) = "NETWORKING" WordList(2) = "PRACTICAL" WordList(3) = "CONGRESS" WordList(4) = "COMMANDER" WordList(5) = "STAPLER" WordList(6) = "ENTERPRISE" WordList(7) = "ESCALATION" WordList(8) = "HAPPINESS" WordList(9) = "WEDNESDAY" End Function

While you're at it, you may want to create one or two other word files and give them names that describe their contents, then save them in the Hangman folder. This way, the player will have more than one category of words to choose from when playing the game.

Modifying the RetrieveWord() Function

I recommend that you begin the modification of the RetrieveWord() function by first deleting all of the statements currently in it and then adding the statements shown next. As you can see, I have added a number of comments to this code to explain its construction in detail.

'This function retrieves a randomly selected word from a word file Function RetrieveWord() 'Locate the folder where collections of game words are stored GameFolder = GetWordFileLocation() 'Get the player to select a word category SelectCategory = SelectAWordCategory(GameFolder) 'Create the complete path and filename for the selected word file InputFile = GameFolder & "" & SelectCategory 'Open the file for reading Set WordFile = FsoObject.OpenTextFile(InputFile, 1) 'Set this variable to zero. It represents the number of words in the file NoWordsInFile = 0 'Count the number of words in the file Do while False = WordFile.AtEndOfStream 'Read a line WordFile.ReadLine() 'Keep count of the number of words (or lines) read NoWordsInFile = NoWordsInFile + 1 'If the loop iterates more than 50 times something is wrong If NoWordsInFile > 50 Then Exit Do End If Loop 'Close the file when done counting the number of words (or lines) WordFile.Close 'Pick a random number between 1 and the number of words in the file Randomize RandomNo = FormatNumber(Int((NoWordsInFile + 1) * Rnd),0) 'Open the file for reading Set WordFile = FsoObject.OpenTextFile(InputFile, 1) 'Skip the reading of all words prior to the randomly selected word For LinesInFile = 1 to RandomNo - 1 'Read the randomly selected word WordFile.SkipLine() Next 'Return the randomly selected word to the calling statement RetrieveWord = WordFile.ReadLine() 'Close the file when done WordFile.Close End Function

Create the GetWordFileLocation() Function

The RetrieveWord() function calls upon the GetWordFileLocation() function, shown below, to retrieve the location of the folder where the Hangman game's word files are stored (that is, the function retrieves the information stored in the Windows registry by the HangmanSetup.vbs script).

'This function retrieves the location of the folder where the word files are 'stored Function GetWordFileLocation() 'Get the folder name and path from its assigned registry value GetWordFileLocation = WshShl.RegRead("HKCUVBGamesHangmanListLocation") End Function

Create the SelectAWordCategory() Function

The RetrieveWord() function also calls upon the SelectAWordCategory() function, shown next, to prompt the player to select a word category from which the game's mystery word should be randomly selected. This function takes one argument, TargetFolder, which is the location of the folder where the word files are stored. The function then displays a list of word categories based on the word files stored in the folder and prompts the player to select one. If the player fails to make a selection, the function automatically specifies the General category as the default. Again, I've added plenty of comments to the function to document its construction.

'This function returns a word category Function SelectAWordCategory(TargetFolder) 'Specify the location of the folder that stores the word files Set GameFolder = FsoObject.GetFolder(TargetFolder) 'Get a list of files stored in the folder Set GameFiles = GameFolder.Files Selection = "" 'Loop through the list of word files For Each WordList In GameFiles 'Build a master string containing a list of all the word files FileString = FileString & WordList.Name 'Remove the .txt portion of each file's filename. CharactersToRemove = Len(WordList.Name) - 4 'Build a display string showing the category names of each word file Selection = Selection & Left(WordList.Name, CharactersToRemove) & vbCrLf Next ValidResponse = "No" 'Loop until a valid category selection has been made Do Until ValidResponse = "Yes" 'Prompt the player to select a word category Choice = InputBox("Please specify the name of a word category from " & _ "which game words will be selected." & vbCrLf & vbCrLf & _ "Available Categories:" & vbCrLf & vbCrLf & _ Selection, "Pick a Category" , "General") 'If the input typed by the player is not in the master string the player 'must try again If InStr(UCase(FileString), UCase(Choice)) = 0 Then MsgBox "Sorry but this is not a valid category. Please try again." Else ValidResponse = "Yes" End If Loop 'If the player typed nothing then specify a default word category If Len(Choice) = 0 Then Choice = "General" End If 'Add the .txt portion of the filename back SelectAWordCategory = Choice & ".txt" End Function

Viewing the Completed Hangman Script

That's it! Your new and improved version of the Hangman script, shown next, should be ready for testing. Don't forget to test it thoroughly and to have someone else test it as well.

'************************************************************************* 'Script Name: Hangman-2.vbs 'Author: Jerry Ford 'Created: 12/14/02 'Description: This is a registry-enabled version of Hangman.vbs '************************************************************************* 'Initialization Section Option Explicit Const cTitlebarMsg = "VBScript HANGMAN" Dim Choice, GameWord, NoMisses, NoRight, SplashImage, PlayOrNot, MsgText Dim PlayAgain, WrongGuesses, RightGuesses, WordGuessed, LetterCounter Dim TempStringTwo, WordLetter, DisplayString, FlipCounter, TempStringOne Dim RandomNo, ProcessGuess, GameStatus, CheckAnswer, WshShl, GameFolder Dim FsoObject, GameFiles, Selection, FileString, CharactersToRemove Dim ValidResponse, SelectCategory, InputFile, WordFile, NoWordsInFile Dim LinesInFile, WordList 'Set up an instance of the FileSystemObject Set FsoObject = CreateObject("Scripting.FileSystemObject") 'Set up an instance of the WshShell object Set WshShl = WScript.CreateObject("WScript.Shell") 'Main Processing Section PlayOrNot = DoYouWantToPlay() If PlayOrNot = 6 Then 'User elected to play the game PlayTheGame() End If SplashScreen() WScript.Quit() 'Procedure Section Function DoYouWantToPlay() 'Display the splash screen and ask the user if he or she wants to play SplashImage = Space(100) & "***********" & vbCrLf & _ "W E L C O M E T O " & Space(68) & "*" & Space(18) & "*" & vbCrLf & _ Space(100) & "0" & Space(18) & "*" & vbCrLf & _ "V B S c r i p t H A N G M A N !" & Space(50) & "--||--" & Space(15) & _ "*" & vbCrLf & Space(99) & "/" & Space(1) & "" & Space(17) & "*" & _ vbCrLf & Space(120) & "*" & vbCrLf & Space(120) & "*" & vbCrLf & _ space(113) & " ******* " & vbCrLf & _ "Would you like to play a game?" & vbCrLf & " " DoYouWantToPlay = MsgBox(SplashImage, 36, cTitlebarMsg) End Function Function PlayTheGame() 'Initialize variables displayed the game's initial popup dialog NoMisses = 0 NoRight = 0 WrongGuesses = "" RightGuesses = "" 'Get the game a mystery word GameWord = RetrieveWord() 'Call the function that formats the initial popup dialog's display string DisplayString = InitialDisplayString() TempStringOne = GameWord 'Let the player start guessing Do Until NoMisses = 6 'Collect the player's guess Choice = InputBox(vbCrLf & vbTab & DisplayString & vbCrLf & vbCrLf & _ vbCrLf & "No. of Misses: " & NoMisses & " " & vbTab & _ "Incorrect:" & WrongGuesses & vbCrLf & vbCrLf & vbCrLf & _ "Type a letter and click on OK." , cTitleBarMsg) 'Determine if the player has quit If Choice = "" Then Exit Function End If ProcessGuess = FirstLevelValidation() 'The Player wants to quit the game If ProcessGuess = "ExitFunction" Then Exit Function End If 'The player typed invalid input If ProcessGuess <> "SkipRest" Then ProcessGuess = SecondLevelValidation() Select Case ProcessGuess Case "DuplicateWrongAnswer" MsgBox "Invalid: You've already guessed this incorrect letter." Case "DuplicateRightAnswer" MsgBox "Invalid: You've already guessed this correct letter." Case Else CheckAnswer = TestLetterGuess() If CheckAnswer <> "IncorrectAnswer" Then 'Reset the value of the variable used to build a string containing 'the interim stage of the word as currently guessed by the player TempStringTwo = "" NonGuessedString() 'Check to see if the player has guessed the word GameStatus = CheckIfGameWon() If GameStatus = "yes" Then WordGuessed = "True" Exit Do End If 'Set the value of the temporary string equal to the string created 'by the 'Previous For...Next loop TempStringOne = TempStringTwo 'Clear out the value of the DisplayString variable DisplayString = "" FlipString() End If End Select End If Loop DisplayGameResults() End Function Function InitialDisplayString() 'Create a loop that processes each letter of the word For LetterCounter = 1 to Len(GameWord) 'Use underscore characters to display a string representing each letter InitialDisplayString = InitialDisplayString & "_ " Next End Function 'Determine if the player won or lost and display game results Function DisplayGameResults() 'Set a message depending on whether or not the player figured out the word? If WordGuessed = "True" Then MsgText = "Congratulations, You Win!" Else MsgText = "Sorry, You Lose." End If 'Display the results of the game PlayAgain = MsgBox(vbCrLf & "The word was: " & UCase(GameWord) & vbCrLf & _ vbCrLf & vbCrLf & MsgText & vbCrLf & vbCrLf & vbCrLf & _ "Would you like to play again?" , 4, cTitleBarMsg) 'Find out if the player wants to play another game If PlayAgain = 6 Then 'If the answer is yes, reset the following variables and start a new game DisplayString = "" TempStringTwo = "" PlayTheGame() End If End Function 'This function retrieves a randomly selected word from a word file Function RetrieveWord() 'Locate the folder where collections of game words are stored GameFolder = GetWordFileLocation() 'Get the player to select a word category SelectCategory = SelectAWordCategory(GameFolder) 'Create the complete path and filename for the selected word file InputFile = GameFolder & "" & SelectCategory 'Open the file for reading Set WordFile = FsoObject.OpenTextFile(InputFile, 1) 'Set this variable to zero. It represents the number of words in the file NoWordsInFile = 0 'Count the number of words in the file Do while False = WordFile.AtEndOfStream 'Read a line WordFile.ReadLine() 'Keep count of the number of words (or lines) read NoWordsInFile = NoWordsInFile + 1 'If the loop iterates more than 50 times something is wrong If NoWordsInFile > 50 Then Exit Do End If Loop 'Close the file when done counting the number of words (or lines) WordFile.Close 'Pick a random number between 1 and the number of words in the file Randomize RandomNo = FormatNumber(Int((NoWordsInFile + 1) * Rnd),0) 'Open the file for reading Set WordFile = FsoObject.OpenTextFile(InputFile, 1) 'Skip the reading of all words prior to the randomly selected word For LinesInFile = 1 to RandomNo - 1 'Read the randomly selected word WordFile.SkipLine() Next 'Return the randomly selected word to the calling statement RetrieveWord = WordFile.ReadLine() 'Close the file when done WordFile.Close End Function 'This function retrieves the location of the folder where word files are 'stored Function GetWordFileLocation() 'Get the folder name and path from its assigned registry value GetWordFileLocation = WshShl.RegRead("HKCUVBGamesHangmanListLocation") End Function 'This function returns a word category Function SelectAWordCategory(TargetFolder) 'Specify the location of the folder that stores the word files Set GameFolder = FsoObject.GetFolder(TargetFolder) 'Get a list of files stored in the folder Set GameFiles = GameFolder.Files Selection = "" 'Loop through the list of word files For Each WordList In GameFiles 'Build a master string containing a list of all the word files FileString = FileString & WordList.Name 'Remove the .txt portion of each file's filename. CharactersToRemove = Len(WordList.Name) - 4 'Build a display string showing the category names of each word file Selection = Selection & Left(WordList.Name, CharactersToRemove) & vbCrLf Next ValidResponse = "No" 'Loop until a valid category selection has been made Do Until ValidResponse = "Yes" 'Prompt the player to select a word category Choice = InputBox("Please specify the name of a word category from " & _ "which game words will be selected." & vbCrLf & vbCrLf & _ "Available Categories:" & vbCrLf & vbCrLf & _ Selection, "Pick a Category" , "General") 'If the input typed by the player is not in the master string, the player 'must try again If InStr(UCase(FileString), UCase(Choice)) = 0 Then MsgBox "Sorry but this is not a valid category. Please try again." Else ValidResponse = "Yes" End If Loop 'If the player typed nothing, then specify a default word category If Len(Choice) = 0 Then Choice = "General" End If 'Add the .txt portion of the filename back SelectAWordCategory = Choice & ".txt" End Function 'This function displays the game splash screen Function SplashScreen() MsgBox "Thank you for playing VBScript Hangman Jerry Ford 2002." & _ vbCrLf & vbCrLf & "Please play again soon!", , cTitlebarMsg End Function 'Validate the player's input Function FirstLevelValidation() 'See if the player clicked on cancel or failed to enter any input If Choice = "" Then FirstLevelValidation = "ExitFunction" Exit Function End If 'Make sure the player only typed 1 letter If Len(Choice) > 1 Then MsgBox "Invalid: You must only enter 1 letter at a time!" FirstLevelValidation = "SkipRest" Else 'Make sure the player did not type a number by accident If IsNumeric(Choice) = "True" Then MsgBox "Invalid: Only letters can be accepted as valid input!" FirstLevelValidation = "SkipRest" Else FirstLevelValidation = "Continue" End If End If End Function Function SecondLevelValidation() 'Check to see if this letter is already on the incorrectly guessed list If Instr(1, WrongGuesses, UCase(Choice), 1) <> 0 Then SecondLevelValidation = "DuplicateWrongAnswer" Else 'Check to see if this letter is already on the correctly guessed list If Instr(1, RightGuesses, UCase(Choice), 1) <> 0 Then SecondLevelValidation = "DuplicateRightAnswer" End If End If End Function Function CheckIfGameWon() 'Check and see if the player has guessed all the letters that make up 'the word. If so set the indicator variable and exit the Do...Until loop If NoRight = Len(GameWord) Then CheckIfGameWon = "yes" End If End Function Function NonGuessedString() 'Loop through the temporary string For LetterCounter = 1 to Len(TempStringOne) 'Examine each letter in the word one at a time WordLetter = Mid(TempStringOne, LetterCounter, 1) 'Otherwise add a underscore character indicating a non-matching guess If UCase(WordLetter) <> UCase(Choice) Then TempStringTwo = TempStringTwo & WordLetter Else 'The letter matches the player's guess so add it to the temporary string NoRight = NoRight + 1 RightGuesses = RightGuesses & " " & UCase(Choice) TempStringTwo = TempStringTwo & "_" End If Next End Function Function FlipString() 'Spin through and reverse the letters in the TempStringTwo variable 'In order to switch letters to underscore characters and underscore 'characters to the appropriate letters For FlipCounter = 1 to Len(TempStringTwo) 'Examine each letter in the word one at a time WordLetter = Mid(TempStringTwo, FlipCounter, 1) 'Replace each letter with the underscore character If WordLetter <> "_" Then DisplayString = DisplayString & "_ " Else 'Replace each underscore character with its appropriate letter DisplayString = DisplayString & Right(Left(GameWord,FlipCounter),1) & " " End If Next End Function Function TestLetterGuess() If Instr(1, UCase(GameWord), UCase(Choice), 1) = 0 Then 'Add the letter to the list of incorrectly guessed letters WrongGuesses = WrongGuesses & " " & UCase(Choice) 'Increment the number of guesses that the player has made by 1 NoMisses = NoMisses + 1 'If the player has missed 6 guesses, then he has used up all his chances If NoMisses = 6 Then WordGuessed = "False" End If TestLetterGuess = "IncorrectGuess" Else TestLetterGuess = "CorrectGuess" End If End Function

Summary

In this chapter, you learned how to write scripts that programmatically interact with the Windows registry; this included reading, writing, and modifying registry keys and values. These new programming techniques provide you with tools for externalizing script configuration information, allowing you to change your script configuration settings without having to make direct modifications to your scripts, and without having to worry about making mistakes while you do it. In addition, I showed you how to used text files as another source of data input for your VBScripts.

Challenges

  1. Create new collection of word files to increase the number of categories available to the player.
  2. Add an error-handling routine to the HangmanSetup.vbs script, and use it to report any problems that may occur when the script attempts to perform the RegWrite() method.
  3. Modify HangmanSetup.vbs to display a popup dialog that asks the user to agree to abide by any terms that you choose to specify in order to play the game. Store a value indicating whether or not the user has accepted the terms in the registry. Check this value each time the Hangman game is started, allowing the user to play only if the terms have been accepted and prompting the user to accept the terms again if they have not been accepted yet.
  4. Create and store a variable in the registry and modify Hangman.vbs to increment it every time the game is started. Use this value to track the number of games played. Check this value each time the game starts to see if it exceeds a value of 20. Then, if the user has not yet accepted your terms, prevent the game from running and force the user to accept your terms in order to play.

Категории