Wyo VB Ch. 5 Lecture Notes
You only have to read pp. 155-162 of the textbook in Chapter 5. We
will not be studying context menus or toolbars. Most of the topics on this page of notes are not explained in Ch. 5 of the textbook.
Objective #1 - Use a MessageBox to
display output.
- In a MessageBox statement, you can use the Show method to display a message to the user in a modal dialog box. A dialog box is a small form with a message or question. A dialog box is modal, as opposed to modeless, if the user is forced to interact with it before returning to another form.
- A message box can be used as a standalone statement with only one string parameter to display a message and provides an OK button for the user to click to continue the program as in:
MessageBox.Show("Hello World")
- A second parameter can be specified to place a customized title in the title bar of the message box as in
MessageBox.Show("Hello World", "Fun Game ")
- A third parameter can be specified to provide different sets of buttons. For example, the following example could be used to display a message box that contains a Cancel button in addition to the standard OK button for the user to click
intAnswer = MessageBox.Show("Would you like to continue?", "Fun Game", MessageBoxButtons.OKCancel)
The value 1 will be returned by the Show method and stored in the variable intAnswer of the user clicks the OK button. The value 2 will be stored in intAnswer if the user clicks the Cancel button.
Instead of MessageBoxButtons.OKCancel, you can place the following other constants as the third parameter:
MessageBoxButtons.OK - provides a single OK button (this is the default)
MessageBoxButtons.OKCancel - provides OK and Cancel buttons
MessageBoxButtons.AbortRetryIgnore - provides three buttons, Abort, Retry, and Ignore
MessageBoxButtons.RetryCancel - provides Retry and Cancel buttons
MessageBoxButtons.YesNo - provides Yes and No buttons
MessageBoxButtons.YesNoCancel - provides three buttons, Yes, No, and Cancel
The following values are returned by the Show method in result of the user clicking the associated buttons:
1 OK
2 Cancel
3 Abort
4 Retry
5 Ignore
6 Yes
7 No
- A fourth parameter can be used with the Show method to include an icon on the message box. The following statement places an asterisk in the lower-left corner of the message box:
MessageBox.Show("Hello World", "Fun Game", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
Other constants that can be used for different icons as the fourth parameter are
MessageBoxIcon.Asterisk, MessageBoxIcon.Error, MessageBoxIcon.Exclamation, MessageBoxIcon.Hand, MessageBoxIcon.Information, MessageBoxIcon.None, MessageBoxIcon.Question, MessageBoxIcon.Stop, and MessageBoxIcon.Warning
- If you don't want to specify a title caption but you do wish to specify a certain set of buttons, you must include the button constant as the third parameter and not the second parameter. You can place a blank space after the second parameter as in:
intAnswer = MessageBox.Show("Would you like to continue?", " ", MessageBoxButtons.OKCancel)
- A fifth parameter can be used to specify which button
is the default button that will be invoked if the user immediately presses
the Enter key. A sixth parameter can be used to set other options for the
message box. See the VB Help for details on these two parameters. You will
not be tested on them in this course. For example, to make the Cancel button
the default button that would activate if the user presses the Enter key,
you can use the following statement
intAnswer = MessageBox.Show("Would you like to continue?", , MessageBoxButtons.Cancel)
- The full syntax for the MessageBox.Show method is
variable = MessageBox.Show(text [, caption][, buttons][, icon][, defaultButton][,
options])
where the square brackets are used to show optional parameters).
Objective #2 - Use an InputBox to
obtain user input.
- Input boxes are similar to message boxes except they also provide a textbox for the user to fill in. An input box can accept a maximum of 255 characters. An input box is appropriate to have the user input his or her name or a short answer to a question. Two buttons are included on an input box, OK and Cancel. If the user clicks OK, the data that he or she typed into the input box's text box will be returned and assigned to the variable in the assignment statement. Unlike a message box statement, you would never use an InputBox statement as a standalone statement. Here is an example
strName = InputBox("Enter your name:")
- Like the message box that is explained above, an optional second parameter can be used to specify the title of the input box's modal dialog box.
- A third parameter can be provided to specify the default value that appears in the text box.
strUserInput = InputBox("Enter your age:", " ", "0")
Notice that no title was provided in the example above but the second comma had to be included.
- The value entered by the user and returned by the InputBox method may be treated by VB as a string. It is safest to convert this value to a numeric value using the Val function or another means as in
Dim strUserInput As String
Dim intAge As Integer = 0
strUserInput = InputBox("Enter your age:")
intAge = Val(strUserInput)
Clean input is input typed by the user that is in the correct format without extra spaces or symbols. It is best to use functions like Trim and Val and If statements to correct the user's inputed data.
Objective #3 - Use two-dimensional arrays.
- A two-dimensional array is an extension of a one-dimensional array. Elements in a two-dimensional array are stored in rows and columns. Two-dimensional arrays are more convenient and efficient than one-dimensional arrays to store certain sets of data.
- You could use the following statement to declare a two-dimensional array...
Dim mintScores(4, 2) As Integer
In this example, assume that the array is being used as a module-level variable.
The m is used in the name to indicate that assumption. The prefix int is
used of course to show that the array stores integers. By parentheses indicate
that mintScores is an array but by placing two integer values in the parentheses,
we have indicated that it is a two-dimensional array with 5 rows and 3 columns.
The first value in the parentheses always refers to the number of rows in
the array. The second value always refers to the number of columns. I remember
this by thinking of the type of soda RC Cola, which is the official soft
drink of the Wyo Computer Science Department.
It is a little confusing but because Visual Basic numbers the rows from 0 to 4, there are a total of 5 rows. Likewise, there are a total of 3 columns in this example numbered from 0 to 2. Other computer languages also provide a zero column and a zero row but they usually require that you place the actual number of desired rows and columns in the parentheses of the declaration statement.
- The following declaration statement could be used to initialize a two-dimensional array rather than having VB store the default value 0 in each of the array's elements:
Dim mintScores(,) As Integer = {{100, 200, 300}, _
{100, 100, 100}, _
{200, 200, 200}, _
{299, 300, 298}, _
{150, 150, 150}}
This statement could have been typed on one line of code but it is easier to understand the two-dimensional array as a set of rows and columns by breaking it up over several lines of code with the line continuation operator ( _ ). The number of rows and columns does not have to be provided in the set of parentheses since VB can easily count the number of values placed in the sets of curly braces ( { } ). However, a comma must be placed in the set of parentheses for VB to know that it is a two-dimensional array rather than a one-dimensional array.
- The following example of nested For loops allows the user to input values into every position of the two-dimensional array mintScores
For intRow = 0 To 4
For intCol = 0 To 2
mintScore(intRow, intCol) = Val(InputBox("Enter the next score:"))
Next
Next
The loop variables intRow and intCol are used in the parentheses of the array in order to allow the user to fill every element of the array.
- The following algorithm could be used to compute the sum of the elements in a two-dimensional array
For intRow = 0 To 4
For intCol = 0 To 2
intSum = intSum + mintScores(intRow, intCol)
Next
Next
The statement in the body of the nested loop is an accumulator statement and keeps the running total in the variable intSum. Notice the use of the loop variables intRow and intCol in the parentheses. This is a pattern that you will often see with code that uses two-dimensional arrays.
- The following algorithm could be used to find the largest value stored in a two-dimensional array
For intRow = 0 To 4
For intCol = 0 To 2
If (mintScores(intRow, intCol) > intMax) Then
intMax = mintScores(intRow, intCol)
End If
Next
Next
This is really just a linear search but applied to a two-dimensional array. The algorithm goes row-by-row from left to right looking for a value that is larger than the one currently stored in intMax. When it finds one, it replaces intMax with the new value.
- The following algorithm could be used to compute the averages
of the values stored in each row of elements in a two-dimensional array and
stores these separate averages into another one-dimensional array named dblAverages.
For intRow = 0 To 4
intSum = 0
For intCol = 0 To 2
intSum = intSum + mintScores(intRow, intCol)
Next
dblAverages(intRow) = intSum / 3
Next
Notice how it is necessary to reset the value of intSum to zero in each iteration of the outer loop
Objective #4 - Use timer objects for animation.
- A Timer object can be used to animate
objects without the user having to press keys. A Timer object has an Interval
property which is a number of milliseconds. If the timer's Enabled property
is true, VB counts off this number of milliseconds and executes any code
typed in the timer's Tick method and does so continuously until the timer
is disabled.
- Since the Interval property is a number of milliseconds, you must set it to 1000 if you want the timer to execute every one second.
- The proper prefix for a timer is tmr. A timer does not appear on the interface of the form. You will see it in the component tray. Double-click the timer to open up the Code window to its Tick method.
- A Timer can be enabled by setting its Enabled property to True or by calling its Start method.
tmrEnemy.Enabled = True
or
tmrEnemy.Start()
- A Timer can be disabled by setting its Enabled property to False or by calling its Stop method.
tmrEnemy.Enabled = False
or
tmrEnemy.Stop()
- It is effective to type animation and collision detection code into the Tick method of a timer as in:
Private Sub tmrEnemy1_Tick(...)
tmrEnemy1.Left = tmrEnemy1.Left + 10
If (picEnemy1.Left < picMissile1.Left And picEnemy1.Left + picEnemy1.Width > _
picMissile1.Left + picMissile1.Width) Then
tmrEnemy1.Stop()
picEnemy1.Visible = False
End If
End Sub
Objective #5 - Measure elapsed time with the DateAndTime.Timer
method.
Objective #6 - Play sound clips.
- To play a sound clip in a VB program, you should include
the following declaration statement for the method PlaySound in the general
declarations area of your form (where you declare module-level variables).
Private Declare Auto Function PlaySound Lib "winmm.dll" (ByVal
lpszSoundName As String, ByVal hModule As Integer, ByVal dwFlags As Integer)
As Integer
You do not have to memorize or fully understand this statement
but you should be aware of the need to have it in a program that plays sound
in a VB program.
At the point where you want an actual sound to play, you then use the PlaySound method with a call statement like this
PlaySound("buzzer.wav",
0, 1)
The path of the actual sound file must be included as the first parameter
of the method. This statement only works if the audio file buzzer.wav is located
in the same folder as the .exe executable file in your VB project. The exe
file is usually
stored in the bin folder. However, if you move the exe file or wish to save
the sound file in another folder location, you must provide the exact file
path to the audio file in the set of double quotes. However, for good style
the sound file should be located in a folder named Sounds. So it's best
to use this
syntax:
PlaySound(System.AppDomain.CurrentDomain.BaseDirectory() + "..\..\Sounds\buzzer.wav",
0, 1)
where the System.AppDomain.CurrentDomain.BaseDirectory() method is used.
This method causes VB to "figure out" what folder (also known as a directory)
stores the exe executable file. The two dots in the path of the file mean "go
up one level" in
the folder hierarchy. From the perspective of the exe file you must go up
one level of folders to get to the point where you would then double-click
the sounds folder and then find the actual sound file named buzzer.wav. As of VB 2005, the Debug folder is considered to be the base directory for a project since it contains the exe file.
The PlaySound method must be spelled with a capital P and a capital S. Otherwise it won't work correctly. Sound files with the .wav file extension should work in VB. Some other sound formats are supported but unfortunately mp3 sounds cannot be used with the PlaySound method.
- See this
Microsoft link for instructions on using a Windows Media Player
object. See the Player
object API
for details. The main steps are to first right-click the Toolbox and select Add/Remove Items. Select the Windows Media Player control (Msdxm.ocx). When the Windows Media Player control icon appears in the Toolbox, add an object to your form. Then use code like this in a button named btnPlay
btnPlay.Enabled = False
Application.DoEvents()
Dim filename As String = Application.StartupPath
filename = filename.Substring(0, filename.Length - 3)
AxMediaPlayer1.AutoStart = False
AxMediaPlayer1.Filename = filename & "test.wav"
AxMediaPlayer1.Play()
In the AxMediaPlayer1_EndOfStream method add the following line of code btnPlay.Enabled = True
Objective #7 - Write data to a text file.
- Until this point in this course, you have not been able to permanently store data from one execution of a program to another separate execution. Variables can be used to store data of course but once the program ends this data is wiped out. For example, to store a high score of a game or to store names, addresses and phone numbers into an address book are two situations in which you would store data to a text file.
- The text file where you need to store date is not part of the VB program. It is a file that could be viewed like most others on the computer using a program such as Microsoft Word. We will use the program Notepad however to create, view, and edit text files. While many file extension could be used for text files, we will use the common file extension .txt.
- Generally, for good style, text files that are used to store data with a VB program should be stored in the same location as the project. I prefer that you create a folder named files that is next to your projects's bin folder (and perhaps sounds folder). It is best to first create a file that you want to use to store data with the program Notepad. Type some "dummy data" into the file. For example, if we are going to use a file named highscore.txt to store the high score to a VB game, we would logically type a zero into the file.
- In order to overwrite the zero that is stored in highscore.txt, we must first create a StreamWriter object variable. Then we must connect this StreamWriter with the file itself. Finally, we are in a position to use the WriteLine method of the StreamWriter to actually store a new number overtop of the old number.
To write data to a text file, you must first declare a variable as a
StreamWriter with a statement like this
Dim outputFile As StreamWriter
Then you must create
the
connection
between
the
StreamWriter variable
and
the
file itself. That is why this kind of variable is also known as a "file
pointer". To create this connection, you must "open" the file with a statement
like this:
outputFile = File.OpenText("highscores.txt")
where the file pointer outputFile now points ("is connected to") the actual file
on
the
hard
drive
named
highscores.txt. It is good style though to store your text files in a separate
folder named files similarly to how audio files should be stored in a separate
folder named sounds. So the following syntax should be used to open a file:
outputFile = File.OpenText(System.AppDomain.CurrentDomain.BaseDirectory() + "..\files\highscores.txt")
This technique does not open the file highscores.txt so that a person would see
its window on the screen. Rather the open connection is established behind the
scenes.
- When a text file is opened the file pointer points to
the beginning of the first line of data in that file. The WriteLine method
is used in the following statement to write the value stored
in the variable mintScore onto
the first line of the file highscores.txt
outputFile.WriteLine(mintScore)
- It's good style to properly close
the connection between a StreamWriter and the
file
that
it
is connected
to
when
you are
finished
using it. This is done with the Close method like this
outputFile.Close()
If you don't close a text file when it's finished being used you risk
the danger of corrupting the file and losing any data stored there.
- When you connect a StreamWriter to a text file, it assumes
that you want to overwrite the data that is stored there. By default, it
will not automatically append data to the end of the existing file. Usually,
it is wise to first open the file with a StreamReader (explained below) to
read the original data from the file into variables in your VB program, then
close the StreamReader and open the file with a StreamWriter. Unfortunately,
a text file can only be opened in either the write mode or the read mode.
That is, you cannot read and write at the same time to the same file. There
is an append mode that can be used with a StreamWriter that can be used to
append data to the end of an existing text file. We will not be studying
the append mode in this course however.
- In order to use a StreamWriter or a StreamReader object in your program,
you must add the line of code
Imports System.IO
to the very top of your program above the line of code Public Class Form1.
Objective #8 - Read data from a text file.
- The data in an existing text file can be stored in variables in your program by reading the file. It doesn't matter whether the text file was created with the program Notepad or it was a file created using a StreamWriter.
- A text file used with StreamReader or StreamWriter is often called a sequential
access file. Each line of data is called a record and the records are therefore stored sequentially. It is similar to a video cassette tape. You can only read the fourth line of data until after you've read the first three lines of data. You cannot jump ahead and read a random line of data. Furthermore, with a sequential access file, you cannot move backwards very easily. Once you've read a given line of data, the cursor automatically advances to the beginning of the next line of data.
- To read data from a text file, you must first declare
a variable as a StreamReader with a statement like this
Dim inputFile As StreamReader
Then you must create the connection between the StreamReader variable and the file itself with a statement like
inputFile = File.OpenText(System.AppDomain.CurrentDomain.BaseDirectory()
+ "..\files\highscores.txt")
Then the following statement would be used to "read" the first line of data
in the text file and store that value into the variable intHighScore
intHighScore = Val(inputFile.ReadLine())
Don't forget to close the text file when you're finished using it.
inputFile.Close()
- A random access file is different from
a sequential access file in that the computer organizes the data in records
that have the same size. We will
not be using random access files in this course but they are very convenient
in professional VB programming. A random access file is like a database (e.g.
Microsoft Access, FileMaker Pro, or SQL). Each record contains multiple fields
such as first_name, last_name, phone_number, etc. The space reserved for
each person's first_name is the same even if one person's name is a lot shorter
than another's. A bit of space is wasted in a random access file but it allows
a programmer to instantly look up and read any record no matter where it
is in the file. Unlike a sequential access file, the records do not have
to be read or written in sequential access but rather "random access".
A random access file is like a CD or DVD. You can immediately play any track
or chapter at any time. Even a DVD seems better than a videocassette tape,
in computer programming depending on the situation, it can be more efficient
sometimes to use a sequential access file rather than a random access file
to save space.
Objective #9 - Create and use functions.
- You have already learned how to create your own method and how to call that method from a call statement. We'll call those general methods. There's another variation of a general method that can be used to compute a value and return that value to the call statement. This type of method is often called a function.
- The following method (i.e. function) named GetRandom generates a random integer between 1 and 6 and returns that value to the call statement in the btnRollDice_Click method
Private Sub btnRollDice_Click(. . .)
Dim intNum As Integer = 0
intNum = intGetRandom()
MessageBox.Show(intNum)
End Sub
Private Function intGetRandom() As Integer
Dim intRandom As Integer = 0
intRandom = Math.Floor(Rnd() * 6) + 1
Return intRandom
End Function
The first line of a function is called the function header. The return type of
a function is the data type that is typed after the keyword As in the function
header. The
name
that
you
give
to
a
function
such
as intGetRandom in the example above, should begin with the prefix associated
with
the data type
of the value that
the function returns. If the function returns an Integer then the prefix should
be int. If it returns a Double or a String its prefix should be dbl or str, respectively.
- A function can accept one or more parameters that are
sent from the call statement to the function. This is called passing parameters.
The parameter(s) is typed in the parentheses of the call statement. The following
variation of the example above allows the user to determine the range in
which the random integer is generated.
Private Sub btnRollDice_Click(. . .)
Dim intNum As Integer = 0
Dim intNumSides As Integer = 0
intNumSides = Val(InputBox("How many sides are on your dice?")
intNum = intGetRandom(intNumSides)
End Sub
Private Function intGetRandom(ByVal intSides As Integer) As Integer
Dim intRandom As Integer = 0
intRandom = Math.Floor(Rnd() * intSides) + 1
Return intRandom
End Function
Notice that the name of the parameter in the call statement, intNumSides, does
not have to match the name of the parameter in the function header. Visual Basic
knows to pass the value stored in intNumSides to the parameter intSides even
though they have different names. The parameter in the call statement is known
as an actual parameter (or argument) while the parameter in the function header
is called a formal parameter. The word ByVal must be typed in front of each parameter
in a function header and the data type of the parameter must be typed after the
keyword As. Using the keyword ByVal means that the actual parameter is being
passed by value and that it will not be changed even if the corresponding formal
parameter in the called function is changed. Using the word ByRef instead of
ByVal causes any changes in the corresponding formal parameter to affect the
actual parameter. Passing a parameter by reference (i.e. with ByRef) is more
dangerous but can save memory when passing large objects rather than numbers.
There are times though when you need to pass a large object and passing by reference
is worthwhile. In this VB course, you will not be responsible for knowing how
to pass ByRef nor will you probably need to pass by reference.
- If there are two or more parameters in the parentheses
of the call statement, they match up in a one-to-one correspondence with
the parameters that are listed in the function header. In this VB course,
you must type the same number of parameters in the call statement as there
are in the function header. Also, the data types for the parameters in the
call statement must exactly match the order of the data types in the function
header.
- Another example of a function is
Private Function dblComputeTax(ByVal dblPrice As Double) As Double
Dim dblPriceWithTax As Double
dblPriceWithTax = dblPrice + dblPrice * 0.06
Return dblPriceWithTax
End Function
- A task that involves the computation of a single numerical value such as computing tax or rounding a number is often handled by a function rather than a normal method. If the task that you wish to place into a method does NOT involve the computation of single numerical value then you should probably use a normal method instead of a function. For example, if you need to move an object to the left on the form window, you could use a normal method named move.
- A function is different from a general procedure in that a function always returns a single value to the method or function that calls it. A normal method does not return a value.
Objective #10 - Use multiple forms in a project
- Often, in commercial applications, a splash form is the
first form that shows up when a program is launched. The splash form presents
the name and version number of the program as well as the names of the authors,
etc. The splash form can distract the user for a little while the rest of
the program loads into the memory. When the user clicks the splash form or
presses any key, the splash form disappears and the first form of the application
is presented.
- To include a second form in a project you can use the menu command Project/Add WindowsForm. The name of the form should start with a capital letter and include the .vb file extension.
- The second form will appear in the Solution Explorer window. You can create a desired interface and type code into this form's Code Window like any other form.
- To have the program show this second form when the user
clicks a button on the splash form, you could use the following:
Private Sub btnStart_Click(...)
Form2.Show()
Me.Hide()
End Sub
The name Form2 is the name of the other form. The Show method displays it on the screen. The Hide method is being used to make the splash form invisible. This is not necessary of course but it is standard to make a splash screen disappear in this situation. The keyword Me is used to designate the current form whose Code Window you are typing in. In other words, Me is the splash form itself in this example.
- However, it is better to create a reference to a new form in the standard code module of a project. After adding the new form to your project with the Project/Add Form command as explained above, you can type code that creates an instance of the form. Ask the teacher how to insert a standard code module to your project. (Or, you could add a Sub Main to a class and set the class as your project's startup object.) In the code module type the following code in Sub Main()
Dim myForm2 As Form2
If myForm Is Nothing Then
myForm = New Form2
End If
myForm.Show()
- In order to communicate between two forms, you can supply a reference to Form1 on Form2 and vice versa. Here's the top of Form2
Public Class Form2
Inherits System.Windows.Forms.Form
Public myCaller As Form1
Then, in a button's Click event on Form1, you can use the code
Dim myForm As Form2
Private Sub Button1_Click(...)
If myForm Is Nothing Then
myForm = New Form2
myForm.myCaller = Me
End If
myForm.Show()
End Sub
Form2 can now access public properties and methods of Form1 through the myCaller variable.
Objective #11 - Create arrays of objects.
- Previously we learned how to create arrays of Integer's, Double's, and String's. We also previously learned how to make an object (e.g. textbox, label, button, picturebox, etc) using code and without double-clicking the VB Toolbox. Well, we can put all of this together to create an array of one kind of object using code. For example, you can create 10 or more "alien" pictureboxes and place them on the screen avoiding the need to create them individually using the mouse. Why would you want to do this? For one, you have more flexibility and control when creating objects with code. Also, it would be very tedious and time consuming to create and edit 30 "alien" picture boxes when you could use a loop in your computer program do the same thing.
- To declare an array of picture boxes you would use the statement
Dim picFrankenstein(5) As New PictureBox
If you want the array to be module-level, you would use the statement
Dim picFrankenstein(5) As PictureBox
without using the keyword New. Then in the Form_Load method perhaps, you would use the code
For J = 0 To 5
picFrankenstein(J) = New PictureBox
picFrankenstein(J).Image = Image.FromFile(System.AppDomain.CurrentDomain.BaseDirectory() + "..\..\images\frankenstein.jpg")
picFrankenstein(J).SizeMode = PictureBoxSizeMode.AutoSize
picFrankenstein(J).Left = Rnd() * 300
picFrankenstein(J).Top = Rnd() * 300
Me.Controls.Add(picFrankenstein(J))
Next
The Me.Controls.Add method must be used to actually place each new picture box onto the current form.