Microsoft Corporation
Information in this document is subject to change without notice and <loes not represent a commitment
on the part of Microsoft Corporation. The software described in this document is furnished under a
license agreement or nondisclosure agreement. The software may be used or copied only in accordance
with the terms of the agreement. It is against the law to copy the software on any medium except as
specifically allowed in the license or nondisclosure agreement. 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 Microsoft
CofP-pration.
Except as otherwise noted, compariies, names, and data used in examples, sample output, and screen
shots are fictitious and are used solely to illustrate potential uses of this Microsoft product.
Microsoft, MS, MS-DOS , the Microsoft logo, PowerPoint, CodeYiew, and GW-BASIC are registered
trademarks and Microsoft QuickBasic, Visual Basic, and Windows are trademarks of Microsoft
Corporati on. OS/2 and Operating System/2 are reg istered trade marks and Presentation M anage r is a
trademark licensed to Microsoft Corporation .
IBM and PS/2 are registered trademarks of International Business Machines Corporation .
Microsoft documentation uses the term "OS/2" to refer to the OS/2 systems - Microsoft& Operating
System/2@(MS@OS/2@) and IBM@OS/2®. The term "DOS" refers to the Microsoft@MS -DOS@and
IBM@Personal Computer DOS operating systems. The name of a specific operating system is used
when it is necessary to note features that are uniqu e to that system .
ADDTASK.FR M
jButl o nH~w j! j P1oc: jc1,ck
• [xec ut ed t,h e never ""Hpw•· bu t ton is c li c ked
S ub Outto nHr1>1_ C J i ck ( )
Di fll l as k As l a s k l y p e. HeuHame As St d ng
HP"1Ha r.ie - 1 as k HaJne . r e x l
· S hot-J ano l1 1e 1· 1 o n 11
St- l ec t Ca s l' r 1· i o ri ty
Ca se H I Cll
H i Pt· i o,· i ' y - S h o,,,
Case ll[0 I Ul-1
1-IPdP d o t"i ty. Shou
Ca s r L Oll "'"'"''
•. ~· A• ,oon a s po u 1blc • l li!Jt,
t.
•
. ~
✓
Contents
Chapter 2 Setup 13
Befare You Run Setup 14
Running Setup 15
Starting Visual Bas ic 17
Setting Up Your Printer 18
Part 5 Appendixes
Appendix A Adapting Basic Code 391
Importing Bas ic Files 392
Program Structure 392
Scope of Variables 394
Event and Error Handling 395
Input and Output 395
Language Mec hanics 396
Unsupported Key word s 396
Keywords with Specifi c Differences 397
lndex 423
~ ~
Figures
Figure 1.1 The Vi sual Basic Interface 6
Figure 1.2 How objects respond to events 7
Figure 1.3 Sorne of the properti es of a text box, with corresponding settings 8
Figure 1.4 A sampling of applications you can create with Visual Basic 9
Figure 2.1 Quitting Setup 16
Figure 3.1 The Help Menu 20
Figure 3.2 The Main Menu 2 1
Figure 3.3 Buttons in T utorial lessons enable you to navigate or see where
you are. 22
Figure 3.4 The Opti ons Menu 22
Figure 4 .1 Using F l to get Help 25
Figure 4.2 Search Di alog Box 26
Figure 4.3 A jump in Help 27
Figure 4.4 Definiti on Window 27
Figure 4.5 Index in Using Windows Help 28
Figure 4.6 Click the jump to go to acode example. 29
Figure 4.7 The Forrn_Click procedure with LineDemo entered 30
Figure 4.8 An exarnple with code that goes in the global module 3 1
Figure 5.1 The Project Window 36
Figure 5.2 Text box and command button tools in the Toolbox 37
F igure 5.3 Text box and command button controls on a form 38
Fi gure 5.4 The Pro perti es Bar 38
Figure 5.5 The Properti es bar with Ct!Name property set to Readout 39
Figure 5.6 The Code window wi th code for the Readout text box 39
Figure 5.7 The Code window with the Click procedure di splayed, and with a li st
of other eve nts 4 1
Figure 5.8 The Code window with the completed HelloButton_Click
procedu re 42 ~
Figure 6.1 The Toolbox 48
Figure 6.2 The Completed ln vestm ent Calcul ator 49
Figure 6.3 Contro ls with default names 50
Figure 6.4 Text box too! selected in the Toolbox 50
Figure 6.S Draw ing th e text box S 1
Figure 6.6 The !abe! and co mmand button too ls in th e Toolbox 5 l
Figure 13.1 Samples from the Visual Basic Icon Library 164
Figure 13 .2 Icons MAIL16A.ICO and MAIL16B.ICO from the Icon Library 165
Figure 13.3 Left and Top properties 166
Figure 13.4 A button that moves when clicked 167
Figure 13.5 A control array of three command buttons 169
Figure 13.6 Scale running from (100,100) to (200,200f- 173
Figure 13 .7 Scale with negative ScaleHeight setting 173
Figure 13.8 Byte layout of color values 180
Figure 13 .9 A line drawn with the Line method 182
Figure 13.10 A spoked pattern 183
Figure 13 .11 Lines of varying width 184
Figure 13.12 Lines drawn with different settings of the DrawStyle property 185
Figure 13.13 Comparing the color value 187
Figure 13 .14 Filling a box with a salid pattern l 89
Figure 13 .15 Ellipses drawn with the Circle method 19 1
Figure 13.16 How angles are measured for a circle 192
Figure 13.17 Using the Circle method to draw ares 193
Figure 13.18 Using negative arguments to connect an are to its center 194
Figure 13.19 Effect of reversing arguments 194
Figure 14.1 Moving a control to the location of the mouse pointer 197
Figure 14.2 The Cli ck-A-Li ne application draws lines wi th the Line method 198
Figure 14.3 The Scribble Application 199
Figure 14.4 A demonstration of where MouseMove events occur 200
Figure 14.5 How bits represent the state of the mouse 202
Figure 14.6 How bits represent the state of the SHIFf, CTRL, and ALT keys 206
Figure 14.7 Dragging a control at run time 207
Figure 15.1 The Beatles Form 217
Figure 15.2 The GroupChoice form is a dialog box. 2 19
Figure 15.3 The Welcome form is th e startup form . 220
Figure 15.4 Visual Basic standard icon and the icon for the We lcome form 221
Figure 15 .5 The GroupChoice Form 223
Figure 16.1 Run-time errors such as "Type mismatch" halt executi on. 23 1
Figure 16.2 A procedure halted by a breakpoint 232 _
Figure 16.3 The Immediate W indow 236
Figure 16.4 Using a question mark to print to the Immediate window 236
Figure 18.1 Moving data to and from the Clipboard wi th SetText and GetText 265
Figure l 8.2 A timer control 268
Figure 18 .3 The Digi tal Clock Application 270
Fi gure 19. 1 Program flow with Resume and Resume Nex t 284
Figure 20. 1 The tool s for the file-system contro ls 296
Tables
Table 2.1 Command-Line Options 17
Table 9.1 Standard Variable Types 83
Table 9.2 Vi sual Basic Operators 98
Table 22.1 DDE Statements in Microsoft Excel, Word, and Visual Basic 372
Document Conventions
Note M icrosoft documentation uses the term "OS/2" to refer to the OS/2 systems -
Microsoft® Operating System/2~ (MS@OS-/2@) and IBM@OS/2@. The term "DOS " refers to
the M icrosoft® MS -DOS ~ and IBM@Personal Computer DOS operating sys tems. The name
of a spec ific operatin g sys tern is used when it is necessary to note features that are un.ique to
that syste rn .
• Variable names are lowercase with an initial capital letter. Variable names with more
than one syll able may contain other capital letters :
Gov As String * 30
PerCapincome As Double
• Line labels are used instead of line numbers. The use of line labels is restricted to error-
handling routines :
OpenError
If Err = 71 Then
Print Error$
Resume
Else
End
End If
• Control-flow blocks and statements in Sub and Function procedures are indented from
the enclosing code:
Sub Commandl_Click
If X > O Then
Textl.Text = " X is greater than O."
End If
End Sub
• As noted earlier, lines too long to fit on one line in this manual may be continued on the
next line using a line-continuation character ( • ).
Sub Form_MouseDown (Button As Integer , Shift As Integer , X As Single,
• Y As Single)
Welcome to the graphical user interface (GUI) revolution . If you want to create applications
for Microsoft Windows or OS/2 Presentation Manager, Visual Basic is the product for you.
Visual Basic is a development system especially geared toward creating graphical
applicati ons. It includes graphical design tools and a simplified, high-level language. It
emphas izes feedback and debugging tools that quickly take you from an idea to a running
applicati on.
.!--~~-
-- ----~---
--_..
Visual Bas ic is centered around two types of obj ects: You create windows, called forms, and
on those forms you draw other objects, called controls. Then yo u program how form s and
controls respond to user actions. The applicati ons you produce are fas t and can include all of
the most common features users expect in a GUI environment.
This chapter gives you an overview of Visual Basic and suggests th e best ways to use the
doc umentation set. The main sections in this chapter are:
• What You Should Know First
• Visual Basic and Its Environment
• Meeting the Challenge of Graphical Applicati ons
• What Can Yo u Create?
• The Visual Basic Documentation Set
• What to Do Next
•
4 Part 1 Getting Started
Note If you're experienced with Microsoft QuickBasic, you'll learn Visual Basic all the
faster. However, you can transfer QuickBasic code to Visual Basic only after making certain
changes. (In sorne cases, large amounts of code can be transferred almost directly, but user
interface code must be rewritten.) See Appendix A, "Adapting Basic Code."
The event-driven approach used by Visual Basic enables you to share computing time and
other resources (such as the Clipboard). An event-driven application consists of objects that
wait for a particular event to happen. (An event is an action recognized by a Visual Basic
object. Objects include forms and controls.)
Your Visual Basic code doesn ' t work in the linear fashion of a DOS program- starting at
the top, proceeding toward the bottom, and finally stopping. Instead, in event-driven
programming, you use code that remains idle until called upon to respond to specific user-
caused or system-caused events.
For example, you might program a command button to respond to a mouse click. When the
command button recognizes that the event has occurred, it invokes the code you wrote for
that event.
While your application is waiting for an event, it remains in the environment (unless the use ,
closes the application). In the meantime, the user can run other applications, resize window s
or customize system settings such as color. But your code is always present, ready to be
activated when the user retums to your application.
Features Supported
Visual Basic enables you to take fu]] advantage of~raphical environments and operating
systems. With it you can create:
• A fu]] set of the objects you need to create Windows applications, including: command
buttons, option buttons, check boxes, list boxes, combo boxes, text boxes, scroll bars,
frames, file and directory selection boxes, and menu bars .
• Multiple windows in an application.
In addition, Visual Basic adds a number of specific programming features, which you'll
leam more about later in this manual :
• Graphics statements.
• A powerful math an d string-handling library.
• Easy-to-use string variables .
• Both fixed arrays and dynamic arrays. (The latter help to simplify memory-management
problems .)
• Random-access and sequential file support.
• Sophisticated run -time error handling.
~
Visual Basic also makes development easier by providing a set of powerful debugging
commands that help you isolate and correct errors in your code. Visual Basic operates as an
interpreter, instantly translatin g your statements into "runnable" form as soon as you type
them. But once you 've completed your app lication , you can convert it into an executable file
that is relatively small and fast and can run outside the Visual Basic environment.
The Visual Basic package also includes an Icon Library. The library consists of icons that
you can use to add visual appeal and functionality to your applications .
Figure 1.1 shows th e Vi sual Basic interface. You ' ll leam more about the various parts of the
interface in Chapter 5, "Overview of Visual Basic Development."
...
=I Fo rml 1· 1·11
~ ~ ..
A [M 3llllmllllE
oo =I Fo rm1
1 View Form 11
¡i¡¡j Global.has
Vi ew Code
Global
1
~ ® Object: lro,m 1~ Proc: j Click •-~ ·"'•""'
~. ~. Sub Fonn_ Cli c k ()
~ fil 1
End Sub
o El
EJ ~
t.11
+I 1 l +I 11
The name itself establishes the association between the procedure and the event. When your
application is running, Visual Basic automatically invokes the appropriate procedure each
time an event occurs.
Here's how a Visual Basic application works :
1. An action is recognized as an event by sorne form or control. The action can be caused
by the user (such as a mouse click or keystroke) or by the environment (such as a timer
event) .
2. If there is a corresponding event procedure, it gets executed.
3. The application waits for the next event.
Figure 1.2 demonstrates how objects in Visual Basic respond to events. For example, when
the user clicks the command button named Commandl , the command button recognizes thi s
action as the Click event. Visual Basic then executes the Commandl_Click procedure, if it
exists.
The procedures you write to respond to events can perform calculations, get input, and
manipulate parts of the interface. In Visual Bas ic, you manipulate objects by changing the
values of properties.
Figure 1.3 Sorne of the properties of a text box, with corresponding settings
Each property has a name and a setting. The setting is the value of the property ; for instance,
the setting of the Bac kColor property could be white. You can change the settin g of most
properties whi le yo u are building an application, and with code when the application is run.
Much of the magic of Visual Basic stems from the fact that when you change the value of a
property, Visual Basic responds ri ght away, doing whatever is necessary to graphicall y
reflect the change . For exa mple, changing the value of the Height property causes Visual
Basic to immediately resize th e object.
Visual Basic supports the majority of statements and function s supported in other versions of
Basic. It also adds sorne new capabilities in the form of methods. A method is a Visual Bas ic
keyword that is similar to a function or statement, but which always acts on a particular
object. For each object, Visual Basic predefines a set of methods you can use.
la Cardfile - (untitled) DD
Eile .!;_dit '{iew ~ard .S.earch !::!elp •
Card View • • 1 Card
[j]•
Spanish Rice
M o use B uttons
• •
Lelt Righl
~=¡==¡=¡==¡===¡==¡==='j ®
Cha pters 3 and 4 give more complete descriptions of the Tutori al and H elp.
T he fo ur parts of the doc umentati on se t are designed to complement one anoth er. To help
yo u qu ickl y find infor mati on in Help and the T utorí a!, thi s manu al includes a number of
cross- references . In the fo ll ow ing chapters, m ost of the cross-references are marked with
these icons:
T he Help ico n represents the Fl key. You can press that key while running Vi sual B asic to
go to Help . T he word o n the second lin e is call ed a keyword. ("Keyword" in thi s case m eans
a search term ; lang uage keywords incJude fun ction s, state ments, operators, and method s.)
The text next to the Tutorial icon refers you to a specific lesson. To start the Tutori al, choosc
Tutorial from the Help menu in Visual Basic.
The index for this manual also includes cross-references to the Tutorial and to Help .
In addition to the documentation , the V isual Basic package comes with a set of sampl e
applications that you can load into Vi sual Basic . These ·applications are useful in the mselves.
but are also excellent leaming tool s. You can copy "1!Y part of them into your own
applications, modifying them as you need to.
What to Do Next
This chapter has introduced you to sorne ge neral Visual Basic concepts. To really get th e
feel of the product, you' ll need to build and run sorne applications .
lmportant If you have the product installed airead y and are anxious to build an application , turn to
Chapter 5, "Overv iew of Visual Basic Development," which leads yo u through a simple
application.
Alternatively, if you are fami liar with event-driven programming and with the Windows or
Presentation Manager environment, you might try a faster track:
1. After working through Chapter 5, start exploring Visual Basic, referring to Help or the
Language Reference when you need to.
2. Skim through the rest of Part 2, paying particularly close attention to Chapter 8,
"f.,.ttaching Code."
3. Read Part 3 to learn the most frequently used coding techniques.
4. Use the Tutorial for lessons on selected topics.
This chapter explains how to install Visual Basic on_your computer using the program
SETUP.EXE. Toe Setup program (which was writte1i in Visual Basic) creates new
directories and copies a number of files - Visual Basic itself, the Help system, the Tutoría! ,
sample applications, and the Icon Library - from the distribution disks to your hard disk.
lmportant You cannot simply copy files from the distribution disks to your hard disk and run Visual
Basic. You must use the Setup program to decompress and install the files.
If any pieces are missing, contact the retailer from whom you bought Visual Basic.
Running Setup
When you run the Setup program (SETUP.EXE) to install Visual Basic on your computer,
you'll set a path for Visual Basic and then select which of the Visual Basic files you want to
install .
You can start Setup from Windows or Presentation Manager, or from DOS .
Ouitting Setup
To quit Setup , click the Exit button in the lower right of the Setup screen, as shown in
Figure 2.1. This di splays a Yes/No message. Choosing Yes quits Setup; choosing No cancel s
your req uest to quit and retums you to the Setup program.
Name :
Continue 1 Exit
The online Tutorial gives you a quick understandin~of how Visual Basic works. It shows
yo u the Visual Basic interface and demonstrates techniques you'll use in building
app lications. One of the best ways to learn Visual Basic is to run the Tutorial first and the n
read this manual.
You run the Tutoría! from within Visual Basic, so it's easy to retum to it when you want to
learn more. You don ' t need to finish all of the lessons befare you start using Visual Basic.
lf you want to run the Tutorial right away, choose Tutorial from the Help menu. To learn
more about the Tutorial befare you run it, read thi s chapter. The section s in this chapter are :
• What's in the Tutorial
• Using the Tutoría!
••
20 Part 1 Getting Starte d
tlbout...
T he first scree n is the Menu , as shown in Figure 3.2. This is where you choose the lesson
yo u want to see. Noti ce th e buttons at the bottom of the scree n: Exi t and Instructions. To qui 1
the Tutoría! , click Ex it. To see in structions on how to use the Tutoría! , click Instructions.
Cl
Select a lesson o r c hoose ins huclions:
Exil 1 1
lns huc tions 1
Each lesso n in the Tutorial includes severa! topics. Move through a topic by clicking the
Nex t button , or by pressing the SPACEBAR. To find out where yo u are in the lesson, click th e
icon in th e upper left of the screen, as shown in Figure 3.3 on the next page. The Tutoría!
d isplays a map th at shows you where you are in relation to other topics in the lesson.
IIJ
Popula tion
cameroon
l 10.800.000
I
GNP S12.600.000.000
lncome pe , Capita ~I$_1_.1_67_ _ _ _~
Options Nexl
Click Options to display the Options menu , as shown in Figure 3.4. Use the buttons on the
Options menu to move around within the Tutori al, orto retum to Visual Basic. You also can
get instructions on how to proceed durin g a lesson, or see a sllmmary of the current lesson.
Options
Because it is an integral part of Visual Basic, online He!f> is installed automatically when
you run Setup. Help is the primary reference for the Visual Basic interface and one of two
prime sources of information on the Visual Basic language (the other being the Language
Reference manual). lt gives you instant reference information about properties, events, and
error messages, plus step-by-step instructions for each phase of building an application. Help
also includes reference on advanced tapies such as debugging and dynamic data exchange.
lt' s easy to keep Help handy as you work with Visual Basic, because you can move the Help
window where you want it and change its size to what suits you best.
For detailed information on Help, choose Using Help from the Help menu in Visual Basic,
or run the "Using Help" tapie in the first lesson of the Tutoría!.
The main sections in this chapter are:
• What's in Help
• Getting Help
• Learning to Use Help
• Running Code Examples from Help
24 Part 1 Getting Started
What' s in Help
Online Help is a comprchensive reference for nearly all aspects of Visual Basic. The
followin g table Ii sts the majar parts of Help. To start or switch to Help from Visual Basic,
press FI or choose Index from the Help menu, then choose one of the index entries.
Fo~_Help on From the Help index, choose
Essential steps in building an application Creating An Application
Visual Basic windows and tools Visual Basic Interface
Visual Basic menu commands and dialog Commands
box options
Conunon tasks in Visual Basic HowTo ...
Objects, properties, events, and methods Properties, Events & Methods
The Visual Basic programming language Programming Language
Useful key comb in ations Keyboard Guide
Using icons to enhance your applications Icon Library
There also is a part of Help called "Using Windows Help" that explains how to use Help
itself. For more information , see " Leaming to Use Help" later in this chapter.
Getting Help
In addition to using the index , there are four other ways to reach specific information in
Help .
When you're in Visual Basic:
• Selecta context-sensitive element of Visual Basic and press FI .
., .,
[Exit Sub]
,,..,, •
•
=I Form
~
!ndex
1 \;,
¡}.':C.{.(
1 s,~,. 1 "~!,. 1 s~
~
11:
A @fil
Toolb ox
The Toolbox conto.ins a set of tools lhatyou
-
•
oo
---
can use to draw. move. or resize .GQfl.\r_o_l~ on
, Textl your fRrrn-You can choose thetoolyouwant
-~181 @ to use by clicking it.
-o El
[!El
•
-g -
To el ose the T oolbox, ch o ose the aose
....,,
~
= ; 1• ¡ . ,a- ' : · I·
Eil e f dit Bo okma rk !:le lp
...at an error
~
jndex 1 ·~ - I ,~\. 1 !!"' 1 Se~
message Out of memory •
1-
Error 7
=I Mi crosoft Vis
CD Ou t o f m e m o r .
More memor-¡ wa!> reqwred 1hon 1s evo.110.ble
Close ony opphc0.t1ons. docum ents. ar
source files the1a,e 1n memo,y but not
needed
E ..
• Cons,d e, break.mg the program mto multrple
.,modules
...
.,.,,
Press Fl from any context-sensitive part of Visual Basic to display information about that
part. The context-sensitive parts are:
• Words that are part of the Visual Basic language (statements, functions, properties,
methods, events, and so on)
• Error messages
• Every window in Visual Basic (Properties bar, Code window, dialog boxes, and so on)
Inside Help itself, you can press Fl to display the index to the Using Windows Help topics.
Searching Help
The quickest way to find a particular topic in Help is to use the Search command. Y ou can
use either the mouse or the keyboard to initiate the search; the latter is probably faster.
To search Help:
1 In the Help window, press ALT +S or just S to display the Search dialog box .
Help displays the Search dialog box, as shown in Figure 4.2.
Search
.S.earch For:
lri.m
•
absolute
access
access keys
access prope rties
activate
No T opics Found
2 Type the first letter of the word or phrase you're looking for.
-or-
Select a word or phrase from the list of keywords.
When you type a letter in the Search For box, the selection in the list shifts to the first
keyword that starts with that letter. If several keywords start with the same letter, you can
type additional letters to move the selection to the keyword you want.
Jumps ....
The topics in Help are linked by jumps. Jumps are easy to spot because they are underlined
(and green on color monitors) , as shown in Figure 4.3. To see the topic related to ajump,
click the jump (or press TAB until the jump is highlighted, then press ENTER). Togo back to
the previous topic, click the Back button in the Help window, or press ALT+B (or just B).
lliJ .,\ ,: ••
!ndex i::r,·;:A $ ' ~ BrQwse
M~1oft
Definitions
Sorne of the words and phrases in Help are marked with a dotted underline (and are green on
color monitors). Help provides definition s for these terms. To see the definition , click the
underlined word or phrase and hold the mouse button down, as shown in Figure 4.4. Help
displays a definition window until you release the mouse.
The Using Windows Help topics include complete information on Help basics, buttons,
commands, keys, and procedures, including navigating and searching. Figure 4.5 shows the
Using Windows Help index topic. When you use the Search command while in Using
Windows Help, the search does not include topics about Visual Basic - only information
about usi ng Help .
...._
Ei_le_ ~d~it_B_o_o_km._ar_k_t!~e_lP_ _~_
f; ___,. }- Help commands
1
,_.1....
~ _,ex__.'-__ _•._e ______,,_,. }- Help buttons
,tw
_,._,:_:.::_, ••_. .._B__
....._,. ____
lnd ex t o Usíng Help
11 you are new to Wmdows Help. choos e Help
Bas, cs
Usin g Help To pi cs
Help Bas,cs
Help Button s
Help Cornrnands
Help Kevs
Help Pro cedures
To choo s e a Help t opic:
~ •
4 Choose Copy from the Edit menu in Help to copy the entire example, or press CTRL+INS .
5 Exit or minimize Help.
6 Double-click the form to show the Code window.
7 In the Object box, select "(general)."
8 Choose Paste from the Edit menu to paste the example into the Code window, or press
S HI FT+ INS,
Note that the name of the procedure -LineDemo --,-fo!Jows the word "Sub."
3 Press CTRL+BREAK and click the Immedi ate window to bring it forward .
4 Type the name of the procedure, "LineDemo,"' in th e lmmediate window and press
ENTER .
To run the demo again , place the cursor aft er th e word LineDemo and press ENTER .
5 When you ' re finished , choose End from th e Run menu .
There are a few language topics whose exampl es mu st be divided between form code and
the global module. Those examples are clearl y marked by comments in the first few lines of
the example, as shown in Figure 4.8 . The procedure followin g the illustration describes how
to copy and run such a piece of code (in thi s case , th e example for the Global statement).
--
[ile ];_dit Bookmark tlelp
~ ••::-. ~H
lnde• Back
'Global Statement Example
Global TestArray() As Integer Put these two lines
Global Size As Integer global module .
Cut these lines
and paste into
Sub Globa lDemo global module.
Size = Int(lOO * Rnd + 1 ) Generate random s1ze
ReD1m TestArray (S ize ) Define how many elements .
For 1% = 1 to Size Index for number o f elements
TestArray(I %) = 1% Put number in each element .
~
Figure 4.8 An example with code that goes in the global modu le
Microsoft Vi sual Bas ic simplifies programm in g fo r the Microsoft Windows and Prese ntati on
Manager environments. With Vi sual Basic . yo u create th e entire use r interface for your
~- appli cati on without writing any code . Thcn. to make th e interface fun ctional , yo u attach code
th at responds when th e user clicks a button or oth erwi se interacts with the interface.
Thi s chapter explain s th e Vi sual Bas ic rnoJel by showing yo u how to create a simpl e
app licati on. lt then prov ides detai ls on \\'Orki ng with Visual Basic ril es. in cludin g how to
save yo ur work.
The main secti ons in thi s chap ter are:
• Your First App licati on
• Worki ng with Proj ec ts
• Sav ing Your Work
t .
36 Part 2 Visual Basic Essentials
For more information on projects, see the next section, "Working with Projects."
Much of the work you do with Visual Basic involves customizing forms and co ntrol s.
Because they are built into Visual Basic, you don't have to do any programming to display
them on the screen. You simply draw them to create your application' s user interface.
Drawing controls is much like drawing an object in a graphics program such as Windows
Paintbrush. To draw a text box for the "Hello, world!" application , cli ck the tex t box too! in
the Toolbox, shown in Figure 5.2. (The Toolbox is a set of tools you use at design time to
place con trol s on a form.) Then móve the pointer to the form and d1:ag to draw a text box .
Repeat the process for the command button .
.
~ fM
-
A @fil Text box too/
~
o -o - -
Command button too/
Figure 5.2 Text box and command button tools in the Toolbox
The result is a form w ith two controls, as shown in Figure 5.3. Each of these items - the
form and eac h con trol - is considered an object by Visual Basic code.
la Formt aa
1 >:: ::: ...
Visual Basic g ives th e tex t box th e defau lt name Textl and the comm and button th e defa ult
name Command 1. but it 's helpful to use more meaningful names so you ca n eas il y refer to
them in code. In this exam pl e, we ' II use the names Readout and HelloButton .
Click the text box once, then look to see whether the CtlName property is selected in the
Properties list box at the left of the Properties bar. (If it 's not selec ted, click the a1rnw at the
right of the list box and select Ct!Name.) Then type Readout. As you type, the text appears
in the Settings box in the rniddle of the Properties bar, as shown in Figure 5.5 .
Figure 5.5 The Properties bar with CtlName property set to Readout
Now click the command button and type HelloButton, then press ENTER. You've just
assigned new values to the CtlName property for each control.
Although the words you typed appeared in the Properties bar, you didn't see any change in
the text on the controls themselves. That's because Readout and HelloButto_n are control
names that appear only in code. The way to tell that a con trol name has changed is by
opening the Code window and looking at the code for the control. The Code window is
where you write, display, and edit Visual Basic code. You can open a Code window for each
form and module in your project. Double-click th e Readout text box to see what code is
attached, as shown in Figure 5.6.
O bject: i
R eadout
+ . •
You ' ll return to the Code window when you start addin g code. For now, close it or minimize
it, and continue setting properties.
The CtlName property settings for the text box and co mm and putton don ' t affect what the
user sees, but the Text and Caption property settin gs do ._The Text property for the text box
specifies the contents of the text box, and the Caption pr'ciperty for th e command button
specifies the text displayed on the button.
Note When you create a text box , Visual Basic initiall y sets th e Ct!Name property and the
Text property to the same default value ..:_ in thi s case, Text 1.
For the "Helio, world! " application, you want the text box to start off empty. You do that by
setting its Text property toan empty string.
Now, you change the caption displayed on the HelloButton command button .
With the interface for the "Hello, world!" application complete, you ' re ready to add the code
th at tell s the command button how to respond to a mouse click at run tim e.
End Sub
•
+ +
Figure 5.7 The Code window with the Click procedure displayed, and with a list ot other events
The Procedure box lists al i of the events recognized by the current object (i n this case, the
command button). When you select Click in the Procedure box, Visual Basic displays acode
template for the event procedure HelloButton_Click. Acode template includes the first and
last lines of an event procedure.
An event procedure is the code that is invoked when a form or control recognizes that a
particular event has occurred. Visual Basic knows which procedure to invoke because the
name of the procedure includes the names of both the object and the event, joined by an
underscore, like thi s:
objectname_eventname
The objectname is the same as the value of the Ct!Name property. The eventname must be
on the li st of events that Visual Basic defines for the object. Because the naming convention
establishes a link between the object and the code, event procedures are said to be attached
to forms and controls.
The. text box in the "Helio, world!" application is named Readout, and the Text property
determines what it displays. Therefore, the line of code that prints "Hello, world !" is :
Readout.Text = "Hello, world!"
Enter that line between the Sub and End Sub statements in the HelloButton_Click
procedure. Figure 5.8 shows what the completed procedure should look like, and it also
points out what each part of the procedure does.
• •
.
Name after the period determines what property to change.
Name befare the period determines what object to act on.
Figure 5.8 The Code window with the completed HelloButton_Click procedure
Now yo u can press F5 to run the application. To make sure the code works, click th e
command button; the words "Heli o, world !" should be displayed in the text box . Choose
End from the Run rnenu to retum to design tim e.
To create a variation, you can add a statement that causes the command button to display the
text , "You clicked me!" Although yo u use the Text property to specify what is displayed in
text boxes, you use the Caption property to specify what appears on buttons . The event
proced ure with the add itional line of code should look like this:
Sub HelloButton _ Click ()
Readout.Text = "H ello, world!"
HelloButton.Caption = "You clicked me!"
End Sub
You ' ve now drawn control s, set properties, and written code to create a simple application in
Visual Basic. The las t secti on in thi s chapter, "Saving Your Work," explains how to save what
yo u' ve done.
For more information on the steps in building an application, see Chapter 6 , "Drawing t:1e
Interface," Chapter 7 , " Settin g Properties," and Chapter 8, "Attaching Code," or:
You tested the "Helio, world !" application by running it inside Visual Basic. You also can
co nvert an application to an executable file so that it can run outside Visual Basic. For more
information, see Chapter 8, or:
For a co mplete di scuss ion of modul es and the global module, see Chapter 17 , "Advanced
Language Features ."
Note 1f you delete or rename a fil e from inside Vi sual Basic using the Remove File or Save
File As commands on the File menu , the project fi le is updated to reflect those changes the
nex t time the project is saved. However, if yo u rename or delete a file outside of Vi sual
Basic and then open the project, Vi sual Basic display s an error message to warn you th at a
file is mi ssin g. To add a new or renamed file into a project, open the project and choo se the
Add Fil e command from the File menu .
Note The Save File As comrnand saves the file, and any changes made since the last save,
unde r a new name that you specify. The old version of the file, without a ny of the changes
made since the last time you saved, is retained also. However, only the newly named file
remains associated with the project. You can add the old version back into the project by
using the Add File command from the File menu.
The fi rst step in creating an appli cation with Visual Basic is to dra w the user interface: th e
command buttons. tcxt boxes , and oth er objects the user will see and use. You th en set
propert ies and write Vi sua l Basi c code to make the interface ac ti ve.
Thi s chapter ex plain s how to draw the interface for an application th at calcul ates th e re turn
on an investment. Chapter 7, ··Setting Properties," and Chapter 8, "Attaching Code,"' use thc
same examp le. lf yo u work at your computer as yo u read throu gh the next three chap ters,
you' ll end up with a rully func ti onal investment calculator.
The main sectiom, in thi'.:. chapter are:
• Drawin g Controls
• Resizing. Mo\'ing . and Deleting Control s
• Saving the In vestmcnt Calcul ator
11
.---·:...
'-...~ •-t:•:-.
. ··... ··.......
··:::..
..
··-.:·-.. ·-==·
··-.:~
..·-·:.
'··{ : ~· :--,......
· . ·. 0··
··..:· --#
- ·-
Part 2 Visual Basic Essentials
Drawing Controls
Chapter 5, "Overview of Visual Basic Development," explained that you draw controls on
forms to create the interface for your application. This chapter provides more detai ls on
drawing controls and how to move and resize them once they're drawn. Although each type
of control is different, you use the same process to draw al i co ntrol s.
The Toolbox
The center of the drawing process is the Toolbox, which you can position anywhere on the
screen. It contains one tool for each control, plus a pointer to manipulate controls after
they ' re drawn. You use the tools to draw controls on a form muchas you would use tools in
a graphics program to draw lines and shapes.
The Toolbox opens automatically when you start Visual Basic. If it has been closed, you can
open it again by choosing Toolbox from the Window men u. Figure 6.1 shows the Toolbox
with its tools labelled .
.
Pointer - ~ ~ - Picture box
Label - A ~ - Text box
Frame - oo - Command button
Check box - [8J @ - Option button
Combo box - ~. gJ - List box
Horizontal sera// bar - 8!] ~ - Vertical sera// bar
Timer - o
. El - Orive list box
Directory list box - o ~ - File list box
This chapter describes only the controls used to build th e In ves tmcnt Calc ulator in the nex t
section . For information on ali Visual Basic controls, see the individuaJ entri es on controls in
the Language Reference, or:
1
Duration in Y ear s .
1 ____ _ __,
1 5 13
Ending Balance . _º _- _ _
l ___ __J
As yo u can see, the lnvestment Calculator uses three types of controls: labels, text boxes,
and a command button. A label displays text th at cannot be directly changed by the user. A
text box provides a place to display or enter text, and a command button is a control that can
be programmed to carry out a command or ac tion when the user clicks it. (Sorne other
products refer to command buttons as "push buttons," and to text boxes as "edit fi elds.")
The first three text boxes accept input for th e startin g balance, interest, and duration of the
in ves tm ent. The command button starts the computation and displays the result in the fourth
tex t box. The labels show the user wh at each text box contains.
1m Forml aa
: : Labell IText1
: : : Label2
~ITe-xt2- ~I
Labe13 1 Tesl3
Command1
Label4 IText4
3 Move the pointer onto your form . The pointer becomes a cross hair, as shown in
Figure 6.5.
a
~ ~
mi Forml aa
A ~
oo 1 ¡:.::
··· ~ - - - -
. +. :::
181 ®
~. ~.
[fil)
fil
o El
cJ ~
4 Place the cross hair where you want the upper-left comer of the control.
5 Drag the cross hair until the control is the size you want.
6 Release the mouse button. The text box appears on the form .
To complete the interface, draw three more text boxes, four labels, and a command button .
You can draw them using the steps above, or use the shortcut described in the next section .
Figure 6.6 shows where the label and command button tool s are located in the Toolbox .
After drawing the controls, arrange them as shown in Figure 6.3 .
.
~ ~
r:--;
A = La bel too!
For information on how to manipulate co ntrol s, see "Resizin g, Moving, and Deleting
Controls" later in thi s chapter, or:
A Shortcut
If you follow the steps in the procedure above for drawing a text box , you can select, place,
and size each control in turn. However, if you have a lot of controls to draw, you may find it
fas ter to crea te all of the controls first , and then arrange them on the form. Y ou can crea te a
default-size control, without drawing it, by doubl e-clickirig the appropriate too! in the
Toolbox .
You can create ali of the controls you need for the Investment Calculator by double -clicking
the appropriate tool s in the Toolbox , and then moving the controls until they are arranged as
show n in Fig ure 6.3. You can resize controls as ex plained in the next section , but you'll
act ually save time if you wait to resize the co nt ro ls until after you've set the captions. That
way you ca n be sure that the captions fit in the control. Setting captions is explained in
C hapter 7, "Setting Properties."
To resize a control:
1 Click the control to select it.
The control is outlined with small black rectangles called sizing handles, as shown in
Figure 6.7.
mi Forml aa
...
I Text1 1- • _ Text2~
'1---i ~~~- [
2 To size the heigh t and width of the control at the same time, drag one of the com er sizing
handles.
To size the control in one direction only , draga sizing handl e on one of its sides.
3 Release the mouse button to redraw the control to the new size .
To cancel the selec ti on, cli ck an em pty part of the form .
To move a control:
• Posi tion the pointer anywhere inside the border of the control and drag it to the new
location on the form .
You can move a control that ' s already selec ted, but be careful not to drag one of the sizing
handles. When you re lease the mouse button after moving a control , the sizing handles will
be di splayed (even if they weren't before the move) .
mi Forml aa
•.. CTextl :
1 Multiple-selected controls
Figure 6.8 Multiple-selected controls are outl ined with gray sizing handles.
To delete a control:
1 Click the contro l to select it.
2 Press the DEL key .
- or-
From the Edit menu , choose Delete.
The grid is there to make it easier for you to line up controls. If you want to move controls
by increments smaller th an the grid allows, choose Grid Settings from the Edit menu and
tum off the Ali gn to Grid option. When you tum the grid back on, you can use the Align to
Grid command on the Edit menu to line up selected controls on the grid. You also can
change the increments for the grid by typing in new Spacing se ttin gs in the Grid Settings
dialog box.
For more information on using the grid:
For more information on saving your work, see Chapter 5 , " Overview of Visual Basic
Development," or:
Chapter 6, "Drawing the Interface," took you through the first steps in building an
application. Working with a bl ank fo rm as the framework , you drew co ntrol s and set their
size and locati on to make a "rough draft" of yo ur application' s interface. Now yo u can refine
the interface by fine-tuning the appearance and behavior of the control s.
You accompli sh thi s fine-tuning by settin g properties. For exampl e, you ca n add a border to
a label control by setting its BorderSty le prope rty to 1. Or, you can set the MultiLine
property for a text box to True so it ca n acco mm odate multiple lines of tex t.
Thi s chapter explain s how to set properti es at desig n time usin g th e Properti e bar. It
continues the creation of the ln vestm ent Calcu lator described in C hapter 6 by show ing yo u
how to set properties for the objects th at mak e up that app li catio n. The main secti ons in thi s
chapter are:
• The Role of Properti es in Vi sual Bas ic
• U ing .the Properties Bar
• Setti ng Properties for the In vestment Ca lcu lator
• Other Ways to Se t Prope rtie ~
X X >
58 Part 2 Visual Basic Es se ntials
Cursor
Default
Draglcon
DragMode
Enabled
FontBold
Fontltalic
FontName •
4 To confirm the setting you've typed, press ENTER, or click the Enter button (the one with
a check mark).
To cancel the new setting, press ESC, or click the Cancel button (the one with an X) .
The Properties li st box at the left of the Properties bar lists all of the properties you can se t
for the selected object at design time. (Sorne properties can be set only at run time .) The
Properties list box always di splays one property for the selected object, and you can cli ck the
arrow at the right of the li st box to scroll through a list of other properties for that object.
You then can click one of the properties to select it and to display its setting in the Settings
box at the middle of the Properties bar. The boxes at the right of the Properties bar display
the position and size of the selected object, both when it's in one place and while you move
or resize it.
Visual Basic makes it easy to change a property setting: You just select an object, select a
property, and type to change the setting. You don't have to select the setting in the Settings
box - you just type to rep lace it. _
Hint A quick way to find a property is to click the arrow in the Properties list box and then
press the first letter of the property name. The selection shifts to the first property th at starts
with that letter. Press the letter again to move to other words that begin with the same letter,
or use the arrow keys. Press ENTER and then type ro edit the property setting.
Sorne properties have a fixed list of se tting . For instance, the Visible prope11y , w hi ch
determ ines whether the user can see a form or control , mu st be either True or False. Rath er
th an typ ing new settings for such properti es, you click the arrow at the right of the Settings
box and choose from a list, as shown in Figure 7 .2.
FALSE
Hint There's another way to chan ge se ttin gs for properties with a fixed number of settin gs:
Fo ll ow Steps I and 2 in the procedure above. then press the first letter of the settin g (such as
" F" for False), and press ENTER
Vi sual Basic also provides key combina ti ons yo u can use to see and set properti es in the
Properti es bar. For more informat ion :
A Shortcut
Sorne of the app li cati ons yo u create with Visual Basic may require you to set a number of
properties for eac h of your controls. One way to do that is to set ali of the necessary
properti es for one control, then set them for the next control, and so on. However, that wi ll
mean repeated ly se lecting properties for each control. _
You can avo id th at by tak ing advantage of a handy fe ature: Once yo u selecta property, the
Properties bar co ntinues to di splay th at property for each object you select. That means you
can set one property-such as Caption-for each control to which it applies without having
to reselect the property in the Properties bar. You simp ly select the nex t control and type a
new settin g. Jf you se lec t an object to whi ch a property does n' t app ly, the Properties bar
di splays the default or most commonl y used property for th e selec ted object.
. : . Labe l4 : ITe•t4 1
E nding Balance
Figure 7.3 The lnvestment Calculator befare and after properties are set
As mentioned earl ier, you often don ' t need to c hange th e default se tting for a property . The
following table lists the properties you do need to set for eac h co ntrol in the ln vestm ent
Calculator. The first column lists the default name th at Visual Basic assigned to each object
when you created it. The other columns list the settin gs for eac h property. Further
explanation follows the table.
In Chapter 8, "Attaching Code," you ' II finish the lnvestment Calculator by attaching code
to the command button.
Default name Caption CtlName Text
Forml lnvestment
Calculator
Textl StartTexi (blank)
Text2 RateText (blank)
Text3 YearsText (blank)
Text4 EndText (blank)
Labell Starting Balance
Label2 Interest Rate in %
Label3 Duration in Y ears
Label4 Ending Balance
Commandl Compute Ending CalcCmd
Balance
The Form
The Caption property places a caption in the form's title bar.
The Labels
Labels have a Caption property that determines what text they display. When a label is
created, its Ct!Name property and Caption property are the same. It doesn 't matter whether
the default names for your labels match the default names in the table, as long as the
captions match the ones shown in Figure 7.3.
Although most properties can be set from code, only a few can be se t directly by the user.
For more information about setting properties from code, see Chapter 8, " Attaching Code."
¡fj
1 2295 X ~95
Width x He,ght
Figure 7.4 Property settings for size and position
Once yo u' ve finished creating an application ' s interface, yo u' re ready to attach code to the
objects in the interface to make them respond to events. ::You write that code in the Code
window.
This chapter explains the various features of the Code window, and reviews the structure of
the event procedures you write there. It also describes the event procedure that completes the
Investment Calculator you've been building in the previous two chapters. After you finish
this chapter, yo u should have a fully functional calculator - and you' 11 understand how it
works .
Details on programming in Visual Basic are provided in Part 3 of this book.
The main sections in thi s chapter are:
• When Do You Need Code?
• Writing Event Procedures
• How the Code Works
• Creating an Executable File
.....--
-
66 Part 2 Visual Basic Essentials
lnterest Rate in Z
5
~1___ ~
1 5 13
Ending Balance _º _- _ _ ~
~1
To make the applicati o n work as described , you don ' t need to write an input statement to
allow the user to enter numbers in the first three text boxes. Text boxes have a built-in
capabilit y of accepting text. Nor do yo u need to program the fourth text box to be able to
di splay text - that functionality is a lso built in . However, you do need to write code to do
four things in thi s application :
• Ret ri eve th e text that the user types in the text boxes
• Convert th at text to nurnbers that can be used in a calculation
• Calculate the ending balance
• Format th e endi ng balance and display it in the Ending Balance text box
Because ali of these tasks are rela~ed to co mputin g and di splaying the ending balance, the
code can go into a single event procedure. And because you want the final calculation to
take place when the user clicks the command button, you'll attach the event procedure to
that button . Ali event procedures follow the same general format, as explained next.
Note Although you can write event procedures from scratch, it's better to use the code
templ ates provided by Visual Bas ic, which automatic ally include the correct procedure
name. (The next section, "Using the Code Window," tells you more about templates .)
All event procedures use the same general sy ntax, as shown in the followin g table.
Syntax for control events Syntax for form events
Sub controlname_eventname () Sub Form_eventname ()
statementblock statementblock
End Sub End Sub
The words Sub and End Submark the beginning and end of the procedure. The words
followin g Sub are the procedure's name, and statementblock is the code you want exec uted
when the event occurs. For exampl e, the following procedure is invoked when the user
clicks the control named Command 1:
Sub Co mm and l _Click ()
Commandl.Height = Commandl.Height + 100 -
Commandl . Wid t h = Commandl.Width + 100
End Sub
lmportant If you change the name of a control after attaching a procedure to it, yo u also mu st change
th e name of the procedure, to match the new nam e of the co ntrol. Otherwise, Visual Basic
won' t be able to match the control to the proced ure. When a procedure name does not match
a co ntro l name, it becomes a general procedure: In the Code window, select "(general)"
from the Object box, then select the procedure name from th e Procedure box .
Vi sual Basic recognizes numerous events, each of whi c h has a particular use . For
ex planations of ali events, see the Language Reference, or:
The Code window has three primary parts: two drop-down list boxes and an editing area.
The Object box , on the left, lists "general ," the names of ali the controls on the form , and
"form. " (Yo u' II leam more about "general" later.)
The Procedure box, on the right, li sts all of the eve nts recogni zed by the fo rm or control
selected in the Object box . If you have airead y written a procedure for an even t, the Object
bo x di spl ays th e event in a bold font. Wh en you se lect an eve nt in the Procedure box, the
procedure assoc iated with it (ora code template) is di spl ayed in the editin g area in the
bottom part of the Code window .
I
· · : Starting Balance
· : : lnterest Rate in ~
_
~---
. ' •
~ ----S ub Cal Endlext
: : : Duration in Years Form
End Sub Labell
~ ---- Label2
Label3
Label4
Rate Text
Startl e xt
· · : Ending Balance Yearslext
+
+
: : : lnte,est Ra te in %
. +
•
In addition to helping you write an event procedure by providing a template, Visual Basic
also catches errors in the code you type. This feature is call ed syntax checking. You can turn
it on and off from the Code menu. When syntax checking is on, Visual Basic displays a
message when it detects an error in syntax in a line of code. The message tells you what kind
of error yo u' ve made. For Help on correcting the error, press Fl .
Note You' 11 also use the Code window to write general procedures, and code that' s stored
in a module. For information on using modules, see Chapter 15 , "Creating Multiple-Form
Applications." For information on general procedures, see Chapter 9, "Language Elements ,"
or:
lmportant Files saved with the Save File command store both the form and code attached to the form in
binary format. You cannot load this formal into a text editor. To save the code-but not the
form - in text (ASCTI) format , choose the Save Text command from the Code menu .
The completed event procedure should }ook like the code in Figure 8.4.
Objecl: ICalcCmd
•
+ +
The statements between Sub andEnd Sub are indented to make the procedure easier to
read . You don ' t have to indent lines in your code.
Note The procedures you attach to forms and controls are part of the form file. Thus, to
permanently save your work on the procedure, you must save the form file to disk. To save
your work and continue , choose Save File from the File menu .
To use the lnvestmen t Ca lcu lator, first enter numbers in the first three text boxes. (Yo u can
enter decimal point s. but not dallar signs or commas.) Click the command button to find th e
ending balance of an investment that is compounded daily . Type new values and cli ck the
button again for each new calc ulation . When you ' re finished, choose End from the Run
menu .
If Vi sual Basic detec ts a run -tim e error in your code, it displays an error message. For Help
in resolving the eJTor, press FI.
When you run your app li ca tion , the Immediate window opens undemeath the application
window. (In Chapter 16. "Debugging," yo u' ll learn how to use the Immediate window
to execute individual lines of code and to modify or examine variable values) . It also is
useful during debugg ing- fixing errors in your code. For information on debuggin g, see
Chapter 16, or:
To learn how to run th e I nves trnent Calculator as a separate application, without Vi sual
Basic , see the secti on "C reating an Executable Fil e" later in thi s chapter.
Tberefore, the followin g statement copies the contents of the StartText tex t box into a
varia ble call ed My Stri n g $:
My Str ing$ - StartText.Text.
The Val function con ve rts th e tex t th at fo ll ows it in parentheses into a number. In thi s
exampl e , the express io n in parentheses represents th e tex t in th e StartText tex t box , while
th e nam e on the le ft is the name of a variable th at will be used later in a calc ulation .
For more inform ation o n data types, see C hapter 9 , "L anguage E leme nts," or:
Doing Calculations
Mathematical fo rmulas in Visual Basic look m uch like they do on paper, except fo r sorne of
the sym bols called operators. The asterisk (*) means " multiply ," the fo rward slash (/) means
"di vide," and the caret (") means "rai se to the power of."
Pare ntheses are used to make the order of calcul ati on expli cit. For instance, in the followin g
example, the expression 1 + Ra t e / 365 0 0 is evaluated first and then raised to the power
of Ye a rs * 36 5 and fi nally, multiplied by Sta rtBa 1.
EndBal = StartBal * ( 1 + Rate / 36500) A (Years * 365)
T he fo mrnl a is the standard formul a for calcul atin g interest co mpounded dail y.
Formatting Output
T he numeric res ul t of the calculati o n abo ve was ass igned to the vari abl e En d Ba 1 . But befo re
the CalcCmd_Click procedure can di splay th e endin g balance in a tex t box , you mu st
convert the balance back to a string data type.
The easies t way to do thi s is to use the Str$ functi on. The Str$ fun cti on is the opposite of
the Val fu ncti on: lt con verts a number in to its tex t eq uivalent. To assign the result of the
End Bal calcul ation to the EndText tex t box, use th e code below. Note that instead of
ass igning the result to a variable, th e state me nt assigns it to the Tex t property of the E ndTex t
tex t box .
EndTe xt. Text = St r $(E ndBal)
T he Str$ fu nc ti on returns an unformatted string. If yo u use it, the ending balance will be
di splayed as a 15-digit number and you ' ll have many more decimal places than you need .
To format the string so that it di spl ays onl y two dec imal places, use the Format$ fun cti o n.
Like Str$, Format$ converts a number to a stri ng, bu t it also fo rmats it accordin g to the
pattern yo u spec ify, as shown in thi s code:
End Text.Tex t = Fo r mat $( EndBal. "#,###.##0 . 00 " )
T he # sig ns represent the digits greater than l O. T he ones and decimal places are represented
by zeros .
T he Format$ functi on can also spec ify many o th er formats. For compl ete info rmati on on
Format$, see th e Language Ref erence, or:
Now yo u' ve hada very brief introducti on to writin g event procedures. Chapter 9, " Lang uage
Elemen ts," teac hes yo u more about contro l properti es, vari ables, ass ignment statements, data
types. and oth er face ts of the Vi sual Basic lang uage. Chapter 9 also te ll s you how to t1 se a
Vi s ual Bas ic co ntrol stru cture to add more f un cti o nalit y to the In ves tment Calcul ator.
Once you've converted yo ur application toan executable file, you can run the exec utable file
from DOS by typing :
win filename
Note If you develop an app li ca ti on using Visual Basic for Windows, that app li ca ti on can
run only under Windows 3.0 or higher, in sta ndard or enhanced mode. Similarly , if you
develop an application using Visual Basic for Presentation Manager, that application can run
only under Presentation Manager.·
For more information on th e op ti ons that are possible when you create an exec utabl e file :
rA.pplication-Building Techniques
Part 3 surveys basic techniques for writing code for a Visual Basic
application - how to create menus and commands, get input, display results,
draw pictures, and display multiple forms. After reading this part, you should
have a good grasp of how to get things done in Visual Basic. Part 4 shows
you how to add the extra touches included in a sophisticated application .
Language Elements
The Vi sual Basic programmin g lan guage is designed to be flexible and powerfu l, yet easy .
to use. This c hapter ex plain s sorne mechanics of the language so that yo u can use it in your
applications to make decisions, perform calc ul ation s, and subdivide tasks for easier
programm ,ng.
The Vi sual Bas ic language is close in most respects to Microsoft QuickB as ic and the Basic
Professiona l Development System. lf yo u' re fam iliar with these other two modern vers ions
of Basic. the first sect io n of thi s chapter was written espec ially for you.
Online He lp and the Language Refe rence each provide a complete refere nce to the Vi sual
Basic lang uage, includi ng functi ons, statemen ts, and methods. They also in cl ude re ferenc e
informati on o n objec ts, eve nt s, and controls. But this chapter introduces so rn e lang uage
informati on you · 11 need to know to fo ll ow th e rest of the manual.
The mai n sec ti ons in thi s chapter are :
• Mi crosoft QuickBasic and Vi sual Bas ic
• Sorne Mechani cs (Com me nts, um bers, Statements)
• Setting and Rctriev in g Properties and Sto rin g Data
·Vi ual Basic Va ,i ables
There are other di fferences between V isual Basic and QuickBas ic as well -especi all y
w hen it comes to which statements each support s. For a co mpl ete di scussion of ali the
differences, see Appendix A , "Adapting Bas ic Code."
Another thin g you ' ll see a lot of is nu mbe rs . Mos t nu mbers in thi s manu al are decimal (base
l O). But occasionally it's con ve ni ent to use hexadec imal numbe rs (base 16). Visual Bas ic
represents numbers in hexadecimal w ith th e prefix &H and octal (base 8) w ith &O. T he
fo ll ow ing table sho ws the same numbers in dec ima l, oc tal, and hexadec imal.
Decimal Octal Hexadecimal
9 &0 11 &H9
15 &01 7 &HF
16 &0 20 &HI 0
20 &024 &H l4
255 &0377 &HFF
Although sorne important constants are defi ned in hexadec imal, yo u generall y don ' t have to
leam the hexadecimal or oc tal number system yourself. A constan/ is a value th at cannot
change during program executi on.
Note If you want to use a hexadeci m al or octal constant in situati ons that involve large
numbers, append an ampersand (&) to the constant. Thi s causes the value to be stored
correctly as a lon g integer. T he " Data Types" section later in thi s chapter gives more
informati on on lon g integers.
Visual Basic statements are normally one to a line, and there is no statement terminator.
However, you can pl ace more th an one statement on a line by using a colon (: ) to separate
them:
Textl. Text = "Hel lo " : Red = 255 : Textl. BackCol or = Red
The Text property is a strin g of characters th at spec ifies the contents of a text box, li st box,
or co mbo box . You ca n ass ign onl y strings to thi s property. T he last two statements above
use the Str$ fun cti on to co nve rt a number to a strin g. V isual Basic requires th at both sides o f
the ass ignme nt stateme nt be strings or both be numeric.
The second statement uses the Val function to convert a strin g into a number. This function
is the converse of the Str$ function .
In addition, each variable has a scope th at determines how much of the application
recognizes the variable. For more information on scope, see the next section, "Scope of
Variables."
Variable Names
A variable name can be up to 40 characters long, and ca n include letters, numbers, and
underscores ( _ ). There are two restrictions :
• The first character in the name must be a Jetter.
• You cannot use a reserved word as a variab le name, thou gh yo u can embed one inside a
larger variabl e name (for example, PrintThis) . Reserved words are words that have a
special meaning in Visual Basic. This inc ludes predefined statements, function s,
methods, operators (such as And or Mod) , and property narn es .
In addition to numbers and letters, a variab le narne also can include a si ngle type-declaration
character used as a suffix, as explained in the next section .
Data Types
Visual Basic variables come in six standard types, as shown in Table 9. 1.
Table 9.1 Standard Variable Types
Type-declaration
Type name Description character Range
lnteger Two-byte integer o/o - 32,768 to 32,767
Long Four-byte integer & - 2,147,483,648 to
2,147,483,647
Single Four-byte floatin g- - 3.37E+38 to
(the default) point number 3.37E+38
Double Eight-byte floating- # (or none) - 1.67D+308 to
point number l.67D+308
Currency Number with fix ed @ - 9.22E+l4 to
decimal point 9.22E+ l4
String String of characters $ (not applicable)
Befare using a variable, you should decl are its data type with the Dim statement (or one of
the keywords Global or Static). For example, the following statements declare an Integer ,
Double, String, and Currency type , res pec tively:
Dim I As Integer
Dim Amt As Double
Dim YourName As String
Dim Bill s Paid As Currency
The Dim statement can combine multiple dec larati ons, as in these statements:
Dim I As Integer, Amt As Doubl e
Dim YourName As String, Bill sPaid As Currency
The third column of Table 9 . 1 lists the Vi s ual Basic type-declaration characters. Instead of
declaring a type with As, you can identify the data type of a variable by appending a type -
declaration character to the end of the variable name . lf you do so, use the type-declaration
character consistently. For example, Co unt% has type Integer, X# has type Double, and
MyName$ has type String.
If you don ' t use either method to declare a type, Vi sual Basic assumes the variable has the
Single data type. However, you can chan ge thi s de fault for a form or module by using a
Deftype statemen t. For more information o n Deftype, see Chapter 17, " Advanced Lan g uage
Features" ; the Language Reference ; or:
If yo u know th at a variable will never need to store a fractional amo unt (such as 3.57) ,
dec lare it as an integer ty pe (lnteger or Long). Operations are fas ter with integers. If the
vari able contains a frac tion , declare it as a flo atin g-point or Currency variable. The
Currency data type supports up to four digits to the right of the decimal point and 14 to the
left. F loating- point numbers have much larger ran ges than Currency, but have a ro unding
erro r produ ced by conversion between base two and base ten fraction s.
Note Floatin g- poi nt constants can be expressed as mmmEeee or mmmDeee, in whi ch mmm
is the mantissa and eee is the exponent (a power of ten). Thus, the hi ghest poss ible va lu e of a
Single data type is 3.37E+38, or 3.37 ti mes 10 to the 38th power. T he use of D causes a
value to be stored as a Double data type.
Values of numeri c vari abl es can be ass igned to each other. Visual Basic round s off th e
frac ti onal part of a fl oatin g-point nu mber before assigning it to an integer.
Scope of Variables
T he scope of a variable is its visibility wi thin an application - in other word s, how rnuc h of
the appli cati o n recogni zes the variable. For example, when different proced ures refer to a
variable coun t , do they all refer to the sam e piece of information, or do th ey eac h have their
own prívate versio n?
T he different levels -from local to global -are summari zed in Figure 9. l.
procedures procedures
Form Module
Application
Scope is one of the principal areas in whi ch Vi sual Basic differs from o ther vers io ns of
Bas ic, inc ludin g M icrosoft QuickB as ic. With Vi sual Basic, the issue of scope is a litt le
sirnp le r beca use it is determin ed mainl y by the placement of a declarati on.
Local Variables
A local variable is recogni zed only within the procedure in which it appears. A local
variable is a good choice for any kind of temporary calculation. A dozen procedures can ali
have a variable called Temp , for instance, but as long as Temp is local, each procedure has its
ow n vari able. A procedure can alter its local Temp vari able without affecting Temp variables
in oth er procedures.
T o make a vari able local, place the data declarations (Dim state ments) inside the procedure:
Sub CmdButtonl _Click ()
Oim Centig r ade As Double
Oim Fa hren heit As Doub l e
Centigrade - Val(Readout.Tex t )
Fahren heit = (Centigrade * 1 .8) + 32
Readout.Text - Format$(Fa hrenh eit)
End Sub
A nother way to create a local variable is to just use it without any Dim statement ; Visual
Basic ass um es th e variabl e is local. However, thi s tec hnique is less rel iabl e, as you ' II see in
an upcoming secti on, "Confli cting Scope Declarations."
To edit th e Declarations secti on of a form, open the Code window and select "(general)"
from the O bj ec t box and "(declaration s)" from th e Proced ure box .
Mod ul e- leve ! vari abl es are similar to fo rm-level vari ab les. A module- leve/ va riable is
dec lared in the Dec larati ons section of a module and is shared by ali the procedures in that
modu le.
A noth er important reaso n fo r using form -leve l or modul e- level variabl es is th at th ey persist
after a procedure return s. Unl ess explicitl y declared as Static , a local vari able las ts as long
as the procedure does. Wh en the procedure is called again, th e variable starts at 0 - or an
empty string, if th e vari able is a strin g. The value of a form-level variable is more
perm ane nt, and las ts as long as the form does .
Global Variables
Global va riables have the broadest scope of ali. The entire appli ca ti on has access to a global
va ri able. T hey also are th e mos t persiste nt vari ables, re taining the ir va lues th roughout the
e nti re appli cati on.
You define global variabl es by decl arin g them in the global module and by using the Global
statement instead of the Dim stateme nt :
Global Warp Speed As Sin gle , Ali enCo unt As Integer
Control Structures
The statements that control dec isions and loops in Visual Basic are called control structures.
Visual Basic control structures are identi caI to those in recent versions of Microsoft Basic ,
and are similar to the control stru c tures found in C and Pascal. This section introduces the
most commonly used contro l stru ct ures:
• If... Then blocks
• If... Then ... Else blocks
• Select Case statements
• Do loo ps
• For loops
Note The term "control struc tures'· has nothing to do with controls on a form .
The first three items above are dec ision structures. You use them to define groups of
statements that may or may not be executed, depending on run-time conditions. The las t tw o
ítem. are loop structures. Yo u use th em to defin e groups of statements that Vi sual Basic
cxec utes repeatedly.
If condition Then
statements
End If
If condition is true, Visual Basic executes al! of the statements. (The statements consist of
zero or more lines of code.) You can use an If... Then block to execute just one statement
conditionally:
If X > 0 Then Textl . Text - "X is greater than zero. "
If X> 0 Then
Textl.Text "X is greater than zero."
End If
Or, as shown in the next example, you can place more than one statement in an If... Then
block. The example builds on the Investment Calc ulator presented in Part 2. This variation
computes the starting balance necessary to reach an ending balance entered by the user:
If StartBal - 0 Then
StartBal = EndBal / (1 + Rate / 36500 ) A (Years * 365)
StartText.Text - Format$(Start8al l
End If
The condition is a Boolean expression. A Boolean expression is one that can be evaluated as
true or false. Often condition is a relationaJ test such as X > O or X = Y. Relational tests use
the following operators.
Operator Meaning
= Equal
<> Not eq ual
< Less than
<= Less than or equa l to
> Greater than
>= Greater than or equal to
The relational operators work with both strings and numbers. You can test string variables
and constants for equality :
If AdrVar$ = "123 Main Street" Then
You also can perform greater-than and less-t han tests with string vari ables. Visual Basic
resolves these kinds of comparisons by using alphabetical arder, so that Aardvark < Zy pher
evaluates to tru e. However, you cann ot compare a strin g to a number.
The keywords And , Or, Xor, Eqv, Imp, and ot canjoin conditions together to create
comp lex conditions. For exampl e:
If . (X > Y) Or (X> = 10 And X <- 20) Then
Sorne properties are Boolean-they have on ly two settings: True or False. A reference to a
Boolean prope rty can, by itself, prov ide the co nditi onal part of an If statement.
Visual Basic firs t tests conditionl. If it's false, Visual Basic proceeds to test condition2 , and
so on , until it fi nds a tru e cond ition. The corresponding statement bl ock is then executed.
You can opti onall y include an Else state ment block, which Visual Bas ic exec utes if none of
th e condi ti ons is true.
lf... Then is reall y j ust a special case of If...Then .. . Else. Note th at you can have any
number of Elself clauses, or none at ali. You can include an Else clause wheth er or not you
have Elself clauses .
The following procedure uses an If... Then ... Else block to make the lnvestment Calculator
(shown in Part 2) more flexible. This version lets the user calculate any of four different
va lues: Starting Balance, Interest Rate, Duration in Years, or Ending Balance. The
If... Then ... Else block performs a series of tests to see which value was set to zero. The
procedure then recalculates that value, using the other three values as input:
Sub CalcCmd_Click ()
StartBa l = Val(StartTe xt .Text)
Rate = Val(RateText.Text)
Yea rs = Val ( Yea rsText. Text)
EndBal ~ Val(EndT ext.Text)
If StartBal = 0 Then
StartBal = EndBal / (1 + Rate / 36500) (Years * 365)
A
RateText.Text = Format$(Rate)
Elself Years = 0 Then
R = 1 + Rate / 36500
Years = (Log(EndBal / StartBal) / (Log(R)) / 365)
YearsText.Text = Str$(Years)
Else
EndBal = StartBal * (1 + Rate / 36500) (Years * 365)
A
EndText.Text = Format$(EndBal)
End I f
End Sub
This procedure uses a local variable, R to si mplify the calculation of Ye ar sR is local anda
double-precision type by default, so the example works correctly as long as R is not declared
at some other leve! (form or global) .
Thi s code stores "One" in the text box if X is 1, "Two" in the text box if Xis 2, and so on.
The following Select Case statement performs exactly the same operation :
Select Case X
Case 1
Textl. Text "One"
Case 2
Textl. Text "Two "
Case 3
Textl. Text "T hree "
Case Else
Textl . Text "Too bi g"
End Select
This vers ion of the code is easier to read, and Visual Basic exec utes it slightl y fas te r.
However, not al] If ... Then ... Else statements can be rewritten thi s way.
A Select Case state ment works with a single test value (w hich can be num eric or string) .
Visual Basic tes ts to see if any value in expressionlist is egu a] to the test value . lf so, it
exec utes th e corres ponding block of statements. Select Case uses thi s sy ntax:
Select Case rextexp ression
Case expressionlist 1
statementblock- 1
[ Case expressionlist2
starementblock -2]
[ Case Else
srorem enthlock- 11 ]
End Select
Each expressionlist is a list of one or more numeric or string values. If there is more than one
value in a single list, the values are separated by commas. Each statementblock contains zero
or more statements. Visual Basic executes statements in the Case Else clause (which is
optional) if none of the values in the expression lists matched the test value.
Do Loops
Use a Do loop to execute a block of statements an indefinite number of times. There are
several variations of the Do ... Loop statement, but each of them checks a Boolean condition
to determine whether to continue execution .
The following Do ... Loop says, "as lon g as the condition is true, execute the statements":
Do While condition
statements
Loop
When Visual Basic executes this Do loop, it first tests condition. If condition is false, it skips
past all the statements. If true, Vis ual Basic :
1. Executes the statements.
2. Goes back to the Do While statement and tests the condition again.
Consequently, the loop can be executed any number of times, as long as condition is true.
Note that the statements are never executed if the condition is initially false. (This version of
Do ... Loop is equivalent to While ... Wend, which Visual Basic also supports.)
For example, the follow ing Form_Click procedure prints numbers from I to 20. The Print
method (which prints to the form unl ess anot her object is specified) is given only once.
Visual Basic executes the stateme nt Pri nt I as long as I is less than or egua! to 20:
Sub Form_Clic k ()
Dim I As Integ er
I = 1
Do While I <= 20
Print I
I = I + 1
Loop
End Sub
Another variation of the Do ... Loop statement executes the statements first , then tests
condition after each execution. Thi s variation guarantees at least one execution of
statements:
Do
statements
Loop While condition
Two other variations are analogo us to the previous two, excep t that th ey test whether
condition is false rather than true :
Do Until condition
statements
Loop
Do
statements
Lo5>p Until condition
For Loops
Use a For loop to execute a block of statements a set number of times. Unlike a Do loop, a
For loop inc ludes a spec ial variable called counter, which increases (or decreases) in value
during each repetiti on of the loop . The sy ntax is:
For counter = start To end [Step increment]
statements
Next [counter]
The arguments counter, start, end, and incrementare al] numeric . They are not required to
be integers, but Vi sual Basic 's performance is better if they are.
Note The argument increment can be either positive or negative. If increment is positive,
start must be less than or eg ua! to end . lf increment is negati ve, start must be greater than or
equ a l to end.
For example, the folJowing procedure performs the same action s as the Do loop in the last
sec tion , but with fewer statements:
Su b Form_Click ()
Dim I As Integer
Far I = 1 To 20
Print
Next I
End Sub
The For loop in this procedure prints all the numbers from 1 to 20. The difference between
this loop and the Do ... While loop of the last section is that the For statement performs the
initialization (1 = 1) and the incrementing (1 = 1 + 1) automatically.
To specify an increment other than 1, use Step. For example, the following code modifies
the procedure above by printing ali odd numbers from 1 to 20:
Sub Form_Click ()
Dim I As Integer
For I = 1 To 20 Step 2
Print I
Next I
End Sub
r
1
In essence, a ge neral procedure tells the application how to perform a specific task. Once the
procedure is defi ned , you can cal! it from anywhere in the application. For exa mpl e, a
complex procedure could di splay a bar chart. After writing the procedure, you can then
di splay a bar chart with a single statement:
Di sp l ayBarChar
T he use of ge neral procedures also helps divide complex application code into manageable
units.
Procedures ca n e ither be Sub procedures or Function procedures. A call to a Sub proced ure
is a complete statement, whereas a cal] to a Function procedure is part of an express ion. For
example, the fo ll owing statement shows calls to two different Function procedures:
Sum = CrossProduct(A, B. C) + St andDe v(Arrl , N)
Cr oss P rod u et and Stand Dev each retum a single value, which Visual Basic the n uses to
calcu1ate the va lue of Sum .
Note Even t proced ures are alw ays Sub procedures, never Function procedures.
Consequentl y. proced ures defined in a mod ul e are recognized by th e e ntire app li ca ti on. But
procedures att ached to a fo rm can be cal1ed only by other proced ures attached to th at forrn.
A proced ure name defi ned in a module mu st be unique across ali mod ules. A procedure
na me defined in a form can be defined in other forms . (Thu s, eac h fo rm ca n have its ow n
Form_Load proced ure.)
To create a new general procedure, make sure the Code window is open. Then choose New
Procedure from the Code menu . Another technique is to type a procedure headin g within the
Code window an d press ENTER. T he procedure heading can be as simple as Sub or Function
fo llowed by a name. For exa mpl e, you can enter either of the fo ll owi ng:
Sub Updat eForm
Function GetCoord
Vi sual Bas ic respond s by clea rin g the Code window and displaying a template for the new
procedure .
To ed it an ex istin g ge neral procedure, select "(general)" from th e Objec t box in th e Code
window, th e n se lec t the proced ure in th e Procedure box .
Sub Procedures
The syntax for a Sub procedure is :
Sub procedurename (arglist)
statements
End Sub
The arglist is a list of argument names, separated by commas if there is more than one. Each
argument can optionally have a type-declaration character (%, &, !, #, @, or $)oran As
clause. The syntax of each argument is :
[ByVal] variablename [()] [As type]
The optional ByVal keyword is explained in the section "Passing Arguments by Value" later
in this chapter.
The type can be any of the standard data types: Integer, Long, Single, Double, Currency ,
or String. Parentheses after variablename indicate that the argument is an array. See
Chapter 17, "Advanced Language Features," for more information on arrays, as well as the
special Form and Control argument types.
Each time the procedure is called, the statements between Sub and End Sub are exec uted.
Visual Basic substitutes each reference to an item in the argument list with the correspond-
ing argument. For example, suppose you have defined the MultiBeep procedure as :
Sub MultiBeep (NBeeps As Integer)
Dim I As Integer
For I = 1 To NBeeps
Beep
Next I
End Sub
Visual Basic responds by calling the MultiBeep procedure and passing 3 as the argument.
The procedure substitutes 3 for NBeeps (the name that appears in the argument li st), thus
executing the following code:
Dim I As Integer
For I = 1 To 3
Beep
Next I
The procedure therefore beeps three times. In the next example, the procedure beeps 12
times because 12 is passed as the argument:
Mult iBeep 12
Calls to a Visual Basic Sub procedure do not use parentheses around the argum ent li st. For
example, the foll owing procedure uses the Log function (which always uses a base of
2. 71 8282) to calculate logarithms of any base. The logarithm is calculated from the seco nd
and thi rd arguments, and assigned to the first argument:
Sub LogB (Resu l t As Doubl e, Base As Doubl e, X As Double )
Result = Log(X) / Log(Base)
End Sub
Then the following calls to LogB store results in the vari ables Ex ponentl , Log l 0, and
Ye a rs:
LogB Exponentl, B, A
LogB Logl0, 10 , Amt
LogB Years, 1 + Rate / 365 00 , EndB al / Sta r tBa l
The LogB procedure also demonstrates how a procedure can return informati o n by changing
th e value of one or more of its arguments. If you call LogB and pass a vari abl e as the first
argum ent, thi s variable gets changed. Both Sub and Function procedures can change their
arguments thi s way.
Function Procedures
The syn tax for a Function procedure is:
Function p rocedurename (a rguments) [As type]
statements
End Function
Every thing said in the previous section about argum ents applies equ all y to Function
proced ures. Aside fro m th e Function keyword , there are three di fferences betwee n Sub and
Function procedures:
• Yo u use parenth eses with each Function call .
• Function procedures have types, just as vari ables do. Thi s determin es the type of the
re turn value. (In the absence of an As clause, the type is determin ed from the
procedurename , whi ch can have a type-declaration character.)
• Yo u re turn a value by assigning it to the procedurename itself. Whe n the Function
procedure return s a value, thi s value is then used as part of a larger express ion.
The last statement, slightly modified, could form part of the code far the CalcCmd_Click
procedure introduced earlier in this chapter:
Years = LogF(l + Rate / 36500, EndBal / StartBal) / 365
As yo u can see, the procedure does change both arguments, Res u 1 t and N. However,
because of the By Val keyword, changes to the seco nd argumentare ignored once the
procedure retums. The following statement changes the value of Amt (placing the results of
the calculation there) and has no effect on X:
Factori a 1 Amt. X
The first argument gets passed by reference, the Visual Basic default. This gives the
procedure direct access to the argument itself- in this case, Amt. The second argument is
passed by value . This gives the procedure a copy of the value of the argument. The
procedure has no access to the second argument-in this case, X.
You can give a constant ora complex expression asan argument, even if it is passed by
reference (the default). Visual Basic responds by storing the value of the argument in a
temporary variable and then passing the four-byte address of this temporary variable . To
force a si mple variable to be passed this way, place it in parentheses, as in the function call
Log F ( (Base) • ( Amt)). This has the same effect as passing by value.
lmp ortant Property values (such as Textl .Text) cannot be passed directly unless you pass them by
value. Either use a ByVal argument or put parentheses around the property reference.
Visual Basic evaluates th is expression as if the foll owing parentheses were present:
( Va r l = Var 2) And ((X+ (Y* 2)) > Z)
Sorne ex pressions involve operators at egua! levels of precedence. When thi s happens,
Vi sual Basic operators assoc iate left to right. Howe ver, if an expression contains multiple
cal Is to Function procedures, yo u cannot rely on the m being executed in a parti cul ar order.
T he fo llowing operati ons, whi ch may be new to you, are covered in the nex t few sections:
• Ex ponenti ati on
• lnteger di vision and mod ul o arithmeti c
• Logical operati ons
• String operations
Exponentiation
Exponentiation is simply raising a number to a power-multiplying the first operand by
itself repeatedly. Far example:
Result Amt 2A ' Amt squared (Amt * Amt).
Result = Amt A 3 ' Amt cubed (Amt * Amt * Amt).
Result Quantity A -2 ' Quantity raised to power of - 2 .
After these statements are executed, the values of Quot , I ntQuot , andRe ma i nder are 9.5 ,
9, and 1, respectively .
Note Truncation is not the same thing as rounding. Truncation discards the fractional
portian, no matter how large. Rounding adds l to the integer portian of a number if the
fractional portian is greater than or equal to 1/2.
Logical Operations
Logical operators serve a dual purpose. They combine Boolean conditions in a meaningful
way, and they also perform bit-wise operations on any integer values. A bit-wise comparison
is a comparison of corresponding bits in two numeric expressions. A bit is the smallest unit
of data a computer can store.
The use of these operators in Boolean expressions works as long as -1 is used to represent
True and O is used to represent False. Visual Basic relational operators and Boolean
properties always retum True or False according to this convention .
For more information on how each of these operators combines bits:
String Operations
Visual Basic supports operations on strings only for the plus operator (+ ), which denotes
string concatenation, and the relational operators. The relational operators compare strings
according to alphabetical order.
Visual Basic provides many ways to put commands in your application. Command buttons,
for example, enable a user to easily perform an action : The user clicks the button and your
code (a Click event procedure) responds.
But as you experiment with Vi sual Basic, yo u'll want to try different ways of providi ng
commands. Menus take up less screen space than command buttons, and are almost as easy
to use. Shortcut and access keys provide command capabilities from the keyboard ; they help
you support users who don ' t have a mouse, and they make it fas ter to execute a command
when the user's hands are at the keyboard .
Thi s chapter expl ains how to put commands in yo ur appli cati on, starting with the simplest
techniques and progressing to techniques that require more programming.
The main sec tions in this chapter are:
• Respondin g to Command Buttons
• Controll ing Command Buttons at Run Time
• Creating a Menu -Dri ven Applicati on
• Controlling Menus at Run Time
• Addin g and Deleting Menu Commands
• Shortcut and Access Keys
• Contro lling the Tab Order
102 Part 3 Application-Building Techniques
When the user chooses the button, it not only carries out the appropriate action (in this case,
starting fireworks), it also looks as if it ' s being pushed in and released. The latter feature ,
which is built into command buttons, is a visual cue to users that they've successfully
chosen the button .
There are four ways the user can choose a command button:
• Use the mouse to click the button.
• Move the focus to the button by pressing the TAB key, then choose the button by pressing
the SPACEBAR. (Focus is the ability to receive user input typed at the keyboard.)
• If the command button is the default command button for the form , pressing ENTER
chooses the button , no matter which control on the form has the focus.
At design time, you specify a default command button by setting that button's Default
property to True (- 1) .
• If the command button is the default Cancel button for the form , then pressing ESC
chooses the button , no matter which control on the form has the focus.
At design time, you specify a default Cancel button by setting that button ' s Cancel
property to True (- 1).
All these actions cause Visual Basic to invoke the Click event procedure . lt makes no
difference to the application which method is used.
Picture boxes also recognize the Click event, so you can use a picture box anywhere you'd
use a command button. For instance, instead of the command button shown in Figure 10.1
(which has the caption, "Start fireworks display"), you could use a picture box that displays
a picture of a firecracker. Figure 10.2 shows a picture box that uses one of the firecracker
icons from the Icon Library included with Visual Basic.
al Test Button aa
Figure 10.2 Picture box with icon from the lcon Library
Note Aside from Click, the other events recognized by both command buttons and picture
boxes include DragDrop, Dragüver, KeyDown, KeyPress, KeyUp, GotFocus, and
LostFocus.
For more information on comrnand buttons, see the Language Reference, or:
1m Two-Button Example aa
Source
D estination
¡Ouplicate¡ ~
~
This is the Click event procedure for the left command button (named "Dup" in code):
Sub Dup_Click ()
Dest.Text = Src.Text
End Sub
Ali the work of thi s procedure is done in the seco nd line of code. The Text property specifies
the st1ing of tex t displayed in the text box . Thus, the statem en t copies the contents of the text
box named "Src" into the tex t box named "Dest'':
Dest . Text = Src . Text
Clicking the Clear Out command button (referred to as "Clearüut" in code) erases the
contents of the text boxes by placing an empty string in each one. The Clearüut_Click
procedure tells the button how to respond to the click:
Sub Clearüut_Click ()
Dest.Text = ""
Src .Te xt =
End Sub
Translating to Uppercase
By itself, copying text from one location to another isn't that interesting. We can make the
application just described more useful by adding text translation.
Visual Basic includes a number of string-handling function s, including LCase$ and
UCase$, which translate strings to lowercase and uppercase letters, respectively. To add
uppercase translation, you app ly the U Case$ function to the contents of the Source text box :
Sub Dup_Click ()
Dest.Text - UCase$(Src . Text)
End Sub
After making this change and running the appl ication again, you'll find that the Dup
command button not only copies text from Src to Dest, but also translates that text to ali
uppercase letters.
For more information on UCase$ and LCase$, see the Language Reference , or:
The argument commandstring$ is the name of the program or command to be exec uted.
For exam ple, Figure 10.4 shows an application you might develop for a proj ect man ager
who wants qu ick access to di fferent types of information. By clicking a comm and button,
the manager can qui ckl y view a proj ect plan, schedule, ora list of people workin g on the
proj ect.
The Click proced ure for the Plan com mand button starts Mi crosoft W ord fo r Windows and
ope ns the fi le con taining the project plan:
Sub Pl an _ Click ()
x - Shell( " \winword \ win word .exe plan.doc " , 1)
End Sub
The Click procedure fo r th e Sc hed ul e co mm and button starts Mi crosoft Proj ec t fo r Windo ws
and loads the schedul e fi le:
Sub Sched Click ()
y = Shell( " \ winpr oj\winproj.exe sc hedule. wpr " , 1)
End Sub
To keep track of names and addresses, the manager uses the Cardfile appli cation th at comes
with Microsoft Windows. The Click procedure for the Contacts command button is:
Sub Cont _ Click ()
z = Shell("\windows\cardfile.e xe prjnames . crd", 1)
End Sub
Each of these procedures starts a Windows application in a normal window . You also can
start them in minimized or maximized windows.
Note that the three Shell functions above return values to variables x, y , and z. This return
value is not used in the project manager application, but you may find it useful in other
applications. The value identifies the program started by Shell and indi cates whether the
program started successfully .
For more information on the Shell function , see the Language Ref erence , or:
Search Help for:
111 Shell
When you disable or enable a command button, you're controlling the user' s access to the
comrnand. Generally, you di sable a command because the comrnand is either impossible or
inappropriate at the time-for example, when a comrnand is supposed to del ete a specified
file , but the file is read -only .
The techniques di sc ussed here require setting certain Boolean properties to True or False.
The next section shows how to do this with the assignment statement.
T his means you can set a Boolean property to True- th at is, "turn it on" - by assignin g any
integer other than zero. Far example, any of these statements enable th e DoAction command
button:
DoAction.Enabled - 3
DoActio n .Enab l ed = 1776
DoAct i on.Ena bled - - 1
To turn a Boolean property off, set it to O. For example, the fo llowing statement di sables the
DoAction command button :
DoAction.Enaoled - 0
However, although you can assign any non-zero value to turn a Boolean property on , Visual
Bas ic stores it as - l. The safes t course of acti on is to use - 1 exclu sive ly for True .
You can make your code more readable by placing the fo llowi ng Const (constant)
defi nitions in the Declaratio ns sec tion of the form or modul e:
Const TRUE= -1
Const FALSE= 0
Ali co ntrol s except frame and label control s have the Enabled property ; you can use similar
code to disable a co ntrol orto find out if it is enabled.
The properti es of the tex t boxes are listed in the fo ll ow ing tabl e.
Control CtlName property Caption property
Top tex t box Readout
Botto m tex t box InfoBo x
Top label Number readout :
Bottom label Jnfo rm ati on box:
CaQtion: \~ 1 1 -º_one
Figure 10.6 Menu Design window far the Try Menus application
Each e ntry in the Menu Design window creates one menu control, and each menu control
co rres ponds to a men u item. Menu items include menu names, commands, separator bars,
and subme nu names. The items in the Menu Design window work like thi s:
• If a menu item is not inden ted. its caption appears on the menu bar as a menu name .
Menus whose names appear on the menu bar are top-l eve! menu s, as opposed to
submenu s, whose names appear on other menu s. Top-leve] menus usually are just call ed
menu s.
To qui ckly see which menu names will appear on the menu bar, sean down the left of the
Menu Design window; eac h item that isn't indented is a menu name.
• Each item that follows a menu name, and is indented only once (preceded by four dots),
appears as an item on that menu .
Menu ite ms can include commands, separator bars, and subme nu names. To qui ckl y see
which ite ms will appear on a menu, sean down the items th at follow a menu name; eac h
ite m indented only once is an item on that menu.
• An ite m th at is indented twice (and thu s is preceded by eight dots) is an item on a
submenu . As with items on a top-level menu, items on a submenu can include
commands, separator bars, and other submenu names.
To qui c kl y see which items wi ll appear on a submenu, sean down the ite ms that follow
th e subme nu name ; each item inde nted once more than the name is an item on th at
subm e nu .
• To create additional levels of submenus, just indent items more to the right.
Visual Basic supports five levels of indentation. Therefore, each of your menus can have
up to four levels of submenus. The fifth level can include commands and separators, but
not submenu names .
• If a menu item has a Caption setting consisting of a hyphen (-), it appears as a menu
separator bar. A separator bar divides items into logical groups on a long menu .
• All menu items except separator bars recognize the Click event. The Click event
procedure for each item (remember that each item is a control) is invoked when the user
chooses it.
Generally you write event procedures only for items that are commands. You can
consider the Click event for a menu or submenu name to be a "drop-down" event: It
inforrns you that the menu or submenu is about to be opened.
To create the Try Menus application, set the following properties in the Menu Design
window.
Caption CtlName lndented
Action ActionName No
Square SquareCom Once
Square Root SquareRtCom Once
Info InfoName No
Date DateCom Once
Time TimeCom Once
Program Name ProgCom Once
Note To start indenting items in the Menu Design window, click the right arrow halfway
down the window. Subsequent items will have the same indentation, but you can use the left
and right arrows to change an item 's position .
The first statement (after the procedure heading) tran slates the text string in Readout into a
numeric value. The last line of code (before End Sub) tran slates the result back into a string
and stores thi s string in Readout.
T he SquareRtCom_Click procedure carries out the Square Root command approximately the
sa me way, but with a different calculation :
Su b Square RtCom_Click ()
Amt = Val(Readout.Text)
Amt = Sqr(Amt)
Readout.Text - Str$(Amt)
End Sub
The two event procedures use the reserved words Date$ and Time$. These words look li ke
st rin g variables but are act uall y string function s. Visual Basic responds to these fun ction s by
suppl ying the current date or tim e to yo ur app licati on.
For more information on Date$ and Time$, see the Language Reference , or:
Disabling a menu name has the effect of disabling the entire rnenu , since the user cannot
access any menu command without first clicking the menu name . This statement disables the
Info menu :
InfoName.Enabled = 0
There are two main reasons for placing check marks on menus:
• To tell the user the status of an on/off condition. Choosing the menu command
alternately adds and removes the check mark.
• To indicate which of severa! modes is in effect. This use of check marks is similar to
option buttons, in which one of several options is in effect.
Thi s sec tion illustrates the second case described above with an application that operates in
oc tal, decimal , and hexadecimal mode. The Number System ap plication has three menu
commands: Octal, Decimal, and Hex . A check mark appears on the menu to show which of
the three number sys tems is in effect.
The application shown in Figure 10.7 has a menu anda text box named "Readout."
Hex
197 1
When the user chooses one of the menu commands, the application converts the number in
the text box to the indicated number system. For exarnple, if decimal mode is in effect and
the user chooses the Hex command, the digit string "64" is redisplayed as its hexadecimal
eq uivalent, "40."
To create the menu, enter the following information in the Menu Design window. The check
mark next to the DecimalCom control indicates that the application initially uses decimal
numbers.
Caption Name lndented Checked
System SystemName o No
Octal OctalCom Once No
Decimal DecimalCom Once Yes
Hex HexCom Once No
Note This application uses Visual Basic defaults fo r the se iterns in the Menu Design
window: Index , Accelerator, Enabled, and Visible.
Sub DecimalCom_Click ()
Amt - ReadValue(Readout . Text) ' Read in number .
OctalCom.Checked = 0 ' Reset check mark .
DecimalCom.Checked - -1
HexCom.Checked - 0
Readout.Text - Format$(Amt) ' Display number.
End Sub
Sub HexCom_Click ()
Amt - ReadValue(Readout.Text) ' Read in number .
OctalCom.Checked = 0 ' Reset check mark
DecimalCom.Checked - 0
HexCom.Checked = - 1
Readout.Text = Hex$(Amt) ' Display number.
End Sub
Each of the procedures reads the contents of Readout by calling a general procedure,
ReadValue. This same code could be placed in every procedure, but by placing it in a
Function procedure you save yourself from typing the same code several times:
Function ReadValue (ByVal Digit s$)
If OctalCom.Checked Then
ReadValue - Val("&O" + LTrim$ (Digits$) + "&")
Elself DecimalCom . Checked Then
ReadValue Val(Digits$ + "&" )
Else
ReadValue = Val("&H" + LTrim$ (D igits$) + "&")
End I f
End Function
The ReadValue procedure tests to see which menu command is checked, because the
placement of the check mark indicates which number system to use. The procedure then uses
the Val function to get the numeric value. Note that adding a "&O" prefix causes Val toread
the digits asan octal string, anda "&H" prefix causes Val toread the digits as a hex strin g.
The LTrim$ function removes leading spaces from the number in the text box.
Appending an ampersand (&) enables the application to support conversion of larger
numbers. The ampersand suffix causes th e Val function to interpret the digit string as a long
integer.
lil e
Arrange lcon s
✓ l Windows Application s
Z. Acce ss orie s
l Main
~ Mi cro s oft Vi sual Bas ic
Yo ur Vis ual Bas ic applications can have rnenu s th at change size durin g run time. These
rnenu s have commands that are part of a control array.
1 1
Data property property property prop erty
(prívate) settings settings se ttings settings
lndex = O lndex = 1 lndex =2 lndex =3
Noti ce how each control is referred to with the syntax controlname (index ). You specify the
index of a control when you create it. In fact, specifying any index at design time makes the
control part of an array .
When the control Combos(2) recognizes the Click event, Visual Basic invokes the event
procedure Combos_Click, and passes the number 2 asan additional argument.
. . . .. . ,, .
When the user c hooses th e Add Application comrnand, a new item is added to the bottom of
the menu . When the user chooses Delete Application, a message asks for an index number of
an item to remove from the bottom part of the menu.
The menu co ntrols are created in the Menu Design window, with these property settings.
Caption CtlName lndented lndex
Applications App No
Add Application AddApp Once
Delete Application De!App Once
AppNafl)e Once o
The last co ntrol on the list, AppName, has its caption set to a hyphen (-), which causes
Visual Basic to display a separator bar.
Because AppName is assigned a value for the Index property, it automatically becomes an
eleme nt of a co ntrol array-even though no other elements ha ve been created yet. At run
time, the fo llowing stateme nt creates ano ther ele men t of the array :
Load AppName(l)
At run time thi s statement adds another item to the menu , just below the separator bar. The
next statement deletes this same element:
Unload AppName(l)
You can use the Unload statement only with controls that were created with the Load
statement; you cannot remove controls created at design time. Therefore, you cannot delete
the separator bar, which is the first element of AppName.
The procedures in this application use a variable called LMen u to track how many items are
on the menu . The variable should be declared in the declarations section of the form:
Dim LMenu As Integer
Once so rne commands have been added to the bottom of the menu, it's a simple matter to
execute the m. AppName_Click is the common eve nt procedure for ali of these commands.
The procedure works by simply passing the control ' s caption to the Shell function . Note that
the control chosen is identified as AppName(lndex):
Sub AppName_Click (Indexas Integer)
x = Shell(AppName(Inde x).Caption. 1)
End Sub
When the user chooses the Add Application comrnand, Visual Basic calls the
AddApp_Click procedure. Thi s procedure asks the user to suppl y the name of an
application:
Sub AddApp_Clic k ()
Msg$ = "En ter path:" ' Mes sage to di sp lay to user.
FileSpec$ = InputBox$(Msg$) ' Assign user input to FileSpec$.
LMenu = LMenu + 1 ' Increase menu length by one.
Load AppName(LMenu) ' Load new menu command.
AppName(LMenu).Caption FileSpec$ · Set caption far menu command.
End Sub
The second line of code uses the Visual Basic lnputBox$ function to display a box that
prompts the user for a filename (which can include a path). This filename becomes the
caption of the new menu command. The fifth line of code uses the Load statement to
actually add the new menu comrnand.
For more information on lnputBox$, see Chapter 11 , "Genin g Information from the User";
the Language Refe rence; or:
When the user chooses Delete Application from the Applications menu, Visual Basic
invokes the DelApp_Click procedure. When deleting an application, the user specifies the
number of the application (the application just below the separator bar is numbered 1). The
De!App_Click procedure has to do severa! things:
1. Get the number of the menu item to delete.
2. Yerify that the number is in range.
3. If Nis the number of the item to delete, copy the caption of item N+ 1. This makes it
appear that item N has been replaced by item N+ 1. Repeat the process for all items up to
the end of the menu.
4. Delete the last item on the menu .
5. Subtract 1 from LMen u.
The following table shows how: _this process rnight work, given four menu items, if the user
requests that ítem 2 be deleted.
lndex of item Before deletion After deletion Action
l Excel Excel
2* Winword Mines Caption copied from
ítem #3
3 Mines Cardfile Caption copied from
ítem #4
4 Cardfile Removed
The asterisk (*) above identifies the item that the user wished to delete. Note that only the
caption of this ítem changes. However, this is the same as replacing the menu item, because
the functionality of the item depends entirely on its caption.
The code for the DelApp_Click procedure is:
Sub DelApp_Click ()
Dim N As Integer. I As Integer
Msg$ - "Enter number to delete:" · Mes s age to display to user .
N - Val(InputBox$(Msg$)) ' Assign user input to N.
If N > LMenu Or N < 1 Then ' Exit if out of range .
MsgBox "Out of range."
Exit Sub
End If
For I - N to LMenu - 1 ' Rea ss ign capt ion s.
AppName(I).Caption = AppName(I + l) . Caption
Ne xt I
Unload AppName(LMenu) ' Remove last item.
LMenu = LMenu - 1
End Sub
The De!App_Click procedure introduces use of the Exit statement, which exits immediatel y
from the procedure. The use of thi s statement prevents the deletion from taking place if the
number is out of range. For more information on Exit, see the Language Reference, or:
To assign a function -key or control-key shortcut to a menu command, select from the list in
the Accelerator drop-down list box in the Menu Design window. Choose "(non~)" from the
top of the list to cancelan assignment.
To use a letter asan access key, placean ampersand (&) in front of the letter in the Caption
property setting. Most often, the access key is the first letter of the caption . You can assign
access keys to any control that has a Caption property, and to any menu name or comrnand.
For exarnple, the following Caption propert y settings respond to the letters O, S, and A:
&Open
Clo&se
Save &As
The arnpersand itself is not displayed on the control or menu ; instead, an underscore appears
beneath the designated letter.
Note Avoid giving multiple objects the same access key. Ideally, each control should have
a unique access key so that the key doesn' t have to be pressed repeatedly to get to the
desired object.
Note You can use the same technique to assign an access key to a picture box.
When Command] is the act ive control , pressing TAB moves the focus back to Textl.
Settin g Tablndex to O places Command 1 first in the tab arder. The Tablndex for the other
controls are au tomatically adj usted up ward, as li sted in the following table.
Tablndex before Command1 Tablndex after Command1
Control name becomes first in Tab order becomes first in Tab order
Textl o 1
Text2 l 2
Commandl 2 o
Whenever you change a Tablndex setting, Visual Basic adju sts the Tablndex property for
each control as necessary , so that the first control in the arder has a Tablndex settin g of O,
and the other cont,·ol s are numbered sequentiall y.
The highest Tablndex setting is always one less than the number of controls in th e tab arder.
You ca n set the Tabln dex property to a number large r than the numbe r of controls; this has
the effect of moving the control to the e nd of the tab arder. For exa mple, if there are ten
co ntrols in the tab arder, th e Tabindex settin gs run from O to 9. If you assign the value 15 to
a control's Tablndex property, Visual Basic converts this value to 9 and moves th e control to
the back of th e tab arder.
If you assig n a Tablndex value less than O, Visual Basic generates an error.
.. · e h a p t e r 1 1 ·
Microsoft Windows and OS/2 Presentation Manager provide a variety of input mechanisms,
which in Visual Basic are implemented as controls. By using each control for its intended
purpose, you add variety, make your applications easier to use, and maintain consistency
with other applications .
Text boxes are good input devices (because most types of information can be represented as
text) , but require the user to type. Option buttons, check boxes, list boxes, and combo boxes
enable the user to choose from a set of altematives. Scroll bars provide a graphical way to
indicate a number: The user changes a value by adjusting an indicator on a scale.
An altemative to data entry is the use of the lnputBox$ function, which prompts the user for
input by displaying a dialog box.
The main sections in this chapter are:
• Advanced Use of Text Boxes
• Providing Choices with Option Buttons
• Using Check Boxes
• Providing Choices with List and Combo Boxes
• Getting Input with Scroll Bars
Prompting for Input with InputBox$
124 Part 3 Application-Building Techniques
When ent ering text, th e user can insert a line break by pressing ENTER- unless a command
button with the Default property set to True is present on the form. If thi s is the case,
press ing ENTER chooses the button, and CTRL+E TER inserts a line break in the text box.
A multiline tex t box automatically manages word wrap as long as there is no horizontal
sc ro ll bar. The ScrollBars prope rty is set to None (O) by default. Automatic word wrap saves
th e use r the trouble of inserting line breaks at the end of lines. When a line of text is longer
th an what can be di splayed on a line, the tex t box wraps the text to the next line.
The Declarati ons section of thi s form de fi nes a form -level vari abl e that holds the most recent
acceptable value entered in the tex t box :
-~
Dim MyN um As In te ge r
Note Visual Basic recogni zes a seri es of events every ti me a form is opened. The Load
event is always the first event to occur, and the Form_Load event is the place to initi ali ze
any form -level variables. Any vari ables you don' t initi ali ze start out with the value O or, in
the case of strings, an empty stri ng.
The LostFocus event procedure for the Readout text box performs the data validation as
shown here :
Sub Readout_ LostFocus ()
Amt = Val(Readou t.Text)
If Amt < 1 Or Amt > 10 Then
Beep
Readout.Text = Str$(MyNum)
Else
MyNum = Amt
End I f
End Sub
When this procedure is invoked, the user has just changed the contents of the Readout text
box. The first step of this procedure is to convert the stri ng of digits in Readout to a numeri c
value:
Amt = Val(Read out . Text )
The procedure then tests Amt to see if it is within the acceptable range. If not, the procedure
performs these statements:
Beep
Readout.Text = Str$ ( MyNum)
The Beep statement produces a warning beep to indicate an error. The assignment statement
on th e next line resets th e contents of Readout to the previous acceptable va lue, stored in
MyNum .
If Amt is within range. then the procedure sets MyNum to the new value:
MyNum = Amt
To summar ize, the proced ure tests to see if the number entered is valid. If so, it assigns the
value to the form-level variabl e, MyNum . lf not , the display is restored by reading back the
va lue of MyNum.
Note The ASCII characters are a subset of the ANSI character set in Visual Basic. ASCII
characters include all the printable characters, the CTRL key combined with an A-Z
character, a few other standard characters such as ENTER (ASCII 13), and the BACKSPACE
key (ASCII 8). You can transform or cancel any of these keystrokes with the KeyPress
event. To have your code respond to a key that <loes not produce an ASCII character, use the
KeyUp or KeyDown event.
The KeyPress event uses one argument, KeyAscii. This argument represents the numeric
(ASCII) equivalent of a printable character. You must translate thi s argument if you want to
evaluate itas a character.
Here is a common sequence for doing things within a KeyPress event procedure:
1. Translate Key As e i i into a charac ter by using the Chr$ function, which returns a
one-character string.
2. Perform whatever operations or tests are appropriate with this string. Remember that the
relational operators (=, >, <, <=, and >=) ali work on strings and use alphabetical arder to
define "greater than" and "less than."
3. To change the character the control receives, translate the character back to numeric
format with the Ase function, then assign this result to Key As e i i .
To cancel the keystroke so that the control receives no character, assign O to Key As e i i.
Man y kind s of objects recognize the KeyPress event, but only text boxes and combo b0xes
di splay charac ters as typed. Therefore the third step above is relevant only to text boxes and
combo boxes.
The fo ll owing example translates characters to uppercase as the user types them; the
KeyPress procedure receives the key stroke, changes it to uppercase, and uses the Ase
function to change the character back to a number. This code assumes that Readout is a text
box:
Sub Readout _KeyPress (KeyAscii As Integer)
C$ = Chr$(KeyAscii) ' Convert to character.
C$ = UCase$(C$) ' Change character to uppercase .
KeyAscii = Asc(C$) ' Convert back to numeric .
End Sub
The first indented line changes the data format to string, and the third changes it back to
numeric again. The middle line does the real work of the procedure. It uses the U Case$
function to change the character to uppercase . (UCase$ has no effect on the character unless
it is a lowercase letter.)
The nex t exa mple demonstrates how to restrict keystrokes; if the character typed is not
within range , the procedure cancels it. The text box for thi s example is named EnterNums,
and the procedure prevents the text box from receiving any characters other than di gits:
Sub Enter Num s_KeyPress (KeyAscii As Inte ger)
C$ = Chr$ ( Key Asci i) ' Con ve rt to character.
If C$ < "0" Or C$ > "9" Then ' If out of range,
Key Ascii = 0 kill the character.
Beep ' Sou nd erro r s ignal .
End I f
End Sub
You can optimize exec ution speed sli ghtly by not translating Key As e i i to a string. Instead,
compare it directly to the numeric (Ase) values of various characters. For example, the
examp le above could be rewritten as:
Sub EnterNum s_KeyPress (KeyAscii As Integer)
If KeyAscii < Asc("0") Or KeyAsci i > Asc("9") Then
KeyAscii = 0 'Kill the character.
Beep ' Sound error signal.
End I f
End Sub
Then, cal! the MyVal Function procedure when you need to tran slate from string to number.
The procedure works by rep lacing the first comma with a point (.), and then passing the
res ulting string to the Val function. The intrinsic InStr function finds the position of the
comma, and th e Mid$ statem ent puts a point at that position . For more information on
strings, see the Language Reference, or:
An option button alw ays works as part of a group. Selecting an option button immediately
causes ali other buttons in the group to be cleared. Defining an option button group tell s
Visual Basic, " Here is a set of choices, from which the user picks one and only one."
Ali of the option buttons placed directly on a form (not in a frame or picture box) constitute
one group .
Note If you want to create more th an one group of option buttons , you must place sorne of
them inside frame s or picture boxes . Ali the option buttons inside any g iven frame constitute
a separate group. as do ali the option buttons inside a picture box. When crea tin g a separate
group thi s way, always draw the frame or picture box first , then draw the option buttons .
The Value property of an option button shows whether or not it is selected . This property is
True (-1) if the button is selec ted and False (0) if not. To selec t a button from within a
procedure. set its va lue to True:
Ame xButton.Value = - 1
The Click event occ urs when the user selects an option button at run time. Oncean option
button is selected, you can assume that it remains selec ted and that its Value property is set
to True (- 1) until the user selects a different option button.
The user se lec ts an option button either by c licking it or by tabbing to the button and
pressing the SPACEBAR. You also can cause a ~ li ck event by choos in g the button from within
code, as in thc previous code fragment.
Example The fo rm shown in Figure l l.3 uses option buttons to determine which of three number
sys tems (octal , decimal , or hexadecimal) to use. When the user selects a button , the number
d isplayed in the Readout text box is converted to the new number system. Thi s application is
a variation of the one at the end of the section on menus in Chapter l O, " Responding to
Commands ."
@ Use octal
O Use decimal
O Use hexadecimal
The code for this application is shorter than that for the rnenu-d1iven version for two
reasons: You don ' t have to write any code to move a check mark around, as you do with
menus, and the code in this version uses the Change event.
When you are designing an application , it 's often helpful to write down how the application
should respond to each event. Then it becornes clear how to write the eve nt procedures. This
application responds to events as follow s:
• Change event for the text box : read in the value (usin g the appropriate number sys tem)
and store it in a form- level numeric variable , CurrentNum.
• C li ck eve nt for the OctButton: output Current Num in octal.
• Click event for the DecButton : output CurrentNum in decimal.
• Click event for the HexButton : output CurrentNum in hexadecim al.
What 's key to this approach is the use of a form- level variable, Curren t Num . This variab le
represe nts the value of Readout in num eric form. The Change event keeps thi s value current,
so ali the Click event procedures have to do is output the number in the proper number
sys tem. Curre ntNummu st be declared in the Declarations section of the forrn code:
Dim Curre ntNum As Single
By default, the variable is initialized to O. That's an acceptable default, so there 's no need for
initiali zat ion code.
The Chan ge eve nt procedure checks to see which number sys tem (octal , decimal, or
hexadecimal) is in effect, and then it reads in the number. The number syste m is easi ly
determined from the state of the option buttons. This procedure is similar to the ReadV alue
procedure in Chapter I O, but it looks at the optionbutton.Va]ue condition rather than
menucommand. Checked:
Sub Readout_Cha nge ()
If OctButto n.Value Then
CurrentNum = Val ( "&O " + LTri m$(Readout .Text) + "&" )
Elself DecButton.Value The n
Current Num Val (LT ri m$(Readout.Te xt) + "&")
Else
CurrentNum Val("&H" + LTrim$(Re adout. Text) + "&" )
End I f
End Sub
The Val function is used to tran slate the string to a number, and can recogni ze octal,
decim al, and hexadec imal strin gs. The LTrim$ function strips the tex t of leading bl anks.
The "&O" prefix causes a di git string to be interpreted as octal; the "&D " prefix causes it to
be interpreted as dec imal; and the "&H" prefix causes it to be interpreted as hexadecim al.
The "&" suffi x spec ifies that the number is a long integer; thi s supports use of large r va lues.
The Cli ck event procedures for the option buttons are short. Ali they have to do is use th e
Oct$ , Str$. or Hex$ fun ction to display Cu rrentNum in the appropriate number sys tem:
Sub OctButton Click ()
Readout.Text = Oct$(CurrentNum)
End Sub
For more information on opti on button events, see the Language Reference, or:
You can have any number of check boxes, but they ali work independently of each othe r.
The user ca n have any number of check boxes selected at the same time.
Cli cking a check box at run time alternately selects and clears it; in either case, each click
action generates the Click eve nt for the box.
The Value property of a check box can be set to one of the following three values .
Setting of Value property Description
O Cleared . The check box is empty .
Selected . An X appears.
2 Grayed .
The fo ll owi ng exa mpl e uses a check box to determine whether or not to tran slate c haracter-,
to uppercase as they are typed. This example builds on o ne of the exa mples in the sec tion
·'C han g in g and Res tricting Keys trokes" earli e r in thi s chapte r.
The application has a check box and a text box , as show n in Figure 11 .5.
11 Character Converter aa
The appli cati on includes a KeyPress event procedure for the text box. The procedure tes ts to
see if the check box is selected. If so, it translates the keystroke to uppercase. Otherwi se, the
procedure makes no changes.
Sub Letters _KeyPress (KeyAscii As Intege r)
If ConvToUpper.Value = 1 Then
C$ = Chr $ ( KeyAsci i)
C$ = UCase$(C$)
KeyAscii = Asc(C$)
End I f
End Sub
When the user selects the check box, ali subsequent letters typed in the text box are
converted to uppercase. However, previously typed letters are unaffected. To make the
check box convert the case of all letters in the text box, you can program the Click event for
the check box.
When a Click event occurs, you cannot ass ume that the check box is selected as a result
(because the user also clicks a check box to clear it) . Therefore, the event proced ure has to
test for whether th e check box is selected:
Sub ConvToUpper_Click ()
If ConvToUpper.Value = 1 Then
Letter s.Text = UCa se $(Letters.Text)
End If
End Sub
For more inforrnation on check box eve nts, see the Language Reference , or:
A combo box control combines the fea tures of a text box anda list box. You can use thi s
control to enable the user to make a selection by typing text into the combo box or by
selecting an item from its list.
With the default setting (Style property set to 0), a combo box is a drop-down combo box.
The user can either enter text direc tl y (as in a text box) , or click the detached arrow at the
right of the combo box to open a li st of choices. Selecting one of the choices puts it into th e
text portian at the top of the co mbo box. The user al so can open the list by pressing
A L T + DO W when the control has th e foc us.
The two illustrations at the le ft o f Fig ure I J.7 show a drop-down combo box in its normal
state, and with its li st dropped do,, n.
= 1Porsche 111]
Combo Box Example
.
Mercedes
Rolls Royce
Setting th e Style property of a co mbo box to I specifies a simple combo box , in which th e
list is di splayed at ali times. The use r can still enter text directl y or selec t from the li st.
When you want to enable the user to choose onl y from a list, but you want to conserve
screen space, you can use a drop-down list box . A drop-down li st box looks like a tex t box
wi th an attached arrow, as show n at the right of Figure 11 .7. The currentl y-selected ite m is
di splayed in the tex t porti a n, and the user can change the selection by clicking the arro w and
choosing from a list that drops down.
To create a drop-dow n li st box, you draw a combo box and set its Style property to 2.
No te th at a co mbo box with its Style property set to O or 1 enables the user to enter choices
that are not on the li st. In contrast, a drop-down list box (a combo box with its Style pro perty
set to 2), does not permit the user choices beyond those on the li st.
Generall y, a combo box is appropriate when there is a list of suggested choices, and a list
box is appropriate when you want to limit input to what is on the list.
To pl ace ite ms in the li st or remove the m, use the Addltem and Removeltem meth ods
descri bed in the nex t sec ti on.
To access items in a list, yo u use the Text, List, Listlndex, and ListCount properties . Tex t is
usuall y the easiest to work with. Thi s property specifies the selected ítem in string fo rm at.
The List property provides access to all the items in the list, as explained in the secti on,
"Getting at the Contents of a List."
The important events for li st boxes are Click and DblClick; for combo boxes, Click and
Change.
Note Everythin g said in the nex t two sec ti ons, "Placi ng Items in a Li st" and "Gettin g at the
Contents of a List," applies to bo th li st boxes and co mbo boxes, except where oth erwise
noted.
The item is a string ex pression, and box is a list or combo box. To place a number in the lis t,
first convert it to a string. (If the number is a literal con stant, enclose it in quotation marks; if
it is a variable, convert it with Str$ or Format$) . The brackets indicate that index is an
opti onal argument. If included, index specifies where the new item is to be inserted in the
li st. An index of O represe nts the first position. If index is omitted, the íte m is inserted at the
end .
Note If the Sorted property is set to True (- 1), then Visual Basic always keeps th e items
so rted alphabeticall y, regardl ess of the order you place them there.
The follow ing example places "Chin a," " India," "USSR," and "USA" into the li st box
named Populations - and in that order:
Sub Form_ Load C)
Populations.Addltem " Ch ina "
Populations.Addltem "Indi a"
Populations.Addltem "U SSR"
Populations.Addl tem "USA"
End Sub
Whenever the fo rm is loaded at run time, the li st appears as shown in Figure 11 .8.
= ~ml ªª
'"India.
USS R
USA
But the next line of code inserts "The UN" into the first position, adjusting th e position of
th e other items downward:
Populations.Add ltem " The UN", 0
You can use the Addltem method at any time . Addltem gives yo u the abili ty to add it ems
to th e li st dynamically (i n response to user ac ti o ns). Yo u can also use the Removeltem
method to delete part of the list. The argumen t index specifies w hi ch item to remo ve:
box. Removeltem index
Usua lly. th e eas ies t way to get the val ue of the currentl y selected ítem is to use th e Text
property. This property has a string type. (If it contains a strin g of digits, use th e Va l
function to obtain the numbe r. ) With li st boxes, the Text property always co rresponds to
so rn e it e m in th e li st. With combo boxes , th e Tex t property conta ins whatev er is e nt ercd in
th e tex t-box portion of the co ntro l, so it can co ntain a string th at is not in th e li st.
Fo r example, the fo llowing code di spl ays information on th e United States if the " USA"
item from the last exampl e is selected:
If Po pulations.Text - "U SA" Then
PopDi sp lay . Te xt = "U SA ha s 250 milli on peopl e. "
End I f
lf yo u' re mainly interested in the relative p osition of the selected item, use the Li stlndex
property. The setting of thi s property is O if the top item is selec ted, 1 if the nex t item down
is selected, and so on. Thus, the code above can be rewritten to test fo r the value "USA,"
whi ch is in the fifth position:
If Populations . List ind ex - 4 Th en
PopDispl ay.Text = "USA has 250 mi llion peo pl e. "
End I f
Note In a combo box, if the user enters tex t directly rather th an selectin g from the list, the
value of the Listlndex property is - 1. This applies only to combo boxes with the Style
property set to O or 1.
The Li st property provides access to all items in the list. T hi s property co ntain s an array in
whi ch each element of the array is an item in the li st. Each ite m is represe nted in string form .
To refer to an item in the list, use this syntax:
box .List (index)
T he argument box is a reference to a list box or combo box , and index is th e position of the
item . The top item has an index of O, the nex t has an index of 1, and so on. For exa mpl e, the
fo llow ing state ment di spl ays the thi rd item (index = 2) in a text box:
Di s pla yBox .Tex t = Pop ul at i ons.List(2)
A recommended practice for list box events (especi all y when th e list box appears as part of a
di alog box) is to:
• Add a command button to use w ith the list box . The C li ck event procedure fo r thi s button
should m ake use of the list-box selec tion, carrying o ut whatever ac ti o n is appro pri ate fo r
yo ur application. ·
• Doubl e-clicking an item in th e li st should have the same effec t as selec tin g the ite m and
then clicking the command button. Thi s prov ides m ouse use rs with a ho rtc ut , ye t it
doesn' t depri ve keyboard users of esse nti al fun ction ality . T o implement thi s shortcut,
have th e Db!C li ck procedure for the lis t box call the C lick proced ure fo r the command
button.
For exampl e , suppose you have an appl icatio n w ith three co ntrols: a li st box (Popu lati o ns), a
command button (Di splayCmd) , and a tex t box (Po pDi spl ay) , as sho wn in Fi gure 11.9. Th e
lis t box is initia li zed as exp lai ned in the sectio n "P lac in g ltems in the Li st" earlier in thi s
chapter.
al Forml aa
China
India
USSR
USA
Figure 11.9 A list bo x, com mand button, and text bo x that work tog eth er
The Click event procedure for the com mand button di splays a different message depending
on the setting of Popul ation s.Tex t. The tex t box , PopDispl ay, is used to hold the message.
Sub Di splay Cmd_Cl ick ()
Se l ect Case Popul ati ons . lext
Case "Chi na"
PopDi splay .T ext = "Chi na ha s a bi ll i on peopl e ."
Case "I ndi a"
PopDis play .Text - " I ndia ha s over 800 mil li on peo pl e ."
Case "U SS R"
PopD is pl ay.Text - "USSR ha s 280 mi lli on peo pl e ."
Ca se "USA "
PopDisp la y.Text "USA ha s 25 0 millio n peop l e . "
End Se l ect
End Sub
You can also enable the user to displ ay the message by double-clicking one of the items in
the list; just have the Populati ons_Db! Click event procedure call the DisplayCmd_Click
procedure:
Sub Popul at i ons_DblC lick ( )
Di s pl ayC md_Click
End Sub
For more information on list bo x eve nts, see the Language Ref erence , or:
Mouse
LJ
13 ,<<. -·• • LJ <> G 1 Cancel
Visual Basic enab les you to use scroll bars the sam e way. With the Toolbox, yo u can create
your own hori zontal and verti cal scroll bar controls, as shown in Figure 11 .1 1.
1m Scroll Bars DD
... ..-
•
· · · · i- ~--.....-.tr-- Sera// box here
··· ~ ..
indicates mínimum
value .
.•.••. J~•~
· ~~-,t-- Scroll box here
l._•...
·I_IL--a'""-'-'-"'-~~'--'-"'===.:.:.i""'<'"t"""'
>...•...•... in die ates maximum
value.
A scroll bar rcpresents an integer va lue; the scro ll box shows w here the value lies relative to
the end poi nts of the range.
When th e integer is at the minimum value, the scro ll box moves to the leftmos t position (for
horizontal scro ll bars) or the top position (fo r vertica l scroll bars) .
Wh cn th c integer is al the maximum va lu e, the scroll box moves to the rightmo st o r bottom
position . S imil arl y, a value halfway between th e bottom ancl top of th e range pl aces th e
scroll box in thc midd le of th e scroll bar.
Y ou can set ali of these properties at design time. At run time, the Yalue property changes as
the user adjusts the scroll bar (unless you di sable the control), but the other properti es stay
the same unless you change them from within code.
In addition to using mouse clicks to change the scroll bar value, th e use r also can drag the
scroll box to any point a}ong the bar. The resulting value depends on the position, but is
always within the range from Min to Max.
Scroll bar control s show the relative qu antity visually , but do not report the ex act qu antity to
the use r. Therefore, the user doesn ' t know exactly what value he or she is entering. One way
to pro vide thi s information is to place a text box next to the scroll bar and print out the value
whenever the scroll bar changes. The code that updates the text box should be placed in the
Change e vent procedure for the scroll bar.
For example, suppose you have a scroll bar narned Fue! and a tex t box named Fue!Readout.
The Change e vent procedure for the scroll bar displays the preci se value in Fue!Readout:
Sub Fuel _Chang e ( )
Fue l Readout. Tex t - FormaU(F uel .Valu e)
End Sub
Green
Blue
The scroll bars are a 11 set to the val ucs 4 and 32 for the Smal lChange and LargeChangc
properties. Othcr properties are set as fo llows.
Control CtlName property Min property Max property
Top scrol l bar RcdBar o 255
Second scro ll bar Green Bar o 255
Third scro ll bar BlueBar o 255
Textbox Readout
The Change proccclure for each of the scroll bars responds by calling a general procedure,
DoColor, th at rccalculates the color.
Sub RedBar_Change ( l
DoColor
End Sub
The DoCol or procedure uses the values of the three scroll bars, combines th em with the
RGB function , and assigns the res ult to the background color of th e tex t bo x. As explained
in Chapter 13, "Creating Graphical Effects," the RGB function takes red, green, and blue
input values, each runnin g from O to 255.
Sub Do Co l or ()
Readout . BackColor - RGB (Re dBar . Value, GreenBar . Valu e. BlueBar. Valu e)
End Sub
For more information on scroll bar events, see the Language R ef erence, or:
The brackets indicate th at ali arguments but the first are optional. The comm as are argume nt
separators: You use them only to separate arguments orto show that an arg um ent i skipped.
Thus, the mínimum syntax of InputBox$ just takes one string, whi ch is inte rpreted as the
prompt$ argument.
The first three arguments are ali strings: prompt$ is the prompting tex t th at appea rs in the
text box, tille$ is the text that appears in the title bar, and defa1tlt$ is th e clefa ult res ponse
di splayed in the text box. The last two arguments, xpos and ypos, give the cli sta nce in twips
from the left edge and top edge of the screen, respectively. (A twip is 1/20 o f a point. )
The fo ll owing state ment creates the res ult shown in Figure 11. 13.
User$ InputBox$ ( " Enter your name. " , " Input Box " )
Ente r your na me . OK
Cancel
The resultin g dialo g box is modal. (A modal dial og box must be closed before the user can
switch to another forrn or di alog box.) However, the user can switch to a completely
differe nt applicati on in W indows.
When the user clicks the OK button or presses ENTER, the lnputBox$ function return s
whatever is in th e tex t box . If the user clicks Cancel, the n lnputBox$ returns an empty
string ('"' ).
For more info rmati on on how screen coordin ates work (includin g the twips measurement
system), see Chapter 12, '•Displ ay ing and Printing ln for mati on," and Chapter 13, "Creatin g
Graphical Effects." For mo re in formation on InputBox$. see the Language Ref erence, or:
It's easy to use Visual Basic to present simple messages or unformatted numbers . Many of
the applications and code fragments of previous chapters display this kind of data.
But as your applications become more sophisticated and polished, you' ll want to take
advantage of the tools Visual Basic offers for selecting fonts, formatting tables, and
changing number formats. You can even include code in your applications that automatically
adopts the number, date, and time format for the user's country (using the Format$
function) . You also can send text and graphics to the printer using the Printer object.
This chapter presents the variety of ways you have to display information . Toe main sections
· is chapter are:
emporary lnformation with MsgBox
146 Part 3 Application-Building Techniques
The argument msg$ is a string that contains your message. The other arguments govern
features such as dialog box title and number of command buttons. You also can use the
MsgBox function to return a va lue indicating which button the user selected.
The following event procedure uses the MsgBox$ statement to di splay the message shown
in Figure 12. l when the user clicks a blank portion of the form .
Sub Form_Click ()
MsgBox "What we have here i s a fail ure to communicate."
End Sub
1 [óKj 1
Figure 12.1 MsgBox Example
This dialog box remains on the screen until the user clicks the OK button or presses ENTER.
Then Visual Basic continues execution of the next statement in the code.
The dialog box is modal. This means that users can not swi tch to another forrn in your
app lication until they first close the dialog box .
For more information on the MsgBox statement and function , see the Language Reference,
or:
A Temperature Converter
The application shown in Figure 12.2 converts temperatures between Celsius and Fahrenheit
temperatures. It features three labels, a text box, and two command buttons. The user enters
a temperature in the text box at the top, and it is converted to Fahrenheit or Celsius,
depending on which of the two command buttons is clicked. The converted temperaiure is
displayed in what looks like a text box labeled Output; it's actually a label that has a blank
Caption and BorderStyle set to 1.
Input: 1 Conve,I lo F. 1
Oulpul: 1 Converl lo C. 1
The application could use a text box instead of a label to display the converted temperature.
However, information displayed in a text box can be changed by the user, which isn' t
desirable in this case. A !abe! with a border looks like a text box , but the information it
displays can't be directly changed by the user.
There is a way to prevent the user from changing text displayed in a text box: set its Enabled
propen y to False. However, once that 's done, text in it would be grayed.
As wi th many of the other exarnples in this manual, the proced ure above fo ll ows a standard
approac h: Convert the characte rs in a text box to a numeric value. pe rform ca lc ulat ions on
the value, the n convert the val ue to a tex t string and display it. The Click procedure fo r
ToDegreesC takes the sam e approach , but performs the reverse calc ulation :
Sub To DegreesC_Click ()
Deg reesF = Val(InputTemp.Text )
DegreesC - (DegreesF - 32) * 5/9
OutputTemp.Caption - Format$(DegreesC)
End Sub
Note that in both procedures DegreesC and DegreesF are two local vari ab les represe ntin g
Ce lsius anct Fahrenhe it quantities, respectively. Because th ey are not ex plicitl y declared ,
they have the default data type, Single.
For more info rm ati on on the label control, see th e Language Reference, or:
Most types of objects can display sorne kind of text, including forms, text boxes, labels, list
and combo boxes, and any control with a Caption property. (This includes command
buttons, labels, check boxes, and option buttons.) In addition, all of the font properties apply
to the special Printer object introduced later in this chapter.
The exact effect of the font properties depends on the technique used to display text:
• If the text is specified by a property (such as Text or Caption), then a change to a font
property applies to the entire contents .
Labels, text boxes, frames, buttons, check boxes, and all the file-system controls use a
property to specify text. None of them supports the Print method.
• If the text is displayed by the Print method, a change to a font property affects
subsequent uses of Print, but has no effect on previously printed text.
Only forros and picture boxes support the Print method.
Consequently, text boxes and labels cannot display text that mixes fonts. If you need to mix
fonts (for example, you want to make sorne words bold but leave others in normal style),
then create a picture box and use the Print method to display text. The next section ,
"Printing to Forms and Picture Boxes," explain s how to use Print.
An additional font property, FontTransparent, is supported for form s and picture boxes only .
The settings available for each of the properties are listed in the Settings box at the middle of
the Properties bar. lf you use a setting from the list, you don ' t have to worry about picking
an unavailable size or typing a font name incorrectly .
You can set any of the font properties at design time (by using the Properties bar) or at run
time. For example, th e followin g statements set various font properti es for a control named
Labell :
Labell . Foílt Name = "M odern" Chaílge foílt to Moderíl.
Lab ell . Fo ntBold = - 1 Tur íl Oíl bold.
Labell.Foíltitalic = - 1 Turn Oíl italics.
Lab ell . Foílt Uíld er liíl e = 0 ' Remove underliíl e.
The order of selection is import an!. becau se not all fonts support ali font variations (bold,
itali c, and so on). Set th e Font Na me property first. The Boolean font properties are not
mutu ally exclusive. They ali can be se t to True, all set to False, or set in any combination of
True and False.
For more information on fo nt properties, see the Language Reference, or:
The object is optional; if omitted, the Print method applies to the form to which the code is
attached (the curren t forrn). Por example, the following statements print different messages
to MyForm, Picture 1, and the current form:
MyForm. Pr i nt "Thi s is a form."
Picturel.Print "This is a picture box."
Print "This i s the current form."
If X contains the value 2 and Y contains the value 7, the statement produces this output:
The value of X is 2 and the value of Y is 7
By default, each Print method prints the text and moves to the next line. If there are no
items, Print simply skips a line. A series of Print statements (for a picture box named
Picturel ) automatically uses separate lines:
Picturel.Print "Thi s is line l."
Picturel.Print "Thi s is line 2. "
Yet by placing a semicolon at the end of the first statement, you cause the output of the next
Print statement to appear on the same line:
Pi cturel. Pri nt "Th i s all appears ";
Picturel.Print "on the sa me line."
You also can set drawing coordinates directly by setting the CurrentX and CurrentY
properties for any given forrn or picture box. For example, these statements reset the
drawing coordinates to the upper-left comer for Picture 1 and for the current fonn:
Picturel.CurrentX = 0
Picturel.CurrentY = 0
CurrentX = 0
CurrentY = 0
Any new text you print is overlaid on top of whatever text and graphics are already there . To
erase text selectively , draw a filled-in box using the background color, as explained in
Chapter 13, "Creating Graphical Effects."
By default, forms and picture boxes use a coordinate system in which each unit corresponds
to a twip (1,440 twips equ al an inch, and approximately 567 twips equal a centimeter). Thi s
is a logical twip - the length of an object that is one twip long when output on the printer.
For more information on coordinate systems, see Chapter 13; the Language Reference; or:
If the string contains embedded carriage-return characters (Ch r $ ( 13 ) ) , then the text
corresponds to multiple lines, and TextHeight returns the height of the number of Iines of
text contained in the string. If there are no embedded carriage returns, TextHeight always
returns the height of one line of text.
One way to use this method is to set the CurrentX property to a particular line. For example,
the following statements set the drawing coordinates to the beginning of the fifth line:
Current X TextHeight("sampl e " ) * 4
CurrentY = 0
Assurning there are no carriage returns in the sample text, you would use this syntax to set
CurrentX to the Nth line:
CurrentX = [object .] TextHeight(sampletext) * (N - 1)
The brackets indicate that object is optional; if object is omitted, the method applies to the
current form . The object can be either a form or a picture box.
The TextWidth method returns the width of a string, taking into account the object' s font
size and style. This method is useful for deterrnining right alignment; if a line of text is about
to run off the right edge of the form, you skip to the next line by using the Print method
with no arguments. The TextWidth method helps you determine if the width of the string is
larger than the width of the form (or picture box) .
For example, the following Sub procedure takes a word , contained in the string S, and
determin es whether to print the word on the current line or to advance to the next line first :
Sub PutAWord (S As String)
If Te xtWidth(S) + CurrentX >= Sc aleWidth Then
Print
End I f
Print S; " " . .
End Sub
The ScaleWidth property gives the interna! dimensions of the form - the width of the area
within the borders of the frame . (As you ' ll see in Chapter 13, "Creating Graphical Effects,"
ScaleWidth also can be used to set the coordinate system .) Forms , picture boxes, and most
other types of objects have both a ScaleWidth anda ScaleHeight property.
For more information on the TextHeight and TextWidth methods, see the Language
Reference, or:
11
First n ame Last Name
Forml
Phone numb er
aa
Jon athan Vand erbilt 555- 4444
Arle ne Lill ega rd 555-7891
J oa nn e Buchanan 99 -11 -12345
Figure 12.3 sho ws a l 0-point System fon t. Like most Windows fonts, System is a
proporti o nal fon t and includes characters of vary ing widths. In this example, each print zone
has th e same width as 14 average System 10-point charac ters . When settin g up tables,
remember that letters such as "W" take upa little more than one column, and letters like " i"
take upa little less than one column.
For example, the following statements print a message in the System font starting at column
5. Each column is the size of an average character in the font you choose:
Picturel.FontName = " System "
Pictur el.Print Tab(5); " This me ssage starts in column 5."
Figure 12.4 shows a table printed to a form. The first tab, at column 2, indents the Iines
slightly from the left edge of the picture box. The tab at column 22 sets the position for the
"Description" heading and the text printed below it.
!ZD Forml aa
Fi lename De scription
Column(2) Column(22)
Figure 12.4 Using tabs in a table
For more information on the Tab function and using it with the Print method , see the
Language Reference, or:
Number Formats
The Format$ function , like the Str$ function , converts numeric values to strings . But with
Format$, you have more control over the appearance of the string . For example, you can
speci fy th e numbe r of decimal places, leading or trailing zeros, and currency formats.
The syntax of the the Format$ fun cti o n is:
Format $( 1111meric-expression l,frnt$ ]) ;
T he argumcn t 11umeric-expressio11 spec ifi es a number to con ve rt, andfmt$ is a string made
up of sy mbo ls th at show how to format the number. The most commonly used symbol s are
listed in th e fo ll owin g table.
Symbol Description
o Digit placeholder; prints a trailing or leadin g
zero in thi s positi o n if appropriate .
# Digit placeholder; never prints trailing or
leading zeros.
Decimal place holder.
Thousands se parato r.
- + $ ( J :--pact' Literal character; di spl ays each o r th ese
charac ters exac tl y as typed into th e form al
string .
Severa! examples are li s tecl be lo w. Th ese number con vers io ns ass um e th at the country in thc
Wind ows Con tro l Pane l is se t to "U nit ed States.'·
Format$ example Result
Format$(83 J 5.4, "00000.00") 083 15.40
Format$(83 l 5.4 ... #####.##") 83 15 .4
Format$ s uppo n s man y other spec ial characters. For more inform ation , see the Lang11age
Ref erencl:'. or:
The sy mbol for the decim al separator is a period (.) and the sy mbol for the thou sands
separator is a comma (,). But the character that' s actually di splayed as a decimal separator or
a thousands separator depends on the country set in the Windows Control Panel.
Country Format$ syntax Result
Sweden Format$(7300, "0,000.00") 7.3 00,00
United Kingdom Format$(7300, "0,000.00") 7,300.00
Germany Format$(7300, "0,000.00") 7.300,00
By usi ng the Now function with the format "ddddd" and "ttttt," yo u can print th e current
date and time in a format appropriate for the country set in the Windows Control Panel.
Country Format$ syntax Output
Sweden Format$(Now, "ddddd ttttt") 90- 12-3 1 18.22 .38
United Kingdom Format$(Now, "ddddd ttttt") 12/3 1/90 18:22.38
Canada Format$(Now , "ddddd ttttt") 90- 12-3 1 18 :22:38
United States Format$(Now, "ddddd ttttt") 12-31-90 6:22:38 PM
For more information on date and time funct ions, see the Language Referen ce, or:
The Prinler object supports ali of the graphics methods presented in Chapter 13, "Creating
Graphical Effects," and can be used to display lines, circles, and points .
The Printer is the name of an object in Visual Basic that has all the font properties described
earlier. For example, the following statements send bold Modem type to the printer:
Printer .Fo ntName = "Modern"
Printer.FontBold = -1
Printer .P rint "Bold Modern type appears on printer."
Because these statements set FontBold to True (-1), subsequent statements also print bold
text on the printer unless you turn off the bold font :
Printer.FontBold = 0
You can set CurrentX and Current Y properties for the Printer object, justas you can with
forms and picture boxes. With Printer, these properties determine where to position output
on the curren t page. Thus, the following sta tements set drawing coordinates to the upper left
of the current page :
Printer.CurrentX 0
Printer.CurrentY = 0
When -printing longer documents, you can specify where you want a new page to begin
using the NewPage method. When you are fini shed creating a print document, specify the
EndDoc method. This advances the page and causes all pending output to be sent to the
spooler. (If you return to design time, Visual Basic issues an EndDoc call automatically.)
For example:
Printer.Print "Thi s is pag e l. "
Printer.NewPage
Printer.Print "Thi s is page 2 ."
Printer . EndDoc
After you use the EndDoc method, you can start printing another document. The first page
of the new document is assigned page number 1. This page number isn't automatically
printed, but Visual Basic tracks the page .number internally. You can access this number by
using the Page property . For examp lc, if yo u wa nt to print a header at thc top of cve ry pagc
of a budget report:
Header$ = "Monthly Budget Summary"
Printer.Print Header$ + Printer.P age
Printer.NewPage
Printer.Print Header$ + Printer . Page
PageNo = Printer.Page
MsgBox "Y ou r document contains " + PageNo + " pages. "
Printer.EndDoc
Printing Forms
Yo u also can send output to the printer by produci ng the output you want on a form , and
then printing the entire form using the PrintForm meth od . This method is very simple. You
can precede PrintForm by the name of a form. lf you omit the form name, Visual Basic
prints the current form. The sy ntax is:
[form.]PrintForm
PrintForm prints the entire form, even if part of the form is not visi ble on the screen. If a
form contains graphics, however, the graphics print only if the form's AutoRedraw property
is set to True (-1).
The PrintForm method always sends pixels on the form directly to the printer. As a
consequence, you may not get the hi ghest resolution when you use PrintForm . For
example, you could send text to a printer by first printing it on a form , then calling
PrintForm :
Print "Here is so rne text . "
PrintForm
However, if the printer has higher resolution than the monitor, then thi s statement prints the
same text with better clarity:
Printer.Print "Here is sorne text."
For more information on the PrintForm method, see the Language Reference, or:
Animated, graphical applications are among the most appealing and exciting to the user.
But with traditional programrning environments, they are difficult to create.
Not so with Visual Basic, which provides severa! ways to produce graphical effects in your
applications. You can move objects around on the screen , make them appear and di sappear,
even change their size - all with simple and easy-to-leam statements. The Visual Basic
language also provides statements that enable yo ur applications to draw circles, lines, boxes ,
and other shapes.
With th e~c fca tures yo u' ll be ab lc to writc game::,, animatcd cffcct -, co lorful ::, imulatiom,, or
any app lication where graphical effects could enhance the user's presentation .
This main sections in this chapter are:
• Adding Pictures to Your Forms
• Moving Controls Dynarnically
• Resizing Controls Dynarnically
• Showing and Hiding Controls
• Adding and Removing Controls
• Settin g an Object's Coordinate System
• The Fundamentals of Drawin g
• Drawi ng Lines and Shapes
• •• • •
••••
•• ••••
•• ••• •
•
_,...,,•~.
_,/",:.·,•.J
.. -:· .-?~
• • •
••••
. .o:--.,.
.{'.....·, ·•.•- J
~:::•:. ->·
¡¡:-·_••-~/
4-:i.--
162 Part 3 Application-Building Techniques
These files can come from Microsoft Windows Paintbrush (incl uded with Windows 3.0),
other graphics programs, or clip-art libraries.
You use different techniques for adding a picture to a form or picture box, depending on
whether you do it at design time or run time .
Once you've set the Picture property for a form or picture box (either by loading a picture
or pasting one), the word displayed in th e Settings box is "(Bitmap)," "(Icon) ," or
" (Metafile) ." To change the setting, loador paste anot her pi cture. To set the Picture property
to "(None)" again, double-click the word displayed in the Settings box and press the DEL
key.
Y ou can load a new picture file onto a form or into a picture box whenever you want.
Loading a new picture completely replaces the existing picture, although the source fil es
of the pictures are never affected.
• Copy a picture from one object to another.
Once a picture is loaded or pasted onto a form or into a picture box, you can assign it to
other forms or picture boxes at run time . For example, this statement copies a picture
from DisplayBox to another picture box named DisplayBox2:
DisplayBox2.Picture = 0isplayBox . Picture
You can both load a picture and assign it to another object by using both the previous
statements within one procedure:
DisplayBox.Picture = LoadPicture ( " c : \p i cts\ca rs.bmp")
DisplayBox2.Picture = DisplayBox.Picture
Note If you loador paste pictures from fil es at design time, the pictures are saved and
loaded with the form. When you create an .EXE file , you don't need to give your users
copies of the picture files; the .EXE file itself co ntains the images. In contrast, to load
pictures at run time with the LoadPicture function, you mu st supply the picture fil es to your
users along with your application. For this reason it's often better to loador paste pictures at
design time. Your application can then copy pictures from one object to another, as
described above.
Another way to set the Picture property is to use the Clipboard object. For more information,
see Chapter 18, "Interacting with the Environment"; the Language Reference; or:
If you want a picture box to automatically expand to accommodate a new picture , se t the
AutoSize property for the picture box to True (-1 ). Then when a picture is loaded or copied
into the picture box at run time, Vi sual Basic automatically expands it down and to the right
enough to display ali of the picture. (The picture box is visible only up to the edges of the
form where it resides, however; if the image you load is larger than that, it appears clipped
because the form size doesn ' t change.)
Y ou also can use the AutoSize property to automatically shrink a picture box to retl ect the
size of a new picture .
Forms do not have an AutoSize property, and do not automatically enlarge to display ali of a
picture.
Figure 13 .1 shows so rn e sa mpl es of the Icon Library. To see all of the pictures in the Icon
Library, refer to Appendix B, '·Jcon Library," or use the IconWorks sample applicati on
incl uded with Visual Bas ic.
11 forml . Da
[Q m 1
~ ~
m ~ ii .
cm
Figure 13.1 Samples from the Visual Basic lean Library
mi Forml aa
Figure 13.2 lcons MAIL16A.IC0 and MAIL16B.IC0 from the lean Library
To create a toggling effect, first draw three picture boxes on a forro at design time. Set th e
BorderS tyle property to O for the first one, and name it Mailbox. Name the other two
NoMail and Mai!Here. Set the Picture property for NoMail to the mailbox icon with its flag
down (the icon file is named MAILI6A.ICO) . For MailHere, set the Picture property to th e
icon with its flag raised (MAIL16B.ICO). Set the Visible property to False (0) for both
Mai!Here and NoMail ; you want to use the images stored in those controls, but you don ' t
want them to be visible on the form.
lf you are using mailbox icons in a mail application, you probably want a Form_Load
procedure that checks to see whether there are messages awaiting the user, and sets the icon
accordingly. In this case, use a Form_Load procedure that sets the Picture property for th e
Mailbox control to the ico n with the flag down :
Sub Form_ Load ()
Mailbo x.Pict ur e = NoMail.Picture
End Sub
Now when you run the application and click the Mailbox picture box, it switches betwee n
the icon with its flag down and the one with its flag up.
For more information on the picture box control and using graphics in your app li cations:
' Top
... .... ·· · ····-·· 1- - -¡A
- Bu-tt-on- !- - - - - - -- - - - +-
The Left property is the distance between the upper-left corner of the control and th e left
side of the for m. The Top property is the distance between the upper-left corner of the
control and the top of the form.
You can move a contro l by changing the settings of its Left and Top properties with
assignme nt statements such as these:
Textl.L ef t = Text l.Left + 200
Textl.T op = Textl.Top - 300
Howeve r. tha t woul d produce a jerky effect, as the control first moves hori zo ntall y and th en
vert ically. In contras t, using the Move meth od produces smooth di agonal movement. The
syntax for the Move method is:
fobjec1 .]Move left [, top[, width [, height]]]
The ohject is th e form or control to be moved. lf object is omitted, the method appli es to th e
current fo rm ; th at is, th e current form gets moved. The arguments left and top are th e new
settings fo r th e Left and Top properti es of object, while width and height are new settin gs fo r
its Wi dth and Height properties. Onl y left is required, but to specify any oth er argum ents,
yo u mu st spec ify ali arguments that appear in the syntax before the argument yo u wa nt to
<; rc ci f\ ·
The fol lowing state ments move th e contro l named Tex tl :
Textl.Move 100. 200
Textl.Move Textl.Left + 100 , Textl.Top + 100
The first statement moves it to the coordin ates ( l 00, 200). The second statement moves it
relati ve to its current position .
By default , ali Visual Basic movement, sizing, and graphical-drawing statements use a unit
of one twip. A twip is 1/20 of a printer's point (1,440 twips egua] an inch, and 567 twips
egua! a centimeter). These measurements apply to how large an object will be when printed .
Actual physical distances on the screen vary according to the monitor size.
In the section "Setting an Object' s Coordinate System" later in this chapter, yo u' 11 learn how
to select units other than twips. For now, just use the default scale.
ID Forml DD
\Click H ere j
The name of the control is MyButton . The Caption property is set to "Click Here."
There is one event procedure, for the command button 's Click event:
Su b MyButt on_Click ()
MyButt on. Move MyButton.Left + 500 , MyButton.Top - 500
·End Sub
You ca n ex periment with different amounts by building this application and then ed itin g the
line of code . lnstead of 500 twi ps , try 50, 700, or 1,000.
For more information on the Move method, see the Language Reference, or:
Hei ght and Width apply to all forms and all controls except timers and menus, while
AutoSize applies only to labels and picture boxes.
In thi s example, a _command button named Command1 grows larger each time the user · -
clicks it:
Sub Co mmandl _Click ()
Co mmandl . Height = Commandl.Height + 300
Co mmandl . Width = Commandl. Wi dth + 300
End Sub
Al i co ntrol s exce pt tim e rs have a Vi sihl e property . Setting th e Vi sible propert y to Fa lse (0)
makes the co ntrol "disappear,.. eve n thou gh it is still loaded in memory . For exampl e, thi s
statement makes a co ntro l named Text I disa ppear:
Textl. Vi sible = 0
The next statement makes the control reappear by setting the Visible property to True (- 1).
Because Textl was not actually deleted from memory , it automatically reappears with ali its
old settings (unless you've changed sorne of the property settings in the meantime).
Textl.Visible - - 1
You also can use a single statement to hide a control if it's visible and show it if it's hidden .
The statement takes advantage of the fact that the Visible property is Boolean-it' s either
"on" or "off' - and toggles it between the two settings:
Sub Commandl_Cli ck ()
Textl.Visible - Not Textl.Vi s ible
End Sub
You can use similar code to toggle othcr Boolean properti es.
i:=I (/ Forml aa
8 Cmd(O)
•• Cmd(l ) Cmd(2)
Figure 13.5 A control array ofthree command buttons
The Index property distinguishes one element of the control array from another. When one
of the co nt ro ls in th e arra y recogni zc1., an e, cnt, Vi sual Basic ca lIs a com mon event
procedure and passes an additional argument (the Index property) to identify wh ich of the
controls actuall y recognizes the event.
For example, the first line of the Cmd_Click procedure is :
Sub Cmd _Click (Index As Integer)
If Cmd(O) recognizes the event, Visual Basic passes O as th e Index argument. If Cmd( l)
recognizes the e vent, Visual Basic passes l as the Index arg umen t.
A control array has at least one element , but can grow to as many as 255. (There is a limit to
255 controls to a form .) Elements of the same control array have their own property settings,
but share the same code. Think of an elemen t asan "instance" of the array. When yo u load a
new element of the control array , the new e lement inherits any pre-existing event
procedures .
Without the control array mechanism, dynamically creating new controls is not possible. A
completely new control does not have any event procedures. Control arrays solve thi s
problem, because each new control uses the cornmon event procedures already written for
the array.
You can create a co ntrol array in one of two ways at design time:
• Set the Index property. usin g the Properties bar.
• Give two control s th e same name. (They mu st have the sa me type .) Vi sual Bas ic
automatically creates a control array and gives these controls the indexe O and 1.
The procedure in the next sec tion uses a control array to create any number of new controls.
When yo u load a new clemcnt of a co ntrol array. ali the property settings exce pt for Vi sibl e,
lndex , and Tabindex are copied from th e lowest ex isting element in the array. As a re sult ,
the previous code makes al I th e control s the same size, and stacks them ali in one place.
A lso, because new control s are crea ted with the Visible property set to False (zero), none of
th e m is visib le (even thou gh th e text box you've drawn is).
The following code ass um es you · ve created a text box named Textl and set its Index
property to O. U pon loading of the form, the procedure loads new text boxes, places them
apart vertically , and turn s on the Visib le property of each.
Sub Form Load()
Far I = 1 to 10
Lo ad Textl ( I )
Textl(I).Top = Textl(I - l).To p + 500
Textl(I).Vi s ibl e = - 1
Textl(I).Text = "Textl( " + Format(I) + " ) "
Next I
End Sub
Note Visual B asic generates an error if you attempt to use the Load statement with an
index number already in use within th e array.
You can use the Unload statement to remove any control created with Load . Howeve r,
Unload cannot be used to remove controls created at des ign time, whether they are part of a
control array or not.
The terms "coordinate sys tem" and "scale" are interchan gea ble. You set the coordin ate
sys tem for a particul ar object (form or picture box control) by using the objec t's scale
properti es and by usin g the Scale method. You can set a scale in one of three d ifferent ways:
• Create a c usto m scale
• Select one of severa! standard scales
• Reset to the default scale
The nex t four sec ti om, cxpléiin l 1u v.. to se t c ustom, stand ard, and defa ult ~cale~ .
These stateme nts se t the value of the upper-lefl comer for a pi cture box named
GraphicsArena:
Graph icsArena . ScaleLeft = 100
GraphicsArena.ScaleTop = 100
These stateme nts define the upper-left co rn eras (100, 100). A ltho ug h the stateme nts don ' t
direc tl y ca use any physical change, they alter the effec t of s ubseq uen t statements. For
exampl e, a s ubsequ en t statement th at sets a contro l" s Top property to 100 places th e object
at the ve ry top of its contain er.
The Sca leW idth and ScaleHeight properties define units in terms of the c urrent w idth and
height of the drawing area. For examp le:
ScaleWidth = 1000
ScaleHeight = 500
These statements define a hori zontal unit as 1/1 ,000 of th e curren t inte rn a] wid th of th e form
and a vert ical unit as l /500 of the current interna! he ig ht of th e form . 1f th e fo rm is la ter
res ized, th e units remain the same .
Note ScaleWidth and ScaleHeight define units in terms of th e inte rna] d imensio ns of the
object - th ese dime ns ions do not inc lu de the bordcr thickness . Thus , ScaleW idth and
ScaleHeight always refer to the amou nt of room uva il ab le inside th e object. The di st in cti on
between interna] and extern a! dimension s (specified by Wid lh and Heigh t) is particul arl y
important wi th fo rm s, w hi ch can have a thi ck bordcr. T he un its can a lso differ: Widlh and
He ight are always expressed in tem1s of the cu11wi11er 's coordin ate sys tem ; ScaleWidth and
ScaleHeight determ in e lhe coordin ate system or the objec t itse lf.
A li four of th ese scale properties can in c lud c rractions , and th ey a lso ca n be ncga ti ve
numbers. Nega ti ve sc ttings for the ScaleW id th and Sca le He ig ht propert ies change th c
orie ntation of th e coord in ate sys tem.
The scale shown in Figure 13.6 has ScaleLeft, ScaleTop, ScaleWidth, and ScaleHeight ali
set to 100.
11'
100,100
As Y ScaleLeft = 100
increases, Sea/e Top = 100
position ScaleWidth = 100
moves ScaleHeight = 100
down.
200,200
11
Note that coordinates increase in value as yo u run from top to bottom, and from left to right.
If you want to change thi s scale so th at coordinates increase as you go from bottom to top,
then you set ScaleTop to 200 and ScaleHeight to - 100, as shown in Figure 13.7 .
As X increases, position moves right.
11' •
100, 200 200,200
As Y ScaleLeft = 100
in creases, Sea/e Top = 200
position ScaleWidth = 100
moves up. ScaleHeight = -100
100,100
•
Figure 13.7 Scale with negative ScaleHeight setting
The values of xl and yl determine the settings of the ScaleLeft and ScaleTop properti es. Th e
differences be twee n the two x coordinates and the two y coordinates determine the setting
of ScaleWidth and ScaleHeight, respectively. For example, suppose you set the coordinate
system fo r a form by settin g end points (100,100) and (200,200):
Scale (100, 100) - (200, 200)
Thi s sta1emen1 defines th e fonn as 100 unit <; wicle and 100 units hi gh . With thi s scale in
place, the follow in g statement moves a control exactly o ne-fifth of the way across the form :
Mov er.Left = Mover.Lef t + 20
Specifying a valu e of x2 >xl , or y2 >yl , has the same effect as settin g ScaleWidth or
ScaleHeight to a negati ve va lu e.
All of th e mode s above , except for O and 3, refer to printed le ngths. For example, an item
th at is two unils lo ng in the ce ntimeter system is two centimeters w hen printed.
Setting a value for ScaleMode causes Visual Basic to redefine ScaleWidth and ScaleHeioht b
so that they are consistent with the new scale. Setting ScaleWidth or ScaleHeight directly
causes ScaleMode to be set to O.
As we ' ve seen in the previous section, "Setting an Object's Coordinate System," each
drawing area has its own coordinate system that determines what units mean. In addition ,
every drawing area has its own complete set of graphics properties.
Persistent Graphics
When a window is moved overa form, temporarily hiding it, and then is moved away again,
sorne of the contents may need to be redisplayed. If there are lines, circles, or text on the
form, you usually want them to reappear exactly as you placed them there. Thi s is what is
meant by persistent graphics.
You can make Visual Basic handle this detail automatically, but there is a cos t in memory.
Eac h form and picture box has an AutoRedraw property . AutoRedraw is a Boolean (i nteger)
property that when set to True (-1) causes graphics output to be saved in memory .
Yo u can use computer memory more efficiently by setting thi s property for forms and
picture box controls:
• When the AutoRedraw property of a resizable form is set to True, Visual Basic creates a
memory im age equal in size to the entire screen. Sav ing an image thi s large enables th e
application to retain graphics output even if it is drawn outside the current form size;
when the form is maximized, all the graphics output appears .
• When the AutoRedraw property of a picture box is set to True, Visual Basic creates a
memory image exactly the same size as the picture box. Graphics output drawn outside
the picture box never appears later, even if the size of the picture box changes.
If you want to conserve memory, create a picture box for all drawing effects and leave
AutoRedraw set to False (0) for the form .
Altematively, you can leave AutoRedraw set to False for the form and all its picture boxes,
and then manage graphics redrawing directly . You can include code that redraws ali lines,
cire les, and points as appropriate when the form or picture box recogni zes a Paint event
Thi s approach usually works best when you have a limited amount of graphi cs th at you can
reco nstruct easily.
A Pa int event procedure is called whenever part of a form or picture box needs to be
redrawn - fo r example, when a window temporarily covers the object and moves away , or
when resizi ng causes graphics to come back into view. If AutoRedraw is set to True, the
objec t' s Paint procedure is never called.
You can change the setting of AutoRedraw at run time. If AutoRedraw is False (0), graphics
and output from the Print method are written to the screen only, not to memory . If you clear
the object with the Cls method, any output written when AutoRedraw was set to True does
not get cleared. This output is retained in memory , and you must set AutoR edraw to True
aga in to clear it.
In addition, each form and picture box has ali of the scale pro perti es described earli er, in the
section "Setting an Object' s Coordinate System ," and the fo nt properti es desc ribed in
Chapter 12, "Displaying and Printing Informati on."
You' ll see how to use most of these properties later in thi s chapter. But there are two
properti es yo u' ll probably want to use ri ght away: BackCo lor and ForeColor. BackC olor
paints the background of the drawin g area. If BackColor is li ght blue, then the en tire area is
light blue when you clear it. ForeColor (foreground) determines the color of tex t and
graphi cs drawn on an object, alth ough sorne graphics meth ods give yo u the option of
specify ing a different foreground color.
The nex t secti on shows you how to select a color at run ti me. For info rmati on on addin g
color to your application s at design time:
111
Search Help for:
Color palette a See Tutorial Lesson:
" Creating Custom Applications "
With this definition in your global modu le, yo u can use the symbolic name RED wh enever
you want to specify red as a color arg um e nt or co lor property setting. For example:
BackCo l or - RED
T he CONSTANT.TXT fil e also pro vides co nstants for Windows default system co lors.
T hese va lues do not set specific co lors. but te ll Vi sual Basic to use one of the colors that th e
user c hooses in the Control Panel. sing such numbers ca uses your application to appear
di fferently on eac h user' s system, but the advan tage is th at the applicati on can be made to
look more consistent with other Windows app licati ons fo r any given user.
For more informati on on the CO STA T.TXT file:
Every visible color can be produced by combining one or more of the three primary colors.
For example:
Forml.BackColor = RGB(0 , 128. 0) Use medium green.
Form2.BackColor = RGB(255, 255, 0) ' Use yellow (red+ green).
PSet (100, 100), RGB(0, 0, 64) ' Set point to dark blue.
For more information on the RGB function, see the Language Reference, or:
For more information on the QBColor function, see the Language Reference, or:
Consequently, you can specify a color as a hexadecimal number using this syntax :
&HBBGGRR
The BB specifies amount of blue, GG amount of gree n, and RR amo unt of red. Each of these
fragme nts is a two-dig it hexadecimal number fro m 00 to FF. The median value is 80. Thu s.
the fo ll owing nurnber spec ifies gray, which has the median amount of all three colors:
&H808080
Settin g the rnost signifi cant bit to 1 changes the meaning of the color value: It no longer
represents an RGB color, but an environrnent-wide color specified through the Control
Panel. The values that correspond to these system-wi de colors range from &H80000000 to
&H 8000001 2 and are included in the CONSTANT.TXT file .
Using the Cls methocl witho ut a specified object clears the form to whi ch the code is
at tac hed.
Plotting Points
Another simple graphics operation is controlling an individual pixel. The PSet method sets
the color of a pixel at a specified point :
[object .] PSet (x , y)[, color]
The arguments x and y are single precision, so they can take either integer or fractional
input. The input can be any numeric expression, including variables.
If you don ' t include the color argument, PSet sets a pixel to the foreground color
(ForeColor). For example, the following statements set various points on the current form
(the form to which the code is attached), MyForm, and Picturel:
PSet (300. 100)
PSet (10.75, 50.33)
MyForm.PSet (230. 1000)
Picturel.PSet (1.5, 3.2)
As desc ribed in the section "The Step Keyword" later in thi s chapter, you can precede the
(x, y) coordinates by Step, which makes the point relative to the last location drawn .
Closely related to the PSet method is the Point method, which return s the color value ata
particular location :
PointColor = Point (500, 500 )
For more information on the PSet method, see the Language Reference, or:
Drawing Lines
To draw a line between two coordinates, use the simple form of the Line method, which has
this sy ntax :
[object .]Line [(xl , y l)] - [x2, y2 ) [, color]
The brackets indicate that objecr is optional ; if omitted, the method draws to the form to
which the code is attac hed (the current forrn) . The first pair of coordinates also is optional.
As with all values given for coordinares, the arguments x and y can be either integer or
fractional numbers. Visual Basic draws a line that ~_n cludes both end points.
For example, this statement draw s a slanted line on a form. The results are shown in Figure
13.9.
Line (500, 500) - (2 000 , 2000 )
1m lineDemo aa
The first pair of coordinares (xl , _v l) is optional. If you omit this end point, Visual Basic uses
the object's c urrent x, y location (drawing coordinates) as the end point. The current location
can be specified with the CurrentX and CurrentY properties, but otherwise is equal to the
last point drawn by a previous graphics or Print method. If you haven' t previously used a
graphics or Print rnethod or se t CurrentX and CurrentY, the current location is the object 's
upper-left comer by default.
For example, the following statements draw a polygon by connecting five points :
CurrentX - 600
CurrentY - 600
Line - (10 00, 500)
Line - (1200, 800)
Line - (800, 1100)
Line - (500, 1000)
Line (600, 600)
You can start experimenting with graphics by opening a blank form and placing statements
in a Form_Load or Form_Click procedure. For example:
Sub Form_Click ()
Line (500, 500) - (2000, 1200)
End Sub
By adding variables and loops , you can create interesting pattems. For example, the
following procedure quickly creates a spoked pattem on the screen. The results are shown in
Figure 13.1 O.
Sub Form_Click ()
Dim I As Integer
For I = 1000 To 2000 Step 50
Line (500, 500) - (2000. 1)
Next
End Sub
al lineDemo aa
This variatio n creates a relatively so lid pattem , and the drawing is slower:
Sub Form_Click ()
Dim l As Integer
For I - 1000 to 2000
Line (5 00, 500) - (2000, 1)
Next I
End Sub
Y ou also can change the color of th e line by first setting the ForeColor property fo r th e
obj ect where the line is being drawn.
T he three pro perti es th at affec t how lines are drawn are DrawWidth , DrawS ty le , and
DrawMocle. T he DrawWidth property specifies the width of the line in pi xels, and affects
the PSet ancl Circle methods as well as th e Line method . For exam ple . th e fo ll ow in g
procedurc uses Dra wWid th to cl raw lines of se vera! d iffe rent wid th s. T he res ulb are show n
in F ig ure 13.11.
Sub Fo r m_Clic k ()
Dr awW idth = 1
Li ne (10 0 , 1000 ) - (3 000, 1000)
Dr awWid th = 5
Li ne (1 00, 1500) - (3 000 , 1500)
Dr awWi dt h = 8
Li ne ( 100, 2000) - (3 000 , 2000 )
End Sub
mi DrawWidth Demo aa
T he DrawStyle property specifies whether the line is salid or has a broken pattern . This
pro perty is an integer whose settings represent the fo llowing.
Setting Description
O Salid (the default)
1 Series of dashes
2 Series of dots
3 Repeated dash-dot pattern
4 Repeated dash-dot-dot pattern
s Transparent (drawing has no effect)
6 Inside salid (see below)
T he inside salid style (DrawStyle = 6) is the same as salid, except when you are using a
wide line to draw a box. In thi s case, the solid style draws th e line half inside, ha lf outside
the box. The inside solid style draws the line entirely inside the box . See the section
"Drawing Boxes" later in this chapter to see how to draw a box.
The following procedure demonstrates a11 of the supported settin gs of the DrawSty le
property by creating a loop in which the setting goes from O to 6, one step at a time. The
results are shown in Figure 13. 12.
Sub Form_Click ()
Dim I As Intege r , Y As Long
For I = 0 To 6
DrawSty l e = I
Y= (2 00 * !) + 1000
Li ne (2 00, Y) - (2400, Y)
Ne xt I
End Sub
Figure 13.12 Lines drawn with different settings of the DrawStyle property
Other se tti ngs are used only rarely. For mo re informatio n on th e DrawMode property , see
the Language Reference, or:
A DrawMode setting of 7 is useful fo r anim ation . Draw ing a line twice restares the exis ting
display precisely as it was befare the line was drawn. This makes it possible to create one
object that " moves over" a background without corru pting it, beca use you can restare the
background as you go. Most modes are not guaran teed to preserve the old background .
For exampl e, the following code moves a circle every time th e mouse is clicked. No matter
what pattern was underneath the ci rcle, it gets restored.
Sub Form_Click ()
ForeColor = 255: DrawMode = 7
Ci rcl e ( CurrentX. CurrentY). 1000
CurrentX = CurrentX + 220
CurrentY = CurrentY + 220
Circle (CurrentX. CurrentY). 1000
End Sub
The Xor Pen draw mode, and most of the other DrawMode settings, work by comparing
each individual pixel in the draw pattem (called the "Pen") and the corresponding pixel in
the existing area (called the "Destination"). On monochrome systems, the pixel is either
tumed on or off, and Visual Basic performs a simple logical comparison: It tums a pixel on
if either the Pen or Destination pixel is on, but not both.
In color systems, each pixel is assigned a color value. For DrawMode settings such as Xor
Pen, Visual Basic compares each corresponding pair of pixels in the Pen and Destination ,
and perforrns a binary (bit-wise) comparison. The result determines the color value of the
resulting pixel , as shown in Figure 13 .13 .
1111 0011
Xor operation
'
Resulting
pixel
1100
Each of these points can be preceded by the Step keyword , which specifies that the point is
relative to the last point drawn. Visual Basic adds the values x and y to the values of the last
point drawn. and the sums determine the new point. For exa mple, the statement
Line (100, 200) - (150, 250)
is equivalent to
Line (100, 200) -S tep (50, 50)
In many situations, the Step keyword saves you from having to constantly keep track of the
last point drawn . Often you are more interested in the relative position of two points rather
than their absolute position .
Drawing Boxes
You can draw a box by using features of the Line method presented so far in thi s chapter.
The following example draws a box with upper-left comer at (500, 500) and measurin g
1.000 twips on each side:
Line (500, 500) -Step (1 000, 0)
Line Step (0, 1000)
Line - Step (-1000. 0)
Line - Step (0, - 1000 )
However. Visual Basic provides a much simpler way to draw a box . When you use the B
option wi th the Line method (B comes after the argument color), Visual Basic draw s a
rec tang le, treatin g the specified points as opposite corners of the rectangle . Thus , yo u could
replace the four stateme nts of the previous example with:
Line (500 , 500) -S tep (1000, 1000), . B
Note that two commas are required before B, to indicate that the color argument was
s kipped. (Oth erw ise, B could be interpreted as a variable giving the color value) .
As long as you do not cha nge the settin g of the FillStyle property, the box appears empty .
Actual ly. the box does get filled usi ng the current FillStyle and FillColor settings. But
Fill Sty le defaults to l (Transparent), which specifies an invisible pattern. You ca n chan ge
th e FillStyle property to any of the settin gs li sted below.
Setting Description
o Solid. Fills in box with the color set for the Fil!Color
property.
Transparent (the default). Graphical object appears e mpt y.
no matter what color is used.
2 Horizontal lines.
..,
.) Vertical lines .
'-+ Upward diagonal lines.
s Downward di agonal lines.
6 Crosshatch .
7 Diagonal crosshatch.
Thu s, se ttin g Fil!Style to O fills th e box so lidly with the color set for the Fil!Color propert y.
Another way to fill the box is to append an F to the B. (Note that F cannot be used without
B.) The following statement fills the box with a solid pattern, using the same co lor used to
draw the line (specified by the DrawColor property) . The result is shown in Figure 13.14.
Line (50 0, 500) -S tep (1000, 1000) , , BF
11 FillDemo ªª
Drawing Circles
The Circle method draws a variety of circu lar and elliptical (oval) shapes. In add ition ,
Circle draws ares (segments of circles) and pie-s haped wedges. You can produce many
kinds of curved lines by using variations of Circle.
To draw a perfect circle (as opposed toan ellipse), Visual Basic needs only th e location of a
c ircle' s center and the length of its radiu s. The syntax for a perfect circle is:
[object .]Circle [Step] (x, y), radius [, color]
The bracke ts indicate that both object and the Step keyword are optional. lf object is
om itted, the c urrent form is assumed. The arguments x and y are the coordinates of the
ce nte r, and radius is the radius of the circle. For example, this state ment draws a circle with
a ce nter at ( 1200, 1000) and radius of 750:
Circle (1200, 1000), 750
The exact effec t of thi s statement depends on the coordinate sys tem in use and the size of the
form. Because the size of the form is unknown , yo u don ' t even know if the circle wil l be
visible. Using the drawing area's ScaleWidth and ScaleHeight properties solves thi s
problem. For example, this statement ensures that the center of the circle is at the cen ter of
the form:
Circ le (Scale Width/2, Sca leHeigh t/2), ScaleWidth/4
By usin g the Step keyword , you can make the location of the circ le relative to the center of
the form , in stead of relative to the upper-left comer:
CurrentX = Sc aleWidth/2
CurrentY = ScaleHeight/2
Circle Step (200, -3 00), 1000
Note The radius of the circle is always specified in term s of hori zontal units . If your
coordinate system uses the same hori zontal and vertical units (which it does by default), you
can ignore thi s fact. However, if you use a custom scale, hori zontal and vertical units may
corres pond to different di stances. In the exa mples above, the radiu s is specified in hori zontal
units, and the actual height of the circle is guaranteed to be equal to its actual width .
Drawing Ellipses
The aspect ratio of a circle controls whether or not it appears perfectly round (a perfect
circ le) or elongated asan ellipse. The compl ete sy ntax for the Circle method is:
[objec1. ]Circle [Step] (x, y ), radius , [color] , [start], [ene/] , aspect
Here. mpecl is a positi , ·e fl oati ng-point number. Thi s mean s yo u can specify in teger or
fractional ex pressions, but not negati ve values.
The arg ume nts start and end are used in displaying ares, as described in the next sec tion .
These arguments are optional , but the commas are necessary if you want to skip arg um ents.
For example, if you include the radius and aspect arguments, but no color, start, or end
argument, yo u must add four successive commas to indicate that you ' re skipping the three
arg uments:
Cir cle (1 000, 1000) , 500,.,. 2
T he argument aspect specifies the ratio of the verti cal to hori zo ntal dimensions. Large
vaJu es fo r aspect produce ellipses stretched o ut alo ng th e ve rti cal axis , while small valu es
for aspect produce ellipses stretched out along the hori zo ntal axis. Since an ellipse has tw o
rad ii - one hori zontal x-radius and one ve rti cal y- radius - Yi suaJ Basic uses th e s in g le
arg um e nt radius in a Circle statern ent as follows : If aspee! is less th an one, radius is the x-
radiu s; if aspect is greater than or equ al to one, radius is the y-radiu s.
Note The arg ume nt aspecr always specifies the ratio between the vertical and hori zontal
dim e nsions in term s of true ph ys ical di sta nce. To ensure th at this happens (even when yo u
use a c usto m scale), th e radiu s is specified in terms of hori zontal units. See the end of th e
previous sec ti on for more information .
Exa mple The following procedure illustrates how different aspect values determine whether Circle
uses the argument radius as the x-radius or the y-radius of an ellipse. The output is shown in
Figure 13.15.
Sub Form_Click ()
FillStyle = 0 ' Draw solid ellipse .
Circle (600, 1000), 800, ... 3
FillStyle = 1 ' Oraw empty ellipse.
Circle (1800, 1000), 800 .... 1/3
End Sub
ID Ellipses Demo aa
Drawing Ares
An are is a segment of an ell ipse ora circle; think of an are as a curved line. To understand
how the Circle method draws ares , you need to know how Vis ual Basic measures ang les .
Visual Basic uses the radian as its unit of angle measure, not only in the Circle method , but
also in the trigonometric functions such as Cos, Sin, or Tan.
The radian is closely related to the radius of a circle. In fact , the word " radian" is deri ved
from the word "radius." The circumference of a circle equals 2 * Pi * radius , w here Pi is
equ al to approximately 3. I 41 S926S. Similarly, the number of radians in one com plete angle
of revolution (or 360 degrees) eq ual s 2 * Pi, ora littl e more than 6.28 .
T hi s statement calcul ates Pi to double precision :
Oim Pi As Oouble
Pi = 4 * Atn(l)
lf you think of angles in term s of degrees, here are sorne common equivalents.
Angle in degrees Angle in radians
360 2*Pi (approximately 6.283)
180 Pi (approximately 3. 142)
90 Pi/2 (approximately 1.571)
60 Pi/3 (approximately 1.047)
45 Pi/4 (approximately 0.786)
If you picture a clock face on the sc ree n, Circle measures angles by starting at the three
o' clock position and rotating counterc lockw ise , as shown in Figure 13. 16.
90 degrees
(TI/2 radians)
- - - - - 3rr./2 radia ns
_ __,,__ _ _ TI radians
- - - -- - - - - rr./2 radians
·..-_ __,_ _ _,___ _,____ 7 radian
180 degrees Odegrees
(TI radians) (O radians)
270 degrees
(Jrr./2 radians)
The general formu la for convertin g from degrees to radians is to multiply degrees by Pi/180 .
To draw an are, give angle arguments defi ning the are 's limits. The sy ntax is:
area .Circle Step(x, y ), radius, color, start, end, aspect
In th e fo llowing example, the Circle method is used to draw seven ares. The innermost are
starts at the three o'eloek position (O radians) and the outermost are starts at the six o'eloek
position (3/2 * Pi). The results are shown in Figure 13.17.
Sub Form_Click ()
Height = 550 0
Const PI= 3.14159265
StartAngle = 0
For Radius% = 1000 To 2200 Step 200
EndAngle = (EndA ngle + (PI / 2)) Mod (2 * PI)
Circle (25 00, 2500) , Radius%, Start Angle, EndAngl e
StartAngle = StartAngle + (PI / 4)
Next Radiu s%
End Sub
11 Ares Demo aa
If th e arg um ent start or end is negati ve, Visual Basie draws a line eonneeting the eenter of
th e eire le to the negative end point. For exampl e, the following procedure draw s a pie with a
sli ce re moved , as shown in Figure 13.8 on the nex t page.
Su b Form_Click ()
Const PI= 3.14159265
Circle (35 00, 1500), 1000 , . -PI/ 2,- PI / 3
End Sub
Both the srarr and end arguments are negative, so lines are drawn co nn ecting both end points
of the are to the center of th e c ircle.
Figure 13.18 Using negative arguments to con nect an are to its center
Note that the are is drawn the long way between the two angles rather than the short way.
T hi s is because Visual Basic alw ays draws ares in a counterclockwise (positive) direction. lf
the angles are given in the reverse order (Pi/3, Pi/2), Visual Basic draws the are usin g the
short di stance between the two angles, as shown in Figure 13 .19.
V
Figure 13.19 Ettect of reversing arguments
This example on the prev ious page also illustrates that - Pi/2 and - Pi/3 indicate th e same
angles (po ints on the c ircle) th at Pi/2 and Pi/3 do. The onl y signifi cance of the nega ti ve sig n
is that it ca uses Vi sual Basic to draw a line between the point and the center of the ci rc le.
As you ' ve seen in earlier chapters, Click is a simple mou se event. It ' s adequate for situat ions
where you respond the same way to any mouse click on an object.
Your applications also can respond to other mou se events - such as MouseDown and
MouseUp . Forms and picture boxes can detect the exact position of the mouse pointer,
whether or nota button is being pressed. In addition , your code can respond differently to
left and ri ght mouse buttons and to combinations of buttons with the SHIFr, CTRL, or ALT
keys .
Close ly related to the mou se events are the drag-and-drop features in Visual Basic. These
include properties and events, and a Drag method that you can use to enable dragging
ope ration s at run time. The drag-and-drop feature s are especiall y versati le; yo u can support
dragging between forms , and you can support drag operati n or users without a mouse.
The main section s in this chapter are:
• Mouse Events
• Positioning a Control with the Mouse
• Graphi cal Mo s-:e,..~ - - - -~ ......~-~.....,;-'"'""""-....,-'""
Mouse Events
Forros and several types of controls recognize three mouse events (aside from drag events,
which are introduced later). You can use the following to respond to the exact location and
state of the mouse .
Event Description
MouseDown Recognized when the user presses any mouse button.
MouseUp Recognized when the user releases any mou se button .
MouseMove Recogni zed each time the mou se pointer is moved to a new
point on the screen.
The obj ec ts th at ca n recog nize th ese eve nt s inc lude form s, pi cture boxes. labels. and any
type of control that involves a list: list boxes, combo boxes, file list boxes, drive list boxes,
and directory list boxes .
A forro can recogni ze a mouse event when the pointer is overa blank portian of the forro . A
control can recogni ze a mouse event when the pointer is over the control.
When the use r presses and hold s down a mou se button , the same form or con trol continues
to recognize ali mouse events until the user releases the button . This is true even when the
pointer is moved off the obj ec t.
Ali three mou se eve nts use the same arguments.
Argument Oescription
Button A bit-fi eld argum ent in which the three leas t-significant bits
give the statu s of the mou se buttons.
Shift A bit-fi eld argument in which the three leas t- significant bits
give the statu s of the SHI FT, CTRL, and ALT keys .
X, y Location of th e mouse pointer, using the coordin ate sys tem
of th e object that rece ives the mou se event.
A bit-field argwn ent retums informati on in indi vidual bits, so that each bit indicates whether
a certain condition is on or off. Techniques for programming with these arg um ents are
desc ribed later. in th e sec tion "The Button and Shift Arguments ."
1m Forml ªª
The picture box has the default name Picturel. If you want to load an image into the picture
box , set its Picture property by using the Properties bar, as described in Chapter 13,
"Creating Graphical Effects."
A single procedure, Forrn_MouseDown, does all the work of this application :
Sub Form_MouseDown (Button As Integer, Shift As Integer, X As Single,
• Y As Single)
Picturel.Move X, Y
End Sub
That 's al i there is to it! The procedure uses the Move method to move the picture box
co ntrol to the location of the mouse (indicated by the arguments X and Y). This procedure
places the top left comer of the picture at the mouse location.
A revised version places the center of the picture at the mouse location :
Sub Form_MouseDown (Button As Integ e r, Shift As Integer, X As Single,
• Y As Si ngle)
Picturel.Move CX - Picturel . Wid th / 2), (Y - Picturel . Height / 2)
End Sub
For more information on the Move method, see the Language Reference, or:
T he first line draw n starts at the ori gin (upper-left com er), whi ch is the default draw ing
locati on . T herea fter, the applica tion draw s a straight line frorn the last location drawn each
time the use r presses the mouse button dow n. The result is a seri es of co nnected lines, as
show n in Figure 14. 2.
Figure 14.2 Th e Cli ck- A-Lin e application draws line s w it h th e Line method .
Scribble ªª
Visual Basic does no t necessaril y generate a MouseMove event for every pi xel the mou se
moves ove r. The operating environment generates a limited number of mou se messages per
second. To see how often MouseMove events are actually recogni zed, you can enhanc e the
Scribble application with the following codeso that it draw s a small circle at each locatio n
wh ere a MouseMove event is recognized. The results are shown in Figure 14.4.
Sub Form_ Mou se Move (B utto n As Integer, Shift As Integer. X As Single,
• Y As Single)
Li ne - (X, Y)
Circle (X, Yl. 50
End Sub
No te that the fa ster the user moves the pointer, the fewe r M o useMove events are recog ni zed
be twee n any two points. Man y c ircles clase together indicate th at th e user moved th e mou se
slow ly.
W hat's important to understand about MouseMove events is th at your appli cation can
recognize man y of them in quic k successio n. Therefo re , a MouseMov e eve nt procedure
sho uld no t do anything that req uires large amount s of computing time.
These acti ons correspo nd to the MouseDown, MouseUp, and MouseMove events. Each of
the three event procedures has a specifi c role. MouseDown and MouseUp in effect say,
"Tum draw ing on," or "Turn drawing off." In Visual Basic , yo u communicate such
information by creating a forrn-level variable to represent the drawing state. Type thi s
statement in the Declarations sec tion of form code:
Dim DrawN ow As Integer
We'II use DrawNow to represent two values: A value of False (0) will mean "Do not draw ,"
and a val ue of True (- 1) wi ll mean "Draw a line."
Variables are initiali zed to zero by default, so the application starts wi th drawing off.
Drawing is then turned on and off again by the MouseDown and MouseUp procedures:
Sub Form_MouseDown (Button As Integer, Shift As Integer. X As Single,
- Y As Sing l e)
DrawNow = - 1
Curr entX X
CurrentY - Y
End Sub
The first indented line in each procedure turn s drawin g on or off by se ttin g th e va lue of th e
form-level variab le DrawNow. ( DrawNow does not by itse lf have special meanin g, but it is
used by the MouseMove procedure.)
The MouseMove procedure draws a line only if DrawNow is T ru e (- J). O th erwise, it takes no
ac tion:
Sub Form_MouseMove (Button As Integer. Shift As lnteger. X As Single .
• Y As Single)
If DrawNow Then Line - CX. Y)
End Sub
This version of the Scribble application demon strates th e relati onship of events: When th e
user presses a mouse button, the MouseDown proced ure is ca lled just once. The
MouseDown event procedure signals to tum drawing on. Thereafter, MouseMove is invoked
many times as the pointer is dragged across the sc ree n.
No te th at the use of the Line me th od above omits the first endpoint, causing Vi sual Basic to
start drawing at the current drawing coordinates. By default , th e drawing coordinates
correspond to the last point drawn , but you can reset them by ass ignin g values to CurrentX
and CurrentY. In thi s appli cation, the MouseDown procedure sets CurrentX and Curren tY to
start drawing from a new location - the place w here the use r presses th e mouse button:
CurrentX X
CurrentY - Y
left button
righ t button
middle button
O O M R L
lunused
The exac t meaning of these bits changes depe ndin g on the event, whi ch is why the
informat ion returned for the MouseMove event differs from that for the MouseDow n and
MouseUp events .
Yo u do n' t need to understand everythin g about how bits are set in order to use Button, but it
can help yo u dev ise more powerfu l uses for the argument, as you' ll see in the nex t sec ti ons.
Note In contrast, you can use the Mo useMove event to tes t not onl y for whi ch button is
pressed during the move, but also whether two or more buttons are pressed simultaneously.
You also can use MouseMove to test fo r whether only one button is pressed, which you
cann ot do with Mo useDown or MouseUp. See the next section, "Using Button with
MouseMove," fo r more informati on.
T he reason you can test only which button is used with-MouseDown and MouseUp is that
only one bit is set in Button for each event. Possible binary values of Button are listed below.
Value Meaning
001 (decimal 1) The left button caused the event.
010 (decimal 2) Toe right button caused the event.
100 (decimal 4) The middle button caused the event.
If a button is not present on the user' s mouse, the corresponding bit is always O. On a two-
button mouse, there is a left and right button, but no rniddle button. On a one- button mouse,
there is only a left button.
You can determi ne which button causes a MouseDown or MouseUp eve nt wi th relati vely
simple code. The fo ll owing procedure tests whether Button equ als 1, 2, or 4:
Sub Form_MouseDo wn ( Bu tto n As Integer, Shi ft As Int eger, X As Si ngle,
• Y As Sing l e)
I f Button - 1 The n Prin t "Y ou pressed t he l ef t bu t ton . "
If Bu tton 2 Then Print "Y ou presse d th e right button . "
I f Button 4 Then Pr i nt "Y ou pressed the middl e bu tt on. "
End Sub
If the user presses more than one button, Visual Basic interprets th at action as two or more
separate MouseDown events. It sets the bit for the first button pressed, prints the "You
pressed ... " message for that button , and then does the same for the next button. Simil arl y,
Visual Basic interprets the release of two or more buttons as separate MouseU p eve nts.
Thus, for MouseMove, if you test for eq uality to 001 (decimal 1), you're test ing to see if
only the left mouse button is held down while the mouse is moved. If another button is held
down along with the left button, this code doesn' t print anything:
Sub Form_Mouse Move ( Butto n As I nteger . Shi ft As Integer. X As Si ngl e .
• Y As Single)
If Button - 1 Then Pr i nt "Y ou pres s ed only the left button . "
End Sub
If you want to test for whether a particular button is down, but you want to ignore whether or
not the other buttons are pressed, use the And operator. This code prints the message for
each button pressed, regardless of whether another button is pressed:
Sub Form_MouseMove (Button As Integer, Shift As Integer , X As Single,
• Y As Si ngle)
If Button And 1 Then Print "You're pressing the left button."
If Button And 2 Then Print "You're pressing the right button."
End Sub
Y ou can test for two buttons being pressed simultaneously by adding another line of code:
Sub Form_MouseMove (Button As Integer, Shift As Integer, X As Single,
• Y As Single)
If Button And 1 Then Print "You're pressing the left button. "
If Button And 2 Then Print "You're pressing the right button."
If (Button And 3) = 3 Then Print "You're pressing both buttons."
End Sub
The value of 3 is obtained by adding 1 and 2 together. This produces the binary pattem O11 ,
in which both of the two least-significant bits are set. Using the And operator with 3 masks
out ali bits except the last two and then tests to see if these two bits are set. Testing for
multiple bits is tricky . Note that the following lines produce erroneous results:
If (Button And 1) And (Button And 2) Then
lf Button And 3 Then
There are severa! ways to test for multiple bits . One reliable way is to add the button
con stant s ( 1, 2, or 4) together to produce a single number. Then use the combined And
operator and equality test shown earlier. For example, the following statement tests to see if
ali three buttons are pressed (note that 7 is the sum of 1, 2, and 4) :
I f ( Butt on And 7) = 7 Then Pri nt "Al l three buttons pres sed."
You may find that yo ur code is more readable and easy to maintain if you define constants
for th e buttons you ' re detecting:
Const LEFT_BUTTON = 1
Const RIGHT_BUTTON = 2
Const MIDDLE_BUTTON = 4
Often, it's helpful to note each relevant event and what the application should do in
response. The three relevant events here are mouse events:
• Form_MouseDown- Take a different action depending on state of mouse buttons:
If the left button is down, set DrawNow to True (-1) and reset drawing coordinates.
If the right button is down, draw a line.
• Form_MouseUp - If the left button is up, set DrawNow to False (0) .
• Form_MouseMove - If DrawNow is True (-1), draw a line.
The variable Dr a wNow and the button constants are declared in the Declarations part of the
form:
Dim DrawNow As Integer
Const LEFT_BUTTO N - 1
Const RIGHT_BUTTON - 2
The MouseDown procedure has to take a different action, depending on whether the left or
right mouse button caused the event:
Sub Form_MouseDown (Button As Integer, Shift As Integer, X As Single,
• Y As Single)
If Button = LEFT_BUTTON Then
DrawNow = -1
Currentx = X
CurrentY = Y
Elself Button = RIGHT_BUTTON Then
Line-(X, Y)
End I f
End Sub
The MouseUp procedure tums off drawing, but only when the left button is released:
Sub Form_MouseUp (Button As Integer, Shift As Integer, X As Single,
• Y As Single)
If Button LEFT BUTTON Then DrawNow = 0
End Sub
Note that within the MouseUp procedure, a bit set to 1 indicates that the corresponding
mouse button is released.
The MouseMove procedure is ídentical to the one in the previous version:
Sub Form_MouseMove (Button As Integer , Shift As Integer, X As Single,
• Y As Single)
If DrawNow Then Line -(X, Y)
End Sub
The three least-significant bits in Shift correspond to the state of the SHIFT, CTRL, and AL T
key s, as shown in Figure 14.6.
SHIFT key
CTRL key
ALT key 1
1 º º º º
1
lunused
Any or all of the bits in Shift are set, depending on the state of the SHIFT, CTRL, and ALT
keys. lf only one key is pressed, the· binary patterns are 001 (decimal 1) for SHIFT, 010
(decimal 2) for CTRL, and 100 (decimal 4) for ALT. If all are pressed, Shift has the binary
pattern 111 (decimal 7) . If only SHIFT and ALT are pressed, Shift has the binary pattern 101
(decimal 5).
As with the argument Button , you can use the And operator to mask out ali bits except the
ones you are interested in testing for:
Sub Form_Mou se Down (Button As Integer. Shift As Int eger, X As Si ngle,
• Y As Single)
If Shift And 1 Then Print "You pressed the SHIFT key ."
If Shift And 2 Then Pr int "You pr ess ed the CTRL key . "
If Shift And 4 Then Print "You pressed the ALT key ."
If (S hift And 3) 3 Then Print "You pres se d both SHIFT and CTRL . "
If (S hift And 5) 5 Then Print "Yo u pre ssed both SHIFT and ALT."
If ( Shift And 6) 6 Then Print "Y ou pres sed both CTRL and AL T."
If (Shif t And 7) 7 Then Print "Y ou pressed SHIFT, CTRL . and ALT . "
End Sub
1m forml aa
Note Run-time dragging of a control does not automatically change the location of the
control. You can cause this to happen, but you must program the relocation yourself, as
described in the section "Causing Control Movement" later in this chapter. Often, dragging
is used only to indicate that sorne action should be performed , and the control retains its
original position after the user releases the mouse button.
The following drag-and-drop properties, events, and methods enable you to determine the
meaning of a drag operation as well as how dragging can be initiated (if at all) for any given
control.
Category ltem Description
Properties DragMode Enables automatic or manual dragging of a control.
Draglcon Specifies what icon is displayed when the control is
dragged.
Events DragDrop Recognizes when a control is dropped onto the object.
Dragüver Recognizes when a control is dragged over the object.
Method Drag Starts or stops manual dragging.
All controls except menus and timers can be dragged at run time and share all the properties
li sted above. Forros recognize the DragDrop and Dragüver events, but they don't have the
DragMode and Draglcon properties.
You set the DragMode property to 1 at design time by clicking the arrow at the right of
Settings box and choosing "1 - Automatic."
When you set dragging to Automatic, dragging is always "on." Later, you'll see how to use
the "O- Manual" setting to control dragging.
Note While an automatic drag operation is taking place, the control being dragged does not
recogni ze other mouse events.
You also can set the Draglcon property at run time by assigning the Picture property of one
control to the Draglcon property of another:
Pi ctur e l . Dragi co n = Pi cture 3. Pi ct ur e
For more information on the Picture property and the LoadPicture function , see Chapter 13,
"Creating Graphical Effects ," or:
A control becomes the target if the mouse position is within its borders when the button is
released. A form is the target if the pointer is in a blank portion of the form.
The DragDrop event provides three arguments: Source, X, and Y. The argument Source is a
reference to the control that was dropped onto the target. For example, if the user drops a
control onto a blank portion of the form, the Form_DragDrop procedure is invoked:
Sub Form_DragDrop (Source As Control. X As Single, Y As Single)
End Sub
You should show sorne care with the argument Source, because although you know that it
always refers to a control, you don't necessarily know which type of control it is. For
example, if the control is a text box and yo u attem pt to re fer to So u re e . Val u e, the result is
a run-time error because text boxes have no Value property.
You can use the If... Then ...Else Statement with the TypeOf keyword to determine what
kind of control was dropped. For more inforrnation, see Chapter 17, "Advanced Language
Features," or:
All the possible types for Source (ali control types except menus and timers) have a Visible
property. Therefore, you can make a control invisi ble when it's dropped on a certain part of
a form or on another control. The following procedure causes a control to disappear when
it's dropped on a picture box named Yanish:
Sub Vanish _ DragDrop (Sou r ce As Control. X As Single. Y As Single)
Source.Visible = 0
End Sub
End Sub
The DragOver event has the same arguments that DragDrop does. In addition, it has a State
argument which indicates one of the following actions.
Value of State Description
o Enter (the mouse position just entered the object' s borders) .
l Leave (the mouse position just left the object's borders) .
2 Over (the mouse position moved from one part of the object
to another).
Typically, you'll use the Enter and Leave states to create and remove highlighting and
ignore the Over state. Over is useful if you want to know when the mouse position is overa
particular subdivision of an object (such as a region within a picture box) . To respond that
way, you ' d need to evaluate the arguments X and Y, which give the mouse position within
the object.
To create or remove highlighting ·Nith Visual Basic, assign values to BackColor and
possibly ForeColor as well. For example, the following procedure inverts colors when the
user drags a control over Textl (Enter) and inverts colors back to their original state when
the control is dragged off the text box (Leave).
Sub Textl _Dragüver (Source As Control, X As Single, Y As Single,
• State As Integer)
Const ENTER - 0
Const LEAVE - 1
Dim TempColor As Long
The constants ENTER, LEA VE, and OVER are defined in the CONSTANT.TXT file.
If action is 1, the Drag method initiates dragging of the control. If action is 2, the control is
dropped, thus causing a DragDrop event. Giving the value O for action cancels the drag: The
effect is similar to giving the value 2, except that no DragDrop event is recognized.
For example, this statement enables (tums on) dragging of a control named ThisBox:
ThisBox.Drag 1
This statement drops the control and has the same effect as releasing a mouse button:
ThisBox . Drag 2
This code may not produce precisely the effects you want, because the top left comer of the
control is positioned at the mouse location. This co9e po~ition the cen~~r of the control at
the mouse location: ·
Sub Form_OragOrop (Source As Control. X As Single, Y As Single)
Source.Move (X - Source.Width / 2), (Y - Source.Height / 2)
End Sub
The code works best when the Draglcon property is set to a value other than the default (the
gray rectangle). When the gray rectangle is being used, the user normally wants the control
to move precisely into the final position of the gray rectangle. To cause this action , record
the initial mouse position within the source control. Then use thi s position asan offset when
the control is moved .
The following example illustrates how to cause drag movement for a picture box named
Pictl. The control' s DragMode property should be set to Manual (O) at design time. The
declarations section contains the form-level variables Ora g X and Ora g Y, which record the
initial mouse position within the picture box :
Dim DragX As Single, OragY As Single
The MouseDown and MouseUp procedures for the control turn dragging on and drop the
control , respectively. In addition, the MouseDown procedure records the mouse position
inside the control at the time dragging begins:
Sub Pictl_MouseDown (Button As Integer, Shift As Integer, X As Single.
• Y As Single)
Pictl.Drag 1
DragX X
DragY = Y
End Sub
The Form_DragDrop procedure actually moves the control. To simplify this example,
assume that Pict 1 is the only control on the form. The target can therefore only be the form
itself. The Form_DragDrop procedure repositions the control, using DragX and DragY as
offsets:
Sub Form_DragDrop (Source As Control. X As Single, Y As Single)
Source.Move (X - DragX), (Y - DragY)
End Sub
Note that this example assumes that Pictl and the form use the same units in their respective
coordinate systems. If they don ' t, then it's necessary to convert between units.
Once you know how to write an application with a single forrn, you know almost everything
you need to know to write a multiple-form application. Any Visual Basic application can be
easily extended to have multiple forms. ·
Multiple forms can give your application increased functionality. Each forrn can have its
own unique look and purpose.
Having more than one form in your application is particularly useful if you want to create
custornized dialog boxes. You designa custom dialog box as a forrn. These dialog boxes can
be more complex than the ones you create with InputBox$ or MsgBox. In fact, custornized
dialog boxes can have all the controls and graphics you'd put on other forms.
This chapter shows you how to load, display, and hide different lcinds of forms. The main
sections are:
• Methods and Statements that Handle Forms
• Setting Form Properties
• Designating a Startup Form or Module
• Choosing an Icon
• Loading and Displaying Forms
• Hiding Forms
• Unloading Forrns
• Exiting a Multiple-Form Application
•
.. •
• •
• •
• •
• •
" •
• •
• •
• • •
• •
• •
• •
• •
• •
• •
"
216 Part 3 Application-Building Techniques
When you create a multiple-form app li ca ti on, you may want the code attached to one form
to refer to something on another form. Or you may want to place a general procedure in a
module, so that more than one form can use it. In both cases, it 's necessary to qualify
references to form s. (In single-form appli ca ti ons with no modules, the form is implicit.)
To refer to a property of another form , use thi s syntax :
form.prop erty
Theform and control can be any valid refe re nce to a form or control. The property is always
a name of a property supported for th at obj ec t.
·r . . ·· ; . ~ _;; . :
1
. ·J/iU .;;ii/1fiJ l!/ 1ii 11 l
: : . : ; ,-•, ; ; One of the most inlluential rock groups ever.
Command
buttons
: : : : : : : : :r Members include Paul McCartney, Ringo Starr,
. ~ :f ¡_: ~ ;• John Lennon .. George Hanison
! .
: : : ·:· ::' : • • : 1 ~ ••• : : ; • : : • : : : .. : :
Note Not all of the material you need for the Rock ' n' Roll application is included in this
chapter, but it may be helpful to create and run its forms.
If users are running several Windows applications, it's likely they ' ll want a lot of control
over how much room the Beatles form takes up on their screen . They may want to shrink the
fo rm to an icon while they run another Windows application. Or they may want to move the
form or make it smaller or larger.
The properties listed below for the Beatles form are typical of many windows in Windows
applications. Except for the last two properties listed (Caption and FormName), the settings
are the defaults for the property . That means th e properties start off with the followin g
settings.
Form property Setting Reason for setting
BorderStyle 2 - Sizeable Because BorderStyle is set to "2," users can change
the size of this window.
MinButton True Users can shrink the window to an icon so they can
view another application on their screen - and then
enlarge the Beatles window later.
MaxButton True Enables users to enlarge this window to a ful] screen.
ControlBox True Adds a Control menu, which provides Restore, Move,
Size, Minirnize, and Maximize commands . Helpful to
ali users, this menu is essential for users who don ' t
have a mouse.
Caption The Beatles Iden tifies the window and appears on the title bar.
Any window with a caption can be moved.
FormName Beatles Sets the name that will be referred to in code.
For more details on form properties, see the Language Refe rence, or:
No Minimize ar
Maximize buttons
The properties for the GroupChoice dialog box are set as follows:
Form property Setting Reason for setting
BorderStyle 3 - Fixed Users don ' t need to change the size of the form.
Double
MinButton False Users don't need to shrink the dialog box toan icon.
MaxButton False Users don ' t need to enlarge the dialog box to a full
screen.
ControlBox True Adds a Control menu, which makes the Move
command accessible from the keyboard . (The
Restare, Size, Minimize, and Maximize commands
will appear on the Control menu, but these
commands will be disabled.)
Caption Rock Groups Identifies the dialog box .
FormName GroupChoice Sets the name that will be referred to in code.
Note The settings you specify for MaxButton, MinButton, BorderStyle, and ControlBox
are not reflected in the form's appearance until you run the application.
Far more information on lnputBox$, see Chapter 11, "Getting lnformation from the U ser."
Far information on MsgBox, see Chapter 12, "Displaying and Printing lnformation"; the
Language Reference; or:
This form uses the default property settings, with the fo1lowing exceptions.
Form property Setting
FormName Welcome
Caption Rock 'n' Roll App
Picture \ROCK\WELCOME.BMP
Note that by default, BorderStyle is set to Sizeable, and ControlBox, MaxButton, and
MinButton all are set to True.
You use the Settings box on the Properties bar to set the Picture property, which identifies
the file containing the background picture. (Toe \ROCK\WELCOME.BMP path given for
Picture in the table is fictitious.) When you select the Pícture property in the Properties list
box , the arrow at the right of the Settings box becomes three dots; click them to open a
dialog box from which you can selecta picture file.
You also can paste a picture onto a form via the Clip board. For more information, see
Chapter 13, "Creating Graphical Effects."
Choosing an lcon
When the user minimizes a form, an icon is displayed that represents it. You can use the
Visual Basic standard icon, or you can customize your applícatíon by selecting your own
icon for each form. The icon is specified by the Icon property of a form.
To specify an icon, select the !con property in the Properties list box, then click the three
dots at the right of the Settings box. Choose the .ICO file that contaíns the ícon you want.
Figure 15 .4 shows the Visual Basic standard icon and the custom icon used for the Welcome
form. The !con property for the Welcome form is set to the filename MISC31.ICO (a
musical scale) in the !con Library included with Visual Basic. (The full path depends on
where you installed Visual Basic.)
Mi,fyft
•~7-.._
~z~~
Visual Basic Rock 'n' Roll .6.pp
Figure 15.4 Visual Basic standard icon and the icon for the Welcome form
Note The graphics file you choose for your icon must have the .ICO format. The Visual
Basic !con Library is a good source of icons for your forms.
The argument modalstate is an integer value that specifies whether or not the form is modal.
If modalstate is 1, the form is modal. If modalstate is O or is omitted, the form is modeless.
Once a modal form is displayed, the user cannot switch focus to another window until the
form is closed. Furthermore, no Visual Basic code is executed until that form is hidden or
unloaded. Dialog boxes are usually modal.
When loading a form, Visual Basic sets the form 's properties to their initial values (specified
at design time) and executes the Form_Load procedure attached to that form. The
Form_Load procedure may do additional initialization beyond what could be set in the
Properties bar.
Note Any reference to a form's controls or properties causes Visual Basic to automatically
load a form into memory, if it is not loaded already.
For more information on the Show method, see the Language Reference, or:
Beatles
Doors
Fleetwood Mac
Jackson Five
Jeflerson Airplane
Pink Floyd
Aolling Stones
Supremes
The'Who
Clicking the Rock Groups command button invokes its Click event procedure, which
displays and loads the GroupChoice form :
Sub RockGroups _Click ()
GroupChoice.Show
End Sub
To add controls to the GroupChoice form shown in Figure 15.5, create a label and set its
caption to "Choose a rock group:". Then create a list box (named GroupChoice) large
enough to hold six or more items.
As soon as the GroupChoice fonn loads, its Load procedure is invoked, which places the
names of the rock groups into the li st box named GroupLi st:
Sub Form_Load
Grouplist.Addltem "Beatles"
Grouplist.Addltem "Door s "
Grouplist.Addltem "Fleetwood Mac"
-Groupl i st.Addltem "Jackson Fi ve"
Grouplist.Addltem "Jefferson Airplane"
Grouplist.Addltem "Pink Floyd"
Grouplist.Addltem "Rolling Ston es "
Grouplist.Addltem "Supreme s "
Groupli st.Addltem "The Who"
End Sub
Hiding Forms
With multiple-form applications, you often may want to hide the form that's currently on the
screen and display a new one. If there's a chance you want to use the form later, you ' ll
improve execution speed by temporarily hiding a form rather tban unloading it.
Another advantage to temporarily hiding a form (ratber than unloading it) is that you don ' t
lose any data attached to the form , such as property values and data stored in form-level
variables.
To hide a form that 's already been loaded, use the Hide method . The syntax is:
[form.]Hide
For example, thi s proced ure hides the Welcome form after the user chooses any item in the
GroupList list box :
Sub Grouplist_DblClick ()
Welcome .Hide
End Sub
If Welcome is a form that you may use again soon, then it makes sense to hide the form
rather th an unload it. You can display the form again by using the Show method :
Welcome.Show
For more information on the Hide method , see the Language Reference, or:
The user can choose a rock group from the GroupChoice form by double-clicking a list item.
The code for the GroupList_DblClick event procedure is:
Sub Grouplist_DblClick ()
Welcome.Hide
GroupChoice.Hide
Select Case Grouplist.Listindex
Case 0
Beatles.Show
Case 1
Doors.Show
Case 2
FleetMac.Show
Case 3
JackFive.Show
Case 4
JeffAirplane.Show
Case 5
PinkFloyd.Show
Case 6
Stones.Show
Case 7
Supremes.Show
Case 8
Who.Show
End Select
End Sub
For example, to load the Beatles form without displaying it, use this statement:
Load Beatles
The Load statement sets a form ' s properties to their initial values and executes its
Form_Load procedure. For more information on the Load statement, see the Language
Reference, or:
Unloading Forms
You can unload form s when you no longer need them. When you unload a forrn , the form is
removed frorn the screen and from memory; you can no longer refer to any of its properties
or controls. Any data stored in the form is lost unless you have saved it to a file (as
explained in Chapter 21, "Processing Files"). For exarnple, this statement unloads the
Welcome form:
Unload Welcome
If there' s a chance you may want to use the form later, you may want to use the Hide
method instead. Hiding a form stores it in memory; this makes greater demands on memory
but can improve response time later on. Conversely, unloading a form frees up memory but
requires that you load the form again when you want to reuse it.
For more information on the Unload statement, see the Language Reference , or:
Note that when you close an application thi s way, no Form_Unload procedures get called. A
Form_ Unload procedure is called only if you explic itl y unload a form.
Visual Basic provides tools to analyze how your application behaves. These are called
debugging tools because they are particularly useful in locating the source of bugs (errors) .
Debugging support includes breakpoints, single stepping, and the ability to display the
values of variables and properties. These are fairly standard debugging techniques. Visual
Basic also includes special capabilities, sorne of which are inherited from Microsoft
QuickBasic: edit-and-continue capability, setting the next statement to be executed, and
testing procedures while halted. Plus, Visual Basic enables you to examine what happens to
property settings.
This chapter shows how to use the debugging tools included in Visual Basic. The main
sections are:
• Approaches to Debugging
• Design T~e, Run Time, and Break Mode
Halting Execution at a Problem Statem~nt
• Running Selected Portions of Your Application
• Testing Data and Procedures with the lmmediate Window
• Special Considerations in Debugging Events
• Testing and Using Command-Line Arguments
228 Part 3 Application -Building Techniques
Approaches to Debugging
The debugg ing techniques presented in thi s chapter are actually a set of analysis tool s.
Vi sual Basic cannot diagnose and fix all of your errors far you , but it does provide tools to
analyze how execution flows from one part of the application to another, and how variables
and property settings change as statements are executed. Debugging tool s are a way of
looking inside your application; they can help you determine what happens and why.
To understand how this is useful, consider the three kinds of errors you can encounter:
• Syntax errors . These errors are the result of a statement that is incorrectly constructed.
You may have mistyped a keyword,- omitted sorne necessary punctuation, or forgotten to
balance pairs of If and End If statements. Visual Basic detects these errors as soon as
they are entered in the Code window.
• Run -rime errors. These erro rs occur (and are detected by Vi sual Bas ic) whe n a statement
attempts an operation that is impossible to carry out. A good example is division by zero.
Suppose you have this statement;
Speed = Mi les / Hour s
If Ho u r s contains zero, the division is an invalid operation, even though the stateinent
itself is syntactically correct. The application must run befare it can detect thi s error. Not
all run-time errors are easily fixed . For example, a "Disk ful! " error is a problem you
can ' t foresee when writing the application. For information on dealing with this kind of
error, see Chapter 19, "Handling Run-Time Errors."
• Program logic errors. An application is not really correct unless it performs the way it
was intended to. An application can have syntactically valid code, run without
pe1fo rmin g any invalid operations, and yet produce incorrect results. Onl y by tes tin g the
application and analyzing results can you verify that the application is performin g
correc tly .
Debugging tool s are designed to help you with the last category - program logic errors,
which can be far more elusive tlían syntax errors or run-time errors. For instance, an
incoITect result may be produced at the end of a long series of calculation s. In debugging,
the task is to determine where something went wrong. Perhaps you forgot to initialize a
vari able, chose the wrong operator, or used the wrong formula somewhere.
There are no magic tricks to debugging, and there is no fixed sequence of steps that works
every time. Bas icall y. debu gg ing in volves understanding what's go ing on durin g runn ing of
the appltcaLion . rhe be LLer yo u understand how your appli cation works, the fas ter yo u can
find a bug. Debugging is easier if you :
• Design your applications carefully by writing down the relevant events and how your
code will respond to each one. Give each event procedure and each general procedure a
specific, well-defined purpose.
• Include numerous comments. As you go back and analyze your code, you ' 11 understand it
much better if the purpose of each procedure is stated in comments.
• Develop a consistent naming scheme for the variables in your application. One of the
most common sources of errors is mistyping a variable narne. Visual Basic creates an
implicitly defined local variable if it can't find a matching declaration.
1111 When your application doesn't produce correct results, browse through the code and try
to find statements that may have caused the problem. Set breakpoints at these statements
and restart the application. Breakpoints are described in the section "Halting Execution at
a Problem Statement" later in this chapter.
• When the program halts, test the values of important values and properties. With Visual
Basic, you use the Immediate window to examine variables and expressions.
Note The Visual Basic title bar (iust above the Properties bar) always shows you which
mode you are in, by displaying "[design]," "[run]," or " [break]."
Break mode enables you to both edit code and run it. Before you entera new statement, you
can first test its effects by entering it in the Immediate window. The Immediate window has
a number of uses, the most common of which is to evaluate variables and property settings .
Whenever you enter break mode, execution has stopped at a particular statement. The
variable and property settings are retained, so you can use the Immediate window to analyze
the exact state of the application at that point.
Once in break mode, you can start running your application again by choosing Continue
from the Run menu . This command resumes execution from the last point at which it
stopped. Y ou can retum to design time by choosing End from the Run menu .
The nex t section describes theways of entering break mode when your application is
runnmg.
The applicati on also switches into break mode if, during running of the application, you
press CTRL+BREAK or choose Break from the Run menu. It's possible to break execution
when th e applica tion is idle (when· it is between processing of events); when this happens,
execution does not stop ata specific line, but Visual Basic switches to break mode anyway .
Forml
Object: IForm li] Proc: 1Click w
Sub Form Click () •
A~%-= Ual(AgeText.Text)
liZ!litiffi - RestRateText. Textl
TrainRate% = ((220 - Age% - RestRate%) * .65) + RestR
Readout.Text.Text = Str$(TrainRate%) + "beats per min
End Sub
Microsoft Visual Basic
¡OK¡
+
+ +
In the case of the type mismatch, the solution is to fix the problem statement so that it places
the correct type of data (numeric) into the variable Res t Ra te%:
RestRate% = Val (RestRateT ext .Te xt)
Then you can continue program execution from the same place it halted, even though you've
changed sorne of the code; just choose Continue from the Run menu. As you continue
running the application, you can see if the problem is fixed. Sorne changes (most commonly,
changes in variable declarations) do require the application to start over again; but when this
happens, Visual Basic notifies you that you must restart the application.
To set a breakpoint:
Tn th c Code window. movc thc i11<..crt ;1rn point to a lin c of codc that does not airead y ha,·c
a breakpoint.
2 From the Run menu, choose Toggle Breakpoint.
-or-
Press F9.
Visual Basic displays the selected line in bold.
To clear a breakpoint:
1 In the Code window, move the insertion point to a line of code that has a breakpoint (the
line is di spl ayed in bold).
2 From the Run menu , choose Toggle Breakpoint.
- or-
Press F9 .
Visual B asic displays the selected line in a plain font.
For exampl e, Figure 16.2 show s a procedure halted at the third line, which has a breakpoint.
Note the rectangular outline around the statem ent at which the procedure halted. This o utline
indicates the next statement to be execu ted ; thi s is called the current statement.
Once a breakpoint is reached and the appli cation is halted, you can examine what 's
happened up to tha t point. Examining results of the application is easy, because yo u can
move the focus back and forth be tween th e form of your application and the Code window.
lf 1he rrohlem yn11 ~re lnokin !:! for 1-w; alrcacly nccu rrecl . th en you know a rrc\ io u, !:,-
execu ted line of code caused the problem . lf not, then sorne line of code not yet exec uted is
ca usin g the problem .
R eme mber that when a breakpoint occ urs, th e application stops just before th at I in e is
exec uted. Therefore, if the line of code wi th th e breakpoi nt is responsible for th e probl e m,
you won ' t see the problem until yo u exec ute at least one more statement. Single stepping ,
di sc ussed later in thi s chapter, may be h elpful to yo u in thi s regare! .
A word of caution: Although no line of code has directly caused the problem, a statement
may indirectly be at fault, because it assigns an incorrect value to a variable. You may want
to examine the value of variables and properties whüe in break mode. The section "Testing
Data and Procedures in the Immediate Window" later in this chapter explains how to do that.
Note There is one important difference between a Stop statement and a breakpoint. If you
leave the current project (or leave Visual Basic) and then load it again, all breakpoints are
cleared. Stop statements are more permanent; they stay in the code until you remove th em.
Remember that (unlike tbe End statement, which terrninates all execution) a Stop statement
does nothing more than temporarily halt execution. You can always choose Continue from
the Run menu to resume running the application.
For more information on the Stop statement, see the Language Reference, or:
During a single-step command, Visual Basic temporarily switches into run time and
executes the current statement. Then it switches back to break mode and advances to the
next statement.
Note A line of code can contain two or more statements, separated by a colon(:). Visual
Basic uses a rectangular outline to indicate which of the statements to execute next. Unli ke
the Microsoft CodeView debugger and most other debugging tools , Visual Basic enables
you to single step between individual statements, even if they are on the same line.
However, breakpoints are always set on the first statement of a line.
Procedure Stepping
Procedure stepping is identical to single stepping, except when the current statement
contains a call to a procedure. The Single Step command steps through each line of the
procedure that was called, but the Procedure Step command executes the called procedure as
a unit and then steps to the next- statement in the current procedure. For example, suppose
the statement calls the procedure SetAlarmTime:
SetAlarmTime 11, 30, 0
If you choose the Single Step command, the Code window displays the SetAlarmTime
procedure and sets the current statement to the beginning of that procedure. This is the best
choice if you want to analyze the code within SetAlarmTime.
If you use the Procedure Step command, the Code window continues to di splay the current
procedure. Execution advances to the statement immediately after the call to SetAlam1Time.
Thi s is th e best choice if you want to stay at the same level of code and don ' t need to
analyze how SetAlarmTime works.
Y ou can freely altemate between the Single Step and Procedure Step commands . The
command you use depends on which portions of code you want to anal yze at any given time.
Visual Basic enables you to start execution at a different line of code as long as it is within
the same procedure.
Note You must be in break mode to set the next statement to be executed. The Set Next
Statement command is not available at design time or run time.
Y ou are clearly not done, however. First, you must determine what the val ue of
My Fo rmC o 1 o r was just befare the statement was executed. Second, yo u must determine
where My Fo rmC o l o r was assigned the incorrect value.
Examining the values of variables and properties is a common use for the Immediate
window. In addition, you also can use the Immediate window to assign values, evaluare
expressions, and test procedures .
There are two ways to print to the Immediate window: by placing statements in the code for
your application, or by entering a statement in the Immediate window itself.
For example, the following statement prints the value of Sal a ry to the Immediate window
every time it is executed:
Debug.Print "Salary - " ; Salary
This technique works best when there is a key place in your application code at which the
variable (in this case, S a 1 ar y) is known to change. For example, yo u mjght put the previous
statement in a loop that repeatedly alters Sal ary .
This technique has a couple of adv antages. First, yo u don ' t have to break execution to get
feedback on performance. You can see data or other messages displayed as yo u run the
appli cation. Another advantage is that th e feedback is di spl ayed in a separate area (the
Immediate window) , so that it does not interfere with output intended for users to see.
For more information on the Debug object, see the Language Ref erence, or:
A ques ti on mark (?) is useful shorthand fo r the Print keyword. The question mark means
precisely the same thing as Print and can be used in any co ntext Print is used. For example,
the examples above coul d be entered as shown in Fig ure 16.4.
Note that you can di splay variables only if they have the appropriate scope relative to the
current statement. Whenever Visual Basic enters break mode, the Code window comes to
the foreground , identifying:
• The currently executing form or module (indicated in the Code window' s title bar) .
• The currently executing procedure (displayed in the window).
• The next statement to be executed (identified by a rectangular outline) .
In addition, the title bar of the Immediate window indicates what the current form or module
is. This way you always know which form or module is current, even if you move the focus
between different Code windows.
The current procedure, form, and module determine what variables can be displayed
according to the scoping rules presented in Chapter 9, "Language Elements." For example,
suppose the Immediate window indicates th at Form 1 is the current form . In thi s case, you
can display any of the form-level variables of Forrnl. You also can display local variables of
the procedure displayed in the Code window. But you can' t display variables of other forms
and modules.
Ass ume that Textl is a control on the currently executing forrn. The first statement prints to
the Immediate window the numeric value of the current forrn's background color. The
second statement prints the height of Text 1.
If execution is suspended in a module, you must explicitly specify a form:
? Forml.BackColor
? Forml.Textl.Height
The first two statements above alter properties of the currently executing form. The third
statement assigns a value to a variable. If execution was stopped in a module (or if you want
to refer to properties or controls of a different form) , it's necessary to refer to a form
explicitly, as described in the previous section.
After you set the values of one or more properties and variables, you can continue execution
to see th e res ults. Or, you can test the effect on procedures, as described in the next section.
Testing Procedures.
The Imrnediate window evaluates any valid Visual Basic executable statement. This window
won ' t accept data declarations, but you can enter calls to Sub and Function procedures.
Therefore, you can test the possible effect of a procedure with any given set of arguments by
entering a statement in the lmrnediate window just as you would enter it into the Code
window . For exa mple:
X - Ouadratic (2. 8. 8)
DisplayGraph 50, Arrl
Form_ MouseDown 1, 0. 100. 100
Visual Basic responds by switching to run time long enough to execute the statement, then
retums to break mode. At that point, you can see results and test any possible effects on
variables or property values.
Scope appli es to procedure calls just as it does to variables. You can call any procedure
within the curren tl y executing form . You can always calla procedure in a module.
Note Although al! executable statements are supported in the Irnmediate window , a control
structure is val id only if it can be completely expressed on one line. Thus, the following For
loop is va lid in the Immediate window :
For I = 1 To 20 : Print 2 * I : Next I
When you move the insertion point back to a Print staternent (or staternent with a question
mark), bear in rnind that Visual Basic overwrites old staternents in the Irnrnediate window as
it prints each line of output. This rneans that unless you append a sernicolon (;) to the end of
the Print statement, it overwrites two staternents. For exarnple, suppose you rnove the
insertion point to the first of the three lines below:
? X
55
? Y* 20
Pressing ENTER prints the current value of X on the second line and then places the insertion
point at the beginning of the third line. The third line also is cleared. To avoid erasing the
third line, append a sernicolon to the first line:
? X
55
? Y* 20
The Command$ function (intrinsic to Visual Basic) retums all arguments entered after the
application name (in this case, Alarrn). The Alarm application has just one argument, so in
the application code, you can assign this argument directly to the string that stores the time
to watch for:
AlarmTime - Command$
For more information on the Command$ function, see the Language Reference , or:
••••
••••
Advanced Language Features
Chapter 9, "Language Elements," presented enough information to help you understand the
application-building techniques discussed in Part 3 and to write sorne useful applications.
But Visual Basic has a number of refined features designed to meet special needs. As you
write larger applications, you'll find that sorne of these features are very helpful.
If you have experience in Microsoft QuickBasic or the Basic Professional Development
+ System, most of the features presented here are already familiar to you. Note, however, that
they are not precisely the same in every case. You should read carefully before you assume
that Visual Basic works justas other Basic products do.
The main sections in this chapter are:
•
•
•
Controlling Execution
Data Declaration
Arrays
-
• The Global Module
• Type and Constant Definitions
244 Part 4 Advanced Appl ications
Controlling Execution
The next three sections describe how to place control structures inside other control
structures and how to use different versions of the Exit statement. A control structure inside
another control structure is said to be nested.
Nested control structures work in a similar fashion. Especially comrnon are nested For
loops, which handle arrays of strings and multidimensional arrays. For example, the
following code prints tables of multiples for numbers from 1 to 20:
Dim I As Integer, J As Integer
Far I - 1 To 20
Print "Multip les of "; I·
Far J - 1 To 10
Print Chr$(9) ; l*J;
Next J
Print
Next I
The I loop is the outer loop ; for each increment of I , J run s an entire cycle from 1 to 1O.
Note that each Next statement applies to the nearest For statement. Thus, the first Next
terminates the I loop, and the second terminates the J loop.
The previous two examples show nested If statements and nested For loops. But you are not
limited to nesting a control structure inside another of the sa me type. You can nest contro l
structures to any level and in any combination .
The Exit Do statement works with ali versions of the Do loop syntax. An important
difference between Do While ... Loop and the While ... Wend statement is there is no way to
exit directly from While ... Wend.
Exit For and Exit Do are useful because sometimes it's appropriate to quita loop
immediately, without performing any further iterations or statements within the loop. For
example, suppose you want to test a number to see if it is a prime number. (A prime number
is an integer that is only divisible by itself and the number 1.) The pseudocode for a prime-
number test on a number N might be:
Ass ume Ni s prime
Determine square root of number N
For each number from 2 to square root of N
If number evenly divides N
Ni s not prime
Stop te s ting numbers
A first attempt to write a prime-number Function procedure might look like this:
Function Prime (N As Integer) As Integer
Const TRUE - - 1. FALSE= 0
Dim R As Integer, I As Integer
Prime= TRUE
R - Sqr(N)
For I = 2 To R
If N Mod I = 0 Then
Prime= FALSE
End If
Nex t I
End Fun cti on
This procedure produces correct results, but it's inefficient; it doesn' t stop testing numbers
when a divisor of N is found. Once it's determined that Ni s nota prime number, it's no
longer necessary to continue the For loop. Therefore, a more efficient version uses Exit For
to termínate the loop once it is deterrnined that N is not prime. The statements are the same
except for the For loop:
Far I - 2 To R
If N Mod I = 0 Th en
Prime - FALSE
Exit For
End I f
Next I
Note that the Exit statement almost always appears inside an lf state ment or Select Case
statement nested inside the loop.
Prime= TRUE
R = Sqr(N)
For I = 2 To R
If N Mod I 0 Then
Prime - FAL SE
Ex i t Function
End I f
Next I
End Fun ction
Data Declaration
You can declare Static variables when you want procedures to have persistent data, and you
also can declare data using the following special types: Form, Control , and fixed-length
strings. The next several sections describe these advanced techniques.
Static Variables
Normally, when a procedure is finished, the values of its local variables are lost. The next
time the procedure is executed, all local variables start at zero oran empty string.
You can make Visual Basic preserve the value of a local variable by making it static. Use
the Static keyword to declare one or more variables inside a procedure, exactly as you
would with the Dim statement:
Static X As Oouble, Y As Double
Static Counter As Integer
For example, the following Click procedure changes the background color back and forth
between two values. The procedure must remember the previous state it was in, and uses a
static variable, Fl a g, for this purpose:
Sub Form_Click ()
Static Flag As Integer
If Flag - 0 Then
BackColor - RGB (255, 0, 0)
Flag - 1
El se
BackColor = RGB (0, 128, 128)
Flag= 0
End If
End Sub
Yo u also can produce the same result by declaring Fl a g in the Declara ti o ns section of the
form, making it into a form-level variable. However, once you change the scope of a
variable this way , the procedure no longer has exclusive access to it.
This causes all the local arguments in the procedure to be considered static, regardless of
whether they are declared with Static, Dim , or declared implicitly. Each time the procedure
is called, it remembers the values of the local variables from the last time the procedure ran.
You can place Static in front of any Sub or Function procedure headin g; this includes both
event proced ures and general procedures.
By includin g an argument of type Form, you can write a procedure that assigns these colors
for any form:
Sub SetColor s (ThisForm As Form)
This Form.BackColor RGB(0 , 0, 128)
ThisFo rm.F or eColo r RGB(l92, 0, 0)
ThisF orm.Draw Colo r RGB(255, 255, 255)
End Sub
You then ca n call the procedure and pass the name of any form yo u wish as an argument:
Se t Colors Forml
SetC olors Form2
Se t Colors Form3
Form and Control variables have two important res trictions that do not apply to other types:
• You ca n use them onl y in arg ument lists, not in other kinds of variable declarations.
• You ca nnot assign va lues directly to Form or Control arg uments at any time. Yo u can ,
however, assign values to their properties.
You can use this procedure with any number of different controls (except timers, which have
no Visible property):
Cloak Te xtl
Cloak Text2
Cloak Pi cture l
Using a Control argument requires extra care, since different types of controls support
different sets of properties. Visual Basic generates a run-time error if you access a
nonexistent property of a Control argument.
For example, the followin g fragment works correctly for text boxes, because text boxes have
a Text property:
Sub InitBox (TextBoxCont r ol As Control)
Therefore, you can pass a text box to thi s proced ure without getting an error:
InitBo x Tex tl
But the following statement causes a run-time error, assumi ng Commandl is a command
button . This statement passes the command button as an argument to InitBox, whi ch then
refers to the Text property. Because command buttons don ' t have a Text property, Vi sual
Basic generates an error:
InitB ox Commandl
To ensure that this error does not happen, you may want to test the type of the co ntrol by
using the Typeüf keyword , as described in the next section .
The TypeOf and Is keywords appear only in exactly that form of syntax. You can test for
only one control type ata time, and you cannot combine that syntax with other conditions on
the same line. However, an lf Typeüf or Elself TypeOf statement can be part of a larger If
block that tests for other conditions . For example:
If X= 3 Then
Print X
Elseif Typeüf ThisControl Is Timer Then
Thi sControl. Interval ~ 1000
End I f
The control is an argument declared As Control. The controltype is one of the following
keywords:
CheckBox Frame PictureBox
ComboBox HScrollBar TextBox
CommandButton Label Timer
DirListBox ListBox VScrollBar
DriveListBox Menu
FileListBox OptionButton
For example, the following fragment places a string in a control if the control is a text box :
Sub InitMyControl (Sou rce As Control)
Sometimes you may want to take an action if a control is not a particular type. Although you
can' t combine the Not keyword with Typeüf, you can produce the same effect by including
an empty statement block combined with an Else clause. For example, the following code
sets the Visible property to O if ThisControl is not a timer:
lf TypeOf ThisControl Is Timer Then
Else
ThisControl.Visible = 0
End If
Fixed-Length Strings
By default, a string variable or argument is a variable-length string; the string grows or
shrinks as you assign new data to it. Y ou also can declare strings that always have a set
length. Y ou specify a fixed-length type wi th this syntax:
String * size
Fixed-length strings are use ful in random-access file operations (as explained in Chapter 21,
"Processing Files"). Or, suppose you want to print a report and you want a string to always
take up the same amount of space. For example, this statement declares EmpName as a fixed-
length string of 30 characters:
Dim EmpName As String * 30
If you assign a string of fewer then 30 characters, EmpN ame is left-justified and padded with
trailing spaces.
You can freely altemate between fixed-length and variable-length strings. If you assign a
string that is too long for the fixed- length string, it simply truncates the characters. For
example:
Dim String5 As String * 5, Mammal As String
String5 = Mammal
Print String5
Because fixed-length strings are often padded with trailing spaces, you may find the intrinsic
RTrim$ function useful when working with them. For more information on RTrim$ , see
the Language Reference, or:
Arrays
If you have programmed in other languages, you ' re probably familiar with the concept of
arrays. Arrays enable you to refer to a series of variables by the same name, and use a
number (an index) to tell them apart. This helps you create smaller and simpler code in many
situati ons, because you can set up loops that deal efficiently with any number of cases by
using the index number.
In additi on, Visual Basic introduces a new kind of array - the control array. A control array
has special features and does not follow all the rules of standard arrays. The differences are
explained below.
lmportant Although co ntrol arrays are similar to other kinds of arrays, they differ in a number of
details . What Visual Basic documentation says about arrays generall y does not apply to
control arrays, unless specifically stated.
Control Arrays
Visual Basic requires the use of control arrays in two situations:
• Writing code far menus that grow or shrink
• Creating new co ntrols at run time
Chapter 1O, "Responding to Commands," and Chapter 13, "Creating Graphical Effects,"
introduced co ntro l arrays and explained their use far these purposes.
However, you ca n use control arrays at other times. Even thou gh it may have man y
elements. the entire control array has only one event procedure far eac h type of even t (Click,
KeyPress, and so on). Creating a control array makes sense when a number of controls can
benefi t from sharing most of their code.
Control arrays do preserve sorne flexibility. Whenever any control in the array recogni zes an
event, Visual Basic passes the indexas an extra argument. This argume nt always comes
befare any other arguments that may be passed. For example:
Sub MyCtlArray_ KeyPress (Index As Integer, KeyAscii As Integer)
Once inside the event procedure, yo u can use lndex to determine which control actually
received the event. An element of a control array can be referred to as:
arrayname (/ndex)
Thus, MyCtlArray(0) and MyCtrlArray(l) refer to specific elements in a contro l arra y, and
can be used anywhere ordinary control names are used.
Y ou create a control array at design time, either by assigning two controls the same name
(CtlName property), or by assigning a value to a control's Index property. The latter
technique produces a control array of just one element. This is useful when you want to
create controls at run time, but don't want to start with a lot of controls.
Control arrays are limited to one dimension. Visually, you can create a grid of controls, but
within the code, each control is identified by a single number.
The lower bound of any control array is zero, and index numbers can run as high as the
system resources allow. Unlike ordinary arrays, you can skip index numbers. MyCtlArray(l)
and MyCtrlArray(9) may both correspond to controls, even though there are no controls with
index numbers from 2 to 8. When you first create a control array, Visual Basic assigns
default index numbers, starting at O and increasing by increments of 1 as each new control is
added to the array. You then can change indexes by resetting each control's Index property .
Note that indexes can be reassigned only at design time.
Note Another lirnitation on control arrays is that, unlike a standard array, a control array
cannot be passed as a single argument. Each element of the control array must be passed as a
separate argument.
Arrays of Variables
Like other languages, Visual Basic enables you to define arrays of standard data types. An
array is a series of memory locations that share the same name and are identified by an index
number. Unlike control arrays, standard arrays have both upper and lower bounds, and there
are no empty elements. Visual Basic allocates space for each index number, so don't declare
an array larger than you need it to be.
Visual Basic has three important rules regarding ordinary (fixed) arrays:
• In the global module, use the Global statement to declare array_s.
• At the form or module leve!, use the Dim statement to declare arrays.
• Within a procedure, use the Static statement (although you can use Dim if the whole
procedure is declared Static). For more inf~rmation, see "Static Variables" earlier in this
chapter.
The rules change when you create a dynamic (variable-length) array. The section "Dynamic
Arrays" later in this chapter discusses these rules.
When declaring an array, follow the array name by parentheses and the upper bound. The
upper bound must be an integer. For example, these array declarations can appear in the
Declarations section of a form or module:
Oim Cou nter s (14) As Integer
Dim Sums (20) As Oouble
In the global module, you simply use Global in place of Dim . The same declarations within
a procedure use Static :
Static Cou nter s (14) As Integer
Stat i c Sums (20) As String
The first declaration creates an array with 15 members, with index numbers running from O
to 14. The second creates an array with 21 members, with index numbers running from O to
20. The default lower bound is O. However, you can change the default lower bound to l by
placing an Option Base statement in the Declarations section of a form or module:
Option Base 1
For more information on the Option Base statement, see the Language Reference, or:
Another way to specify lower bounds is to use the To keyword (a lower bound also must be
an integer):
Dim Counters (1 To 15) As Integer
Oim Sums (1 00 To 120) As String
ln the declarations above, the index numbers of Counters run from 1 to 15 , and the index
numbers of Sums run from 100 to 120.
Note Other versions of Basic permit implicit declaration of arrays; Visual Basic <loes not.
You must declare an arra y before using it.
Arrays are an efficient way to handle many array elements in a loop. Each element is
accessed through a combination of the array name and index. For example, if the lower
bound of array Counters is 1, then the third element of the element is :
Counters(3)
Two-Dimensional Arrays
Sometimes information is naturally represented in a grid, or matrix - a data structure that
has both rows and columns. You can declare two-dimensional arrays that reflect the
structure of a grid. For example, the following statement declares a 10-by-10 array within a
procedure:
Static MatrixA (9 , 9) As Double
Once you declare a two-dimensional array, you can efficiently process it by using nested
For loops. For example, these statements initialize every element in Má tri xA to 1:
Dim I As Integer, J As Integer
Sta tic MatrixA (1 To 10, 1 To 10) As Double
For I = 1 to 10
For J - 1 To 10
MatrixA(I, J) = 1
Next J
Next I
Multidimensional Arrays
With Visual Basic, you can declare arrays of up to 60 dimensions. Each dimension is
declared by giving an upper bound and optionally a lower bound . For example:
Dim MultiD (3, 1 To 10, 1 To 15)
This declaration creates an array that has the dimensions 4 by 10 by 15. The total number of
elements is the product of these three dimensions, or 600.
Note When you start adding dimensions toan array, the total storage needed by the array
increases dramatically, so be careful in the use of multidimensional arrays.
Generally, multidimensional arrays are useful for highly specialized mathematics and
science applications (although three-dimensional arrays are useful in projected graphics) .
Most applications rarely require arrays of more than two dimensions.
Dynamic Arrays
Sometimes, you may not know exactly how lar.ge to make an array. You may want to have
the capability of changing the size of the array at run time.
A dynamic array can be resized at any time. Dynamic arrays are among the most flexible
and convenient features in Visual Basic, and they help you to manage memory efficiently.
For example, you can use a large array for a short time, then free up memory to the system
when yo u' re no longer using the array.
The alternative is to declare an arra y with the largest size possible, and then just ignore arra y
eleme nt s you don 't need. However, this approach wastes storage and, if used often, might
even cause your application to run low on memory .
The ReDim statement can appear only in a procedure. Unlike the Dim and Static statement,
ReDim is an exec utable statement - it makes the application carry out an action ar run time.
The ReDim statement supports the same syntax described in the Jast few sec tions far fixed
arrays. Each use of ReDim can change the number of elements, and lower and upper bounds
far each dimension. However, the number of dimensions must not change.
important Each tim e you execute the ReDim statement, all the values currently stored in the array are
lost. Visual Basic resets the values to zero-or, in the case of strings, to the empty string.
Far examp le . the dynamic arra y Ma tri x 1 is created by first declaring it at the farm leve!:
Dim Matrixl () As Integer
The ReDim statement allocates a matrix of 20 by 30 integers (at a total size of 600
elements) . Alternatively, the bounds of a dynamic array can be se t using variables:
ReDim Matrixl (X. Y)
When you create a dynamic array that is local to a procedure, th e first step above
(declaration with Dim at the beginning of the procedure) is recommended but not req uired.
Declaring a dynamic array first with Dim limits the number of dimension s to 8. lf" you need
more dimensions, avoid using Dim and create the array directly with ReDim :
ReDim BigArr (A. B. C. D, E. F. G. H. I) As Integer
Note Thi s techn ique supports the normal limit on the number of dimensions (60) .
Each project has exactly one global modul e, although you may find that you don ' t use it for
simple applications with a single form. Yet even for small projects, the global module is
con venient if you include any constant defi nitions from the CONSTANT.TXT fil e. These
definiti ons are written using the Global keyword, so they must be placed in the global
module or else rewritten.
Unlike other modules, the global module cannot include any procedures. The global module
is like one large Declarations secti on; it has no definite subdivisions.
The global module can include:
• Global variable declarations.
• Deftype statements. These statements, introduced later in this chapter, determine the
default type of variables. When placed in the global module, Deftype statements affect
only the data type of global variables.
• Global constant definitions.
• User-defined type statements. These are similar to structures or records in other
languages .
Type . .. End Type , whi ch crea tes a user-defi ned type, can be pl aced onl y in the global
module. Once created, a user-defi ned type can declare a vari able at any leve!. The section
"User-Defin ed Types" at the end of this chapter describes how to create and use these types .
In contras t, variable declarati ons and constant definition s can be placed in form s, modul es,
and procedures, but are not global in scope when placed at those levels.
Variabl e declarati ons and constant definiti ons use a different syntax at the global leve]:
• In variable declarati ons, the Dim keyword is repl aced by Global.
• In constant dec larati ons, Global must precede Const.
The fo ll owing examples show a variab le and constant decl arati on at the modul e leve], and
the sa me statements rewri tten so they ca n be 1:1 sed in the global modul e.
Form-level statements Rewritten for the Global module
Dim Salary As Currency Global Sal a ry As Curre ncy
Di m X Gl obal X
Co ns t FAL SE 0 Glo bal Co nst FAL SE 0
Symbolic Constants
Often, you ' ll find your code is sprinkled with constant values that appear over and over. Or
you may find that your code depends on certain numbers that are difficult to remember, and
(in and of themselves) , have no obvious-meaning unless you look up their significance.
Man y such numbers are recorded in CONST ANT.TXT.
In these cases you can greatly improve the readability of your code and make it easier to
maintain by using the Const statement. This statement enables you to use a meaningful
name, called a symbolic constant, in place of a number. In sorne respects, a constant
definition is like a variable. But unlike a variable, the value of a constant cannot change
during program execution .
A Const statement has scope just as a variable declaration does, and the same rules apply. If
you want to make sure a constant definition is recognized throughout the application, place it
in the global module and put the keyword Global before Const.
The syntax for a Const statement is:
[Global] Const constantname =expression [, constantname = expression ] ...
The argument constantname is a valid sy mbolic name (the rules are the same as the rules for
creating variabl e names), and expression is made of numeri c or string constants.
A Const state ment can represe nt a mathematical qu antity:
Co nst PI = 3 .1 4159265
Co nst SQROOT2 = 1.41421356
Co nst E= 2.71828 183
TRUE and FALS E constants are useful wherever you need to set a Boolean ·property :
Co nst TR UE = - 1 , FAL SE = 0
Once you define co nstants, you can place them in your code to make it much more readable.
For exa mpl e:
Che c kBox . Va lu e = TRUE
Angle = PI
Angl e2 = PI / 2
The ex pression on the ri ght side of the equal sign (=) is ofte n a number, but also can be an
ex press ion that produces a num e ric or string result (although it cannot contain call s to
fun cti ons) . You ca n even defin e constants in term s of previously defined constants:
Con s t PI 2 = PI * 2
Deflnt is a Deftyp e statement; without this statement in the example above, you'd have to
add an As Integer clause to each of the variables in the list.
A Deftype statement can be placed in the global module, or in the Declarations section of a
farm or module. The statement affec ts the default type of all variables in that farm or
module. Thus, Deftype statements in the global module determine the default type far global
variables, but have no effect on other variab les. Deftyp e statements in a farm affect farm-
level variables as well as local vari ab les in procedures attached to that farm . It' s the same far
modules .
Vi sual Basic supports six different kinds of Deftype statements, one far each data type.
Statement Associated data type
Deflnt letterrange Integer
DefLng lette rrange Long
DefSng letterrange Single
DefDbl letterrange Double
DefCur letterrange Currency
DefStr lette rrange String
With each statement, lette rrange is either a single letter ora range of letters described by this
syntax :
letterl [-letter2 ]
You also can specify a combination of ranges, separated by commas. Thus, the followin g are
all valid state ments:
' Declarations
Deflnt A- E, I - M, T
Deflng F
DefDbl X- Z
The range A-Z is a special case. Thi s range, and only thi s range, causes the default-type
range to include ali international characters as well as the letters in the English alphabet.
lmportant You can place Type definitions only in th e global module. The Type statement is not valid
anywhere else .
End Type
In thi s syntax displ ay, usertype is the name yo u c hoose for the new type. Each elementname
specifies a field of data within the user-defi ned type. The elementname fo llows the same
rules of Visual Basic vari ab le names, and eac h elementname has a corresponding typename .
The typename indicates what kind of data is stored in that field. This type can include any of
the standard data types, including variable-length strings. The type also can be another user-
defi ned type that has been previously defined.
Note Other versions of Basic require that strin gs in user-defined types be fixed-length
strings . Vis ual Bas ic supports vari able-length strings (the standard condition of strings) in
user-defined types . However, Visual Basic doesn' t support arrays inside user-defi ned types .
The following user-defined type includes a double-precision floating-point number and two
variable-length strings. Note that fixed-length strings should be used if the type is intended
for random-access file operations:
Type StateData
Gov As String * 30
StateBird As String * 20
PerCapincome As Double
End Type
Once a user-defined type is declared in the global module, you can use the name of the type
as part of a variable declaration, just as you would with any of the standard types:
Dim I As Integer
Oim California As StateData
Dim USA (1 To 50) As St ateData
Far example, the following statement places the name "Cary Grant" in the Gov field:
California.Gov = "Cary Grant"
Microsoft Windows and Presentation Manager provide access to a number of special system
resources, including the Clipboard, system time, idle-loop processing, and low-level
keyboard handling. By taking advantage of these features, you can give your applications the
extra flexibility that polished, professional applications often require.
For example, although the techniques in Chapter 1O, "Responding to Commands," cover the
most typical use of the keyboard, only the low-level keyboard handling in this chapter gives
,n, you complete access to the keyboard - including the arrow keys and the numeric keypad.
Visual Basic supports simple, direct hooks into a number of operating environment
resources. As this chapter demonstrates, it' s possible to create a useful digital clock
application with only one line of code. Small enhancements can then tum the application
into an alarm clock or give it other custom features .
The main sections in this chapter are:
• Working with Selected Text
• U sing the Clip board Object
• Using Timer Controls
• Writing Idle Loops with DoEvents
• Writing Low-Leve.l Keyboard Handlers
••••--
--
--
-
264 Part 4 Adv anc ed Appl ic ations
Yo u can actually control w hat tex t is se lected by setting the Se!Star t and SelLe ngth
properties. Far example, these statements hi ghli ght ali the tex t in a text box :
Textl.SelSta r t = 0 Start hig hlight befare f i rst c haracter.
Textl.Se ll ength = Len ( Textl .Text ) ' Highlight to end of text.
If yo u assign a new stri ng to Se lTex t. the new stri ng repl aces whatever text is se lected. T he
hi ghli ght is the n removed and th e in sertio n point is placed j ust after the e nd of the newly
in se rted text. Far example, the following statemenl replaces the se lected text with the string
'Tve just bee n inserted !":
Tex tl.SelText = " I've just been inserted !"
lf no tex t was selected , the string is simply pas ted in at the in se rt ion point.
Fa r more informati on on the Se!Start , Se!Length , and Se!Text properties, see the Language
Reference , o r:
Abe!
SetText - - - - - - - . ~
~ - - - - - - ~ , . ----GetText
Abe! _...--
- -w
Textboxes Environment
Clipboard
Figure 18.1 Moving data to and from the Cl ipboard with SetText and GetText
SetText copies text onto the Clipboard, replacing whatever text wa·s stored there before. You
use SetText like a statement, and its syntax is:
Clipboard.SetText data$[, format o/o ]
GetText returns text stored on the Clipboard. You use it like a function :
destination = Clipboard.GetText ( )
By combining the SetText and GetText methods with the selection properties introduced in
the previous section, you can easi ly write Copy, Cut, and Paste commands for a text box .
The following procedures implement these commands for controls named CopyCmd,
CutCmd, and PasteCmd:
Sub CopyCmd_Click ()
Clipboard.SetText Textl . SelText
End Sub
Sub CutCmd_Click ()
Clipboard.SetText Textl . SelTe xt
Textl. SelText -
End Sub
Sub PasteCmd_Click ()
Textl.SelText - Clipboard.GetText()
End Sub
Note The example works best if these controls are menu commands, because you can use
menus while Tex tl has the focus .
Let' s examine two of these statements. In the Copy command, the statement consists of two
components: the SetText method andan argument (Textl .SelText) passed to that method.
The statement tells Visual Basic to copy the tex t selected in Textl to the Clipboard:
Cl ipboard.SetTe xt Textl.SelText
In the Paste comrnand, the GetText method retums the string of text currently on the
Clipboard. An assignment statement then copies this string into the selected portian of the
text box (Text l. SelText). lf no text is currently selected, Visual Basic places this text at the
insertion point in the tex t box:
Textl.SelText - Clipboard .GetText( ,
This code assumes that ali text is transferred to and from the text box Textl. This may sound
li mited at first , but the user actually can copy, cut, and paste between Textl and controls on
other forrns. Because the Clipboard is shared by the entire environment, the user can transfer
text between Text 1 and any application that uses the Clipboard.
If you want the Copy, Cut, and Paste commands to work with any text box that has the
foc us, use the ActiveControl property of the Screen object. The following code provides a
reference to whichever co ntrol has the foc us:
Screen.Acti veC ontrol
You can use this fragment just like any other reference to a control. If you know that the
co ntrol is a text box , you can refer to any of the properties supported for tex t boxes,
including Text, Se!Text, and Se!Length. This code assumes that the active co ntrol is a text
box , and it refers to SetText:
Sub CopyCmd_Click ()
Clipb oard.SetText Sc reen.ActiveControl .SelText
End Sub
Sub PasteCmd Cl i ck ()
Sc reen.ActiveControl .SelText Clipboard .Get Text()
End Sub
Another useful Clipboard method is Clear, which clears ali contents of the Cli pboard. The
syn tax is :
Clipboard.Clear
The last three forrnats (bitmap, metafile, and device-independent bitmap) are all used for
transferring graphic images. For example, the following code copies a picture using bitmap
forrnat (assuming that the constant CF_BITMAP is defined as equal to 2):
Sub Copy ()
Clipboard.SetData Picturel.Picture, CF_BITMAP
End Sub
This code pastes the bitmap picture on the Clipboard into Picturel:
Sub Paste ()
Picturel.Pi ct ure - Clipboard.GetOata(CF_BITMAP)
End Sub
You can use the GetFormat method to determine whether a given data forrnat matches the
data on the Clipboard.
For more inforrnation on the Clipboard object, see the Language Reference, or:
Every timer control must be associated with a forro . Therefore, to create a timer applicati on.
you must create at 1east one form . As explained in Chapter 15, "Creating Multiple-Form
Applicati ons," you can load a forro without maki ng it visible.
Note The word "tim er" is used in severa] ways in Visual Bas ic, eac h closely related to th e
workings of the timer co ntro l. In addition to the control name and control type, "timer" is
used in th e Timer event and the Timer fun ction . (The latter return s the number of seco nds
e lapsed since midni ght. )
1m Forml Da
.
.
-~ -
. .- ~V ..
The timer appears on the form at design time only so you can select it, view its properties,
and write an event procedure for it. At run time, a timer is invisible and its position and size
are irrelevant. In fact, it has no size or location properties.
For more information on drawing controls, see Chapter 6, "Drawing the Interface," or:
Note that the Enabled property for the timer is different from the same property for other
objects. With most objects, the Enabled property determines whether the object can respond
to an event caused by the user. With the timer control, setting Enabled to False suspends
timer operation.
Remember that the Timer event is periodic. The Interval property doesn't determine "how
long" as much as it determines "how often." The length of the interval should depend on
how much precision you want. Because there is sorne built-in potential for error, make the
interval one-half the desired amount of precision.
Note The more often a timer event is generated, the more processor time is eaten up in
responding to the event, and this can slow down overall performance. Don't set a
particularly small interval unless you need it.
A di gital clock is a very simple but hi ghly useful application involving a timer control. Once
you understand how the application works, you can enhance it to work as an alarm clock,
stopwatch, or other timing device.
The Digital Clock application includes a label with a border, and a timer. The application
looks like Figure 18.3 at design time.
al Forml DII
'-------
llabel- 1 -~I ~ :
Figure 18.3 The Dig ital Clock Application
The procedure displays the system time by calling the intrinsic Time$ function. This
function retums a string showin g the current time in a convenient hh :mm:ss formal.
You can customi ze the look of the Digital Clock without having to write any addition al
statements. For exa mple, you mi ght want to select a different font for the label, or change
the BorderStyle property of the form.
The Time$ fun ction shows the time in 24-hour format , so that 11 P.M. is represented as:
23 :00:0 0
To display time in A.M .IP.M. formal, the procedure must alter the time string before copying
it to the la bel :
Sub Timerl _Timer ()
Di m MyTi me As String
Dim Hours As Integer
MyTime = Time$
Hour s = Val(MyTime)
If Hours > 12 Then Mid$(MyTime, 1, 2) Str$(Hours - 12)
Labell.Caption - MyTime
End Sub
This procedure starts by storing the system time in a temporary string variable, MyTi me .
Then it extracts the first two digits :
Hours - Val(MyTime)
The Val function reads digits until it encounters a character that is not numeric: in this case,
it stops reading digits when it encounters the first colon (:), which immediately follows the
two hours digits. The function retums the numeric value of these digits. This gives you the
number of hours .
For more information on the Val function , see the Language Reference, or:
To extract minutes or seconds from a string variable, use the Mid$ function.
This statement tests to see if the number of hours is greater than 12. If so, it uses the Mid$
function to replace the first two digits with the number of hours minus 12:
If Hours > 12 Then Mid$(MyTime. 1, 2) - Str$(Hours - 12)
The Mid$ function retums a substring. The arguments to Mid$ give the string to dissect, the
starting position (in which 1 is the first character), and length of the substring on which to
operate. Therefore, Mi d$ ( MyTi me, 1, 2) refers to a substring of MyTi me that begins in
the first position and is two characters long.
For more information on the Mid$ function , see the Language Reference, or:
To set the alarm time, the user clicks the blank portion of the forrn. (Altematively, this can
be irnplemented as a menu command oras a command button.) The procedure prompts the
user for a time by usi ng the InputBox$ statement. If the user presses the Cancel button on
the input dialog box, the lnputBox$ function r:etums an empty string. Therefore, the
procedure assigns a new value to the alarm time only if the string returned is not empty.
Sub Form_Click ()
Temp$ = InputBox$("Enter alarm time in 24-hour hh : mm: ss format:")
If Temp$ <> "" Then AlarmTime - Temp$
End Sub
The Time r event now compares the current time to the string stored in Al a rmTi me . After
updating the time di splay , the Timer event checks to see if the alarm time has been reac hed
yet. If so, it alerts the user:
Sub Timerl _Timer ()
Labell .C aption - Time$
If Time$= AlarmTime Then
Be ep: Beep: Beep
MsgBox "Alarm has sounded ."
End I f
End Sub
Thi s code works fine as long as the clock is not interrupted at th e wrong time. The
application can run in the background, and will beep and di spl ay the message box eve n
though it does n' t have the focu s. However, exec ution is suspended any time the user i~
moving the form.
If the application is not active on the same second that the alarm time is reached, the alarm is
never sounded. The following variation to the Timer event enables the Alarm Clock to report
the alarm time as soon as it can, even if execution was suspended when the time was
reached:
Sub Timerl _Timer ()
Const TRUE = - 1, FALSE = 0
Static AlarmSounded As Integer
In thi s ve rsion , the procedure tests to see if the current time is greater than or egu a! to alarm
time. Thi s way the application can detect whether the alarm should go off, even if it is
returnin g from a suspended state and was not ac tive at the alarm time. The stati c variable
Al a rmSounded ensures that the alarm goes off only once in each 24- hour cyc le.
Note The examples in this secti on ass ume 24- hour formal for the time. However, yo u can
rewrite them to adopt A.M./P.M . format usi ng th e techniques shown at the e nd of the
previous section . When using a different formal, store the alarm time intern ally in th e
standard 24-hour format (for ease of co mparison to Time$). Then convert for A.M./P.M .
on ly when ge ttin g input or di splaying output.
.,.;ortant Multitasking in Microsoft Windows is not preemptive. Thi s means that Windows depends
on each individual application to yield time voluntarily before it can service another
application.
To write an idle loop, add a module to the project and place a procedure called Main there.
This has the effect of making this module the startup module. (As a result, no form is
automatically loaded on startup, so you may need to use Load statements.) Write a Do
While loop that uses the DoEvents function :
Sub Main ()
Forml.Show • Optionally, you can lo ad and di s play a form.
Do While DoEvents()
' Place idle-loop code here.
' These statements are processed whenev e r t he sys tem has free time.
Loop
End Sub
An idle loop might be useful in a communications program (for example, a stock market
ticker) that continually monitors data. Another use of a DoEvents loop is creating an alarm
clock, though a timer control is more appropriate for doing that.
The DoEvents function switches control over to the operating environment kernel. It retums
as so,on as ali other applications in the environment have had a chance to respond to pending
events . This doesn't cause the current application to give up the focus , but it does enable
background events to be processed. For example, if the Alarm Clock application from the
previous section is running in the background, calling DoEvents gives the clock a chance to
update its display .
DoEvents retums the number of forms in the application that are currently loaded. In the
code example above, the DoEvents loop terminates when no forms are loaded. Also note
that if any procedure anywhere in your application executes the End statement, all code in
your application terminates unconditionally.
To call DoEvents, you must store the retum value somewhere. lf you don't want to use the
value, store the return value in a dummy variable:
Dummy - DoEvents() ' Relinquish time to other applications.
DoEvents is useful if you have a long mathematical calculation, and you don ' t want to slow
down the responsiveness of the environment. However, be careful when using DoEvents
thróughout your application. A procedure that has given up control with DoEvents must not
be executed again before DoEvents retums. Otherwise, the procedure may end up being
called endlessly, until system resources are exhausted.
For example, this procedure tests for prime numbers, and uses DoEvents to periodically
enable other applications to process events:
Function PrimeStatus (TestVal As Long) As In t eger
Co nst TRUE = - 1 . FAL SE - 0
Dim Lim As Integer
PrimeStatus - TRUE
Lim = Sqr (TestVal)
For I = 2 To Lim
If TestVal Mod I - 0 Then
PrimeStatus - FALSE
Exit Far
End I f
If I Mod 200 = 0 Then Dummy = DoE vents()
Next I
End Function
The second-to-last line calls DoEvents once evcry 200 iterations. This statement allows the
PrimeStatus Function procedure to continue calculations as long as needed while the rest of
the environment responds to events.
With this example, you must ensure that PrimeStatu s is not called again before DoEvents
returns . Consider what happens during a DoEvents call . Execution of application code is
suspended while other forms and application s process events . One of these events rnight be a
button click that launches the PrimeStatus procedure again. This would cause PrimeStatus to
be re-entered before DoEvents could return .
The solution is to prevent this from happening. For example, if the PrimeStatus Function
procedure is launched by a click on a command button, then don't make it possible for
PrimeStatus to be called again until it retums. The code for this command button might be:
Sub StartPrimeTest_Click ()
Const TRUE - - 1, - FALSE - 0
Static AmCalculatingNow As Integer
One of the effects of DoEvents is to give forms and windows a chance to respond to Paint
events, so DoEvents can be used to update the display. However, because of the
complications just described, DoEvents is not the safest way to cause screen updates. Use
the Refresh method instead. For more information on the Refresh method, see the
Language Reference, or:
Before writing a low-level keyboard handler, make sure that the KeyPress event isn't
sufficient. This event detects keys that correspond to all the standard ASCII characters,
including all alphanumeric keys anda number of others, including BACKSPACE, ENTER, and
TAB. It's generally easier to write code for the KeyPress event.
You also should consider using shortcut and access keys, described at the end of Chapter 10,
"Responding to Commands." Shortcut keys must be attached to menu commands, but they
can include function keys (including sorne function-key- shift-key combinations). These
keys have the virtue of requiring no additional code.
The keyboard even ts are not mutuall y exclusive. When the user presses a key, both the
Key Down and KeyPress events are ge nerated .
End Sub
End Sub
The argument KeyCode is an integer that indicates the physical key that is pressed or
released. The key is represen ted by a numeric code found in the CONST ANT.TXT fil e.
The argument Shift is a bit-field argument (similar to the ones introduced in Chapter 14,
"Responding to Mouse Events") that retums the state of the SHIFf, CTRL, and ALT keys at the
time of the keyboard event.
Key codes for letter keys are the same as the ANSI codes of the uppercase character of the
letter. So the KeyCode for both "A" and "a" is the value returned by Asc("A"). Key codes
for the number and punctuation keys are the same as the ANSI code of the number on the
key. So the KeyCode for both "l" and "!" is the value retumed by Asc("l"). Again, numeric
keypad keys are separate. They have their own special codes, as indicated in the file
CONSTANT.TXT.
For example, this procedure quits the application when the user presses F2:
You then can test for each shift-key state that you're interested in:
ShiftOown% = (Shift And SHIFTKEY) > 0
CtrlOown% = (S hift And CTRL) > 0
AltOown% - (S hi ft And ALT) > 0
Note To improve readability and maintenance of your code, place ali the Shift and KeyCode
arguments in the global module.
You ' ve probably noticed that Visual Basic does a good job of catching errors that creep into
your code as you write. Visual Basic often warns you immediately if you have entered a line
of code that contains a syntax error. Similarly, Visual Basic provides tools for analyzing
code and isolating prograrn logic errors.
There are other errors that only appear when your code is running. These are called run-time
••
dling
•
•
• •
•• ••
• ••
•
•
280 Part 4 Advanced Applications