introduction to visual basic - book 1lwc1/files/files/s3_cl... · dim withevents timer1 as new...
TRANSCRIPT
TextBox1
More about
Copyright © HKTA Tang Hin Memorial Secondary School 2012-13
A guide to complete
your VB project in
Visual Basic 2010
*
2
Contents
Chapter 1 Programming Hints for Your Project................................................................... 3
1.1 Introduction ....................................................................................................... 3
1.2 What to expect in this book ............................................................................... 3
Chapter 2 More about Variables and Data Types ............................................................... 4
2.1 Object data type ................................................................................................ 4
2.2 Local type interference ...................................................................................... 4
2.3 New keyword and With keyword ....................................................................... 5
2.4 WithEvents keyword .......................................................................................... 5
Chapter 3 Working with time and timers............................................................................ 6
3.1 Introduction to Timer control ............................................................................ 6
3.2 Measuring time with Date and TimeSpan data type ........................................... 9
3.3 Accuracy of Timer control ................................................................................ 11
3.3.1 Problems with Timer control ................................................................ 11
3.3.2 Improved Timer control........................................................................ 12
3.4 Summary ......................................................................................................... 14
Chapter 4 Adding images to the form ............................................................................... 15
4.1 Display an image with PictureBox control ........................................................ 15
4.2 Alternate choices in displaying images ............................................................. 16
4.3 Resizing an image ............................................................................................ 16
4.4 Behaviour of controls when they are double clicked ........................................ 17
4.5 Using the resources of your project ................................................................. 18
4.6 Using an ImageList to store images .................................................................. 20
3
Chapter 1 Programming Hints for Your Project
1.1 Introduction
When you create a computer program, the
first thing to do is to define the functions of
your program. And you will write your
program according to your own definition.
The idea of the game should be interesting
to you, so you will have the motivation to
finish it. However, since your programming
skills are limited, do not be too ambitious.
Having a simple idea that works is already
enough.
1.2 What to expect in this book
This guide contains intermediate and advanced programming techniques that can be
useful for creating your own Visual Basic project. The content here is not required in the
examination.
This guide also contains example programs that can be copied or modified into your own
program. However, you will not get a step-by-step tutorial of how to complete your
arbitrary complex program. You are not also guaranteed to understand the concepts and
skills used by the examples, since they contain programming skills that takes time to
master.
If you have any difficulties in creating your program, ask your teacher for advice.
Define the Problem
Solve the Problem
Write a Program
Testing and
Debugging
Evaluation
4
Chapter 2 More about Variables and Data Types
2.1 Object data type
If you want to declare a variable that is not limited to a particular type of data, you may
use the Object data type. The Object data type is so flexible that it can store all kinds of
data, including numbers, strings, Booleans and all other things.
To declare an Object, just type one of the following statements. However, if you use the
second statement, do not initialize the variable.
Dim variablename As Object
--- OR ---
Dim variablename
However, Object variables have a lower performance than typed variables, and do not
benefit from the code auto-completion feature of the Visual Basic IDE.
2.2 Local type interference
When you do not supply a data type in the Dim statement, Visual Basic can also find to the
data type from its initial value. This is known as type inference. For example, the statement
“Dim x = 3” declares variable x with a type of Integer.
However, type inference only works for non-static* variables in procedure level (i.e. inside
Sub for Function). In other cases, the variables are given the type Object instead.
* Static variables are declared using the Static keyword instead of Dim keyword. Other variables are
non-static.
5
2.3 New keyword and With keyword
The New keyword is used to create an object, or an instance of a class. The New keyword
can also be used in the Dim statement to infer to a data type. In the following statement,
Timer1 will have a data type of Timer (i.e. the Timer control).
Dim Timer1 As New Timer
The New keyword can also be used with the With keyword to change the value of its
properties. For example:
Dim Timer1 As New Timer With {.Interval = 1000, .Enabled = False}
(Note: You should note the dots before the words Interval and Enabled.)
2.4 WithEvents keyword
The WithEvents keyword in the Dim statement is used to declare an object or control that
allows the Handles keyword to work, and allow the Visual Basic IDE to create events.
Dim WithEvents timer1 As New Timer With {.Interval = 1000}
(Note: The form designer in Visual Basic works by creating similar statements in files like
Form1.Designer.vb)
6
Chapter 3 Working with time and timers
3.1 Introduction to Timer control
In your project, you may want to require the user to finish a task (e.g. do some calculations)
within a specific time. In this case, you need to use a Timer control to do the task.
The Timer controls works by generating the Tick event after a specified time. The user
interface of the Timer control is shown in the screenshot below*.
* The description of Interval property in the screenshot is incorrect.
7
Here are the properties, events and methods of the Timer control.
Name Description
Properties
Enabled Whether the Timer will generate ticks.
Interval The time between two ticks, in milliseconds. The value of
Interval must be at least one.
Events Tick Occurs when the specified timer interval has elapsed and
the timer is enabled.
Methods Start Starts the timer. Same as setting Enabled to True.
Stop Stops the timer. Same as setting Enabled to False.
And here is a simple timer that uses the Timer control:
Example 3.1.1 Simple timer
' Note: Timer1 has an Interval of 1000 and is not Enabled.
Public Class Form1
Private Sub Timer1_Tick(...) Handles Timer1.Tick
LabelTicks.Text = Val(LabelTicks.Text) + 1
End Sub
Private Sub ButtonStart_Click(...) Handles ButtonStart.Click
Timer1.Enabled = True
End Sub
Private Sub ButtonStop_Click(...) Handles ButtonStop.Click
Timer1.Enabled = False
End Sub
End Class
LabelTicks
ButtonStart
ButtonStop
8
It is recommended to create a Timer control in Visual Basic source code instead, i.e.
Dim WithEvents timer1 As New Timer With {.Interval = 1000}
One of the common techniques for using a Timer control is to create a countdown timer.
Please see the example below:
Example 3.1.2 Simple countdown timer
Public Class Form1
Dim WithEvents timer1 As New Timer With {.Interval = 1000}
Private Sub ButtonStartGame_Click(...) Handles
ButtonStartGame.Click
LabelTimeLeft.Text = Val(TextBox1.Text)
ButtonWin.Enabled = True
timer1.Enabled = True
End Sub
Private Sub timer1_Tick(...) Handles timer1.Tick
Dim timeleft As Integer = Val(LabelTimeLeft.Text) - 1
LabelTimeLeft.Text = timeleft
If timeleft <= 0 Then
timer1.Enabled = False ' Disable timer before MsgBox!!!
ButtonWin.Enabled = False
MsgBox("You've lost!")
End If
End Sub
Private Sub ButtonWin_Click(...) Handles ButtonWin.Click
timer1.Enabled = False ' Disable timer before MsgBox!!!
ButtonWin.Enabled = False
MsgBox("You've won!")
End Sub
End Class
LabelTimeLeft
ButtonStartGame
ButtonWin
TextBox1
9
3.2 Measuring time with Date and TimeSpan data type
Visual Basic has a data type dedicated to store date and time information. The data type is
called Date, or System.DateTime.
You can also use the property Date.Now (or simply Now) to get the current time. Of course,
the value of Now is always changing over time.
You may add a time interval to a Date to get a new Date, by the following methods:
Method Example (d is a Date)
AddDays d.AddDays(3)
AddHours d.AddHours(3)
AddMilliseconds d.AddMilliseconds(3)
AddMinutes d.AddMinutes(3)
AddMonths d.AddMonths(3)
AddSeconds d.AddSeconds(3)
For example, “Now.AddSeconds(60)” returns a Date that is 60 seconds in the future,
and “Now.AddDays(-2)” returns a Date that is 2 days in the past.
If you subtract two Dates, you will get a time interval called TimeSpan. To do a subtraction,
use the Subtract method, or the “-” operator. A TimeSpan has the following properties:
Property Description
Days Gets the days component of the time interval.
Hours Gets the hours component of the time interval.
Milliseconds Gets the milliseconds component of the time interval.
Minutes Gets the minutes component of the time interval.
Seconds Gets the seconds component of the time interval.
TotalDays Express the TimeSpan in whole and fractional days.
TotalHours Express the TimeSpan in whole and fractional hours.
TotalMilliseconds Express the TimeSpan in whole and fractional milliseconds.
TotalMinutes Express the TimeSpan in whole and fractional minutes.
TotalSeconds Express the TimeSpan in whole and fractional seconds.
For example, “(Now - start).TotalSeconds” calculates the number of seconds
from start (which is a Date) to Now, expressed in the number of seconds.
10
Finally, relational operators (=, <>, >, <, >=, <=) can also be used with Date.
You can use Date data type with Timer controls to construct a countdown timer below:
Example 3.2.1 Countdown timer (more accurate)
Public Class Form1
Dim WithEvents timer1 As New Timer With {.Interval = 50}
Dim stopTime As Date
Private Sub ButtonStartGame_Click(...) Handles
ButtonStartGame.Click
ButtonWin.Enabled = True
stopTime = Now.AddSeconds(Val(TextBox1.Text))
LabelTimeLeft.Text = Math.Ceiling((stopTime -
Now).TotalSeconds)
timer1.Enabled = True
End Sub
Private Sub timer1_Tick(...) Handles timer1.Tick
LabelTimeLeft.Text = Math.Ceiling((stopTime -
Now).TotalSeconds)
If Now >= stopTime Then
timer1.Enabled = False ' Disable timer before MsgBox!!!
ButtonWin.Enabled = False
MsgBox("You've lost!")
End If
End Sub
Private Sub ButtonWin_Click(...) Handles ButtonWin.Click
timer1.Enabled = False ' Disable timer before MsgBox!!!
ButtonWin.Enabled = False
MsgBox("You've won!")
End Sub
End Class
LabelTimeLeft
ButtonStartGame
ButtonWin
TextBox1
11
3.3 Accuracy of Timer control
3.3.1 Problems with Timer control
In the previous examples, we have made two countdown timers. However, is there any
difference between them? Are they accurate? When you enter 60 seconds, do the
programs actually measures 60 seconds?
We can make a program to check the accuracy of Timer control:
Example 3.3.1 Checking of accuracy of Tick events of Timer
Public Class Form1
Dim WithEvents timer1 As New Timer With {.Interval = 1000}
Dim start As DateTime
Dim ticks As Integer
Private Sub ButtonStart_Click(...) Handles ButtonStart.Click
TextBox1.Clear()
ticks = 0
timer1.Enabled = True
start = Now
End Sub
Private Sub ButtonStop_Click(...) Handles ButtonStop.Click
timer1.Enabled = False
End Sub
Private Sub timer1_Tick(...) Handles timer1.Tick
ticks += 1
TextBox1.AppendText(ticks & " : " &
(Now - start).TotalSeconds & vbCrLf)
End Sub
End Class
The result (see the screen capture) shows
that the interval of each Tick event is a
bit longer than it should. If you measure a
time of one minute, you will get an
unwanted extra 0.8 second!
Note: The second countdown timer is not
affected by this problem.
ButtonStart
ButtonStop
12
3.3.2 Improved Timer control
In the previous section, we discovered a problem with the Timer control. Now we will
solve the problem.
Since we can correctly measure the actual time elapsed, we can solve the problem by
adjusting the Interval property of the Timer control according to the actual time elapsed. If
the time elapsed is too long, then decrease the Interval accordingly to compensate for the
difference. This idea result in the following file, which can be copied into your project.
aTimer class : improved timer
aTimer.vb
Public Class aTimer
Inherits System.Windows.Forms.Timer
Private _start As Date
Private _interval As Integer
Shadows Property Interval As Integer
Set(value As Integer)
_interval = value
MyBase.Interval = value
End Set
Get
Return _interval
End Get
End Property
Overrides Property Enabled As Boolean
Set(value As Boolean)
If value Then
If _interval = 0 Then _interval = MyBase.Interval
MyBase.Enabled = value
_start = Now
Else
MyBase.Enabled = value
End If
End Set
Get
Return MyBase.Enabled
End Get
End Property
Private Sub aTimer_Tick(sender As Object, e As System.EventArgs) Handles
Me.Tick
Dim elapsed = (Now - _start).TotalMilliseconds / _interval
MyBase.Interval = _interval * (Math.Round(elapsed) - elapsed + 1)
End Sub
End Class
13
To use this library, add aClass.vb to your project, and change the Timer declaration into
Dim WithEvents timer1 As New aTimer With {.Interval = 1000}
The only difference is the letter “a” before the word “Timer”. (This is why I recommend
creating Timers in Visual Basic source code.)*
Example 3.3.2 Usage of aTimer (see Example 3.3.1, only one word is changed)
Public Class Form1
Dim WithEvents timer1 As New aTimer With {.Interval = 1000}
Dim start As DateTime
Dim ticks As Integer
Private Sub ButtonStart_Click(...) Handles ButtonStart.Click
TextBox1.Clear()
ticks = 0
timer1.Enabled = True
start = Now
End Sub
Private Sub ButtonStop_Click(...) Handles ButtonStop.Click
timer1.Enabled = False
End Sub
Private Sub timer1_Tick(...) Handles timer1.Tick
ticks += 1
TextBox1.AppendText(ticks & " : " &
(Now - start).TotalSeconds & vbCrLf)
End Sub
End Class
* The word aTimer means the aTimer class, which is declared in aClass.vb. It is a modified Timer control/class
that solved the problem.
ButtonStart
ButtonStop
14
The screenshot indicates that the difference from the expected time and the actual time is
reduced from 0.8s to about 0.01s. Such difference is acceptable for gaming purpose.
3.4 Summary
Now we have studied how the Timer control works, and about its problems and solutions.
The plain Timer control is good enough if
The Tick event is raised only once, or
You do not rely on the accuracy of the Interval property.
However, if you need something like a countdown timer and need to rely on the accuracy
of the time of Tick events, you should use the aTimer library in the notes instead.
15
Chapter 4 Adding images to the form
4.1 Display an image with PictureBox control
To show an image in a form, the easiest idea is to add a PictureBox control.
After you add the PictureBox control, you should change its Image property to see the
dialog box below, click “Local resource”, and click import to add the image.
You should also set the SizeMode property to AutoSize, so the PictureBox can resize itself
to the actual dimensions of the image. Besides the properties dialog, you may also set the
SizeMode property using PictureBox Tasks (see the screenshot below).
16
4.2 Alternate choices in displaying images
You can also add images to other controls such as Button, Label and Form, by setting their
Image property and/or BackgroundImage property. However, each control has different
functions in displaying images.
Control type Property Functions
PictureBox Image Resize image and/or PictureBox
PictureBox BackgroundImage Tile or resize image
Add a second image by the Image property
Label Image Need to manually resize image (by setting the
Height and Width properties) (set AutoSize
property to False first!)
Add text on the image
Set alignment of both image and text
Automatic link to an ImageList
Button Image Need to manually resize image
Always have a button border (add 8 pixels to
both width and height to the image).
Add text and also a background image
Set alignment of both image and text
Automatic link to an ImageList
Button BackgroundImage Tile or resize image
Add a second image by the Image property
Form BackgroundImage Tile or resize image
4.3 Resizing an image
It is best to display an image in its original resolution, so the image is not distorted in any
way. However, it is useful to know different ways to display an image:
Mode Meaning
Normal Display the image in its original resolution. (Same for None / Centre)
Tile Repeats the image to fill the entire area.
Stretch Resize the image to fill the entire area. The image can be distorted.
Zoom Resize the image to fill the entire area, without distorting the image.
Some of the area can therefore be blank.
17
4.4 Behaviour of controls when they are double clicked
Controls like PictureBox and Label generate a Click event in the first click, and then a
DoubleClick event in the second click. Other, like Button, generate two Click events in
these two clicks. The difference has some implications when you handle the Click event.*
If you do not need distinguish between plain click and double click, you should handle both
Click and DoubleClick events of a PictureBox or a Label in the same event procedure, like
the statement below:
Private Sub PictureBox1_Click(sender As System.Object, e As
System.EventArgs) Handles PictureBox1.Click, PictureBox1.DoubleClick
A simple way to add the event procedure is to double click the PictureBox / Label in the
design view, then add “, [controlname].DoubleClick” at the end of the
corresponding Sub statement.
Example 4.4.1 Handling the Click and DoubleClick events of PictureBox
Public Class Form1
Private Sub PictureBox1_Click(sender As System.Object, e As
System.EventArgs) Handles PictureBox1.Click, PictureBox1.DoubleClick
Label1.Text = 1
Label2.Text = Val(Label2.Text) + 1
End Sub
Private Sub PictureBox2_Click(sender As System.Object, e As
System.EventArgs) Handles PictureBox2.Click, PictureBox2.DoubleClick
Label1.Text = 2
Label2.Text = Val(Label2.Text) + 1
End Sub
End Class
You should also bear in mind that
PictureBox and Label generate Click and
DoubleClick events on both left and right
mouse clicks.
(It is not the scope of this chapter to differentiate different kinds of mouse clicks.)
* See http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doubleclick.aspx for details.
PictureBox1 PictureBox2
18
4.5 Using the resources of your project
You can utilize the resources of your project to store image for you picture boxes. Once
the image is imported into the resources, it can be used by all controls in both design view
and in runtime. To add images to the resources, just select “Project resource file” when
you change the Image property, and then press “Import”.
After you import images to the resources, you can rename or remove the images by
selecting “My Project” in Solution Explorer, and then select “Resources”, then “Images”.
The red exclamation mark next to the image indicates that the name of the resource is not
a valid identifier. Rename the resources to solve the problem.
19
You can load images from the resource file by setting the Image property of controls by
the following ways:
My.Resources.[resource_name]
My.Resources.ResourceManager.GetObject("[resource_name]")
The second method allows you to select an image based on the result of a string operation.
See the following example:
Example 4.5.1 Using resource file Public Class Form1
Private Sub Button1_Click(...) Handles
Button1.Click
' Method one
PictureBox1.Image = My.Resources.Dice1
End Sub
Private Sub Button2_Click(...) Handles Button2.Click
' Method two
PictureBox1.Image = My.Resources.ResourceManager.GetObject("Dice2")
End Sub
Private Sub Button3_Click(...) Handles Button3.Click
' Roll the dice and display the result (method two)
Dim i As Integer = Int(Rnd() * 6 + 1)
PictureBox1.Image = My.Resources.ResourceManager.GetObject("Dice" & i)
End Sub
Private Sub Form1_Load(...) Handles MyBase.Load
Randomize()
End Sub
End Class
20
4.6 Using an ImageList to store images
Beside the project resources, you can also add an ImageList control to use a list of related
images. However, the images must have the same size and the same bit depth.
After you add the ImageList, you
MUST set the properties of the
ImageList to match the images
you insert.
If you are not sure about the format of the image, you can simply import the image and
read the information from the dialog box. There is a number (in the screenshot below,
from 0 to 5) next to each image, and these are the indices of the image.
To load an image from an ImageList, set the Image property of a control to the following:
[ImageListName].Images([index])
21
However, to maximize the use of ImageList, you should set the ImageList property of
buttons or labels to your ImageList, and use the ImageIndex property of the buttons and
labels to select the image (or set ImageIndex to -1 to remove the image). See the following
example:
Example 4.6.1 Monopoly dice thrower with ImageList
Public Class Form1
Private Sub Form1_Load(...) Handles MyBase.Load
Randomize()
End Sub
Private Sub Button1_Click(...) Handles Button1.Click
Dim n1 As Integer = Int(Rnd() * 6) + 1
Dim n2 As Integer = Int(Rnd() * 6) + 1
Dim total As Integer = n1 + n2
LabelDie1.ImageIndex = n1 - 1
LabelDie2.ImageIndex = n2 - 1
LabelTotal.Text = total
End Sub
End Class
LabelDie1 LabelDie2 LabelTotal