Visual Basic Programmers Guide 1991
Visual Basic Programmers Guide 1991
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
The code appears to cover either of the possible outcomes of the Dir$ call. However, if the
current drive is a floppy disk drive, this fragment will work correctly only if a disk is in the
drive and the drive door is closed. If this isn't the case, Visual Basic generares the error
message De vi e e un a va i l a b l e and halts execution of the appl ication. If the application
were running in the Visual Basic environment, the user could fix the error and resume
runnin g the program. But if the application were started from an executable file , it would
display a Visual Basic error message, then unload the application and retum the user to the
operating environmenl.
To avoid this situation , use the error-handling features in Visual Basic to intercept errors and
take corrective action. (lntercepting an error is also known as trapping an error.) For
example, device problems such as the disk not in drive or drive door not closed could be
handled by using the following code.
Sub CheckTxtFiles ()
' Define constant to represent Visual Basic error code .
Const ERR_DISKNOTREADY = 71, ERR_DEVICEUNAVAILABLE = 68
' Define constants for message - box types.
Const MB_EXCLAIM = 48, MB_STOP = 16
The Err function retums the number associated with the run-time error that occurred;
Error$ retums the Visual Basic message associated with the error. Should Vis ual Basic
generate the error Disk n ot rea dy or Dev ice un a va i la ble, a message is displayed
telling the user what to do. The Resume statement immediately preceding End Sub then
retums control to the statement at which the error occurred and attempts to execute it again.
If the user has corrected the problem, the statement succeeds; otherwise, the program
branches to the error handler again . If an unanticipated error occurs an alternative message is
presented and the program ends . See the section "Guidelines for Complex Programs" for an
explanation of using the Stop statement.
Your application can correct many kinds of errors, or prompt the user to change the
co nditions that ca used the error, using techniques such as those shown in the preceding
example . The nex t section discusses these techniques in detail.
Details on how to perform these steps are prov ided in the follow ing secti ons. Refer to th e
example in the precedin g section as you read .
The Err function returns a numeric code representing the most recent run-time error. (As
mentioned earlier, a run-time error can occur only when your code is running.) By using Err
in combination with Select Case or lf... Then ... Else statements, you can take specific action
for any error that occurs .
Note The string returned by Error$ always explains the error associated with the current
error number. However, precise wording of the message may vary among versions of the
product.
Resume returns to the statement that caused the error. Use it to repeat an operation after
correcting the error.
The Resume Next statement returns to the statement immediately following the one that
caused the error. The difference between Resume and Resume Next is shown in Figure
19.1.
Start
Resume
1
l
Statement with error . Error handler
( End )
~-~
Whether you use Resume or Resume Next depe nds on whi ch source changes th e condition
that led to the error - either the user mu st make the change, or the code fo r yo ur appli cati on
does. If the user can make th e change (s uch as closing a dri ve door), Resume is probably
appropri ate. However, your error handler may be written so that the existence of a run-time
error is never revealed to th e user.
In the fo ll owing code fragme nt, a di vision is performed with two variables. If the numerator
is nonzero, but the denomin ator happens to be zero , Vi sual Basic generates the error
Oi vi s i on by z e r o. If both are zero (and flo ating-point di vision is being perforrned),
Visual Bas ic generates the error Ov e rflow . In these cases the Function procedure could
simpl y ret urn the largest va lue of its ty pe (thu s simulating infinity) .
Resume Next also can be used if you anticípate an error in a loop, and you need to restart
the operation. Or, you can use Resume line, which returns control to a specified line label.
The following example enables the user to enter file specifications to check until Dir$
returns without errors, or choose Cancel at the InputBox to exit from the procedure.
Function VerifyFile () As String
Const ERR_BADFILENAME = 52, ERR_DRIVEDOOROPEN = 71
Const ERR_DEVICEUNAVAILABLE = 68, ERR_IN VA LIDFILENAME = 64
Const FALSE= 0. TRUE - Not FALSE
NLS = Chr$(13) + Chr$(10) ' Carriage return-linefeed comb ination.
PromptS = "Enter file specification to check:"
StartHere:
FileSpecS = "" • Start with a default specification.
Msg$ = MsgS + NL$+ PromptS
'Let the user modify the default .
File Spec$ = InputBoxS(MsgS, "File Search", FileSpecS, 100, 100)
If Fil eSpecS = "" Then Exi t Funct ion • Exi t i f user enters nothi ng.
On Error GoTo Handler
VerifyFile = DirS(FileSpecS)
Exit Function
Handl er:
Se l ect Case Err ' Analyze error code, then load up message .
Case ERR_ INVALIDFILENAME, ERR_BADFILENAME
Msg$ = "Your file specification was invalid, try another:"
Case ERR_DRIVEDOOROPEN
Msg$ = "Clase the disk drive door and try again:"
Case ERR_DEVICEUNAVAILABLE
Msg$ = "The drive you specified was not found . Try again:"
Case Else
Error Err
End Select
Resume Start Here ' This j umps back to label so user can
End Funct ion ' try another filename .
If a file matching the specification is found, its path and name are returned. If Dir$ returns
an empty string, the function is executed. If one of the anticipated errors occurs, a message is
assigned to Ms g $ and execution jumps back to the label StartHere, and the user has another
chance to enter a valid path and file specification:
Although Resume fine is a legitimate way to perform this operation, jumps to labels are
ofü~n considered throwbacks to a less structured style of programming, since their
proliferation can make code difficult to understand and debug.
The previous example also illustrates how to use an Error statement to regenerate an
unanticipated error within the error-handling routine itself. This causes Visual Basic to
search back through the invocation path (if there is one) for another error-handling routine.
The next section, "Unanticipated Errors," explains the invocation path and how Visual Basic
searches back through it.
Unanticipated Errors
As previously noted, an enabled error handler is one that has been turned on by executing an
On Error statement, and has not yet been tumed off-either by an On Error GoTo O
statement, or by exiting the procedure from which it was tumed on. An active error handler
is one in which execution is currently taking place. An error handler must be enabled to be
active, but it need not be active simply because it is enabled.
When an error occurs within a procedure that does not have an enabled error-handling
routine, or when an error occurs within an active error-handling routine, Visual Basic
searches the invocation path for another enabled error-handling routine.
Consider the following path of invocati on:
• Form_Load procedure calls Procedure A
• Procedure A calls Procedure B
• Procedure B calls Procedure C
While procedure C is execu tin g, th e invocation path is Form_Load, A, B,C. The procedures
Form_Load, A, and B are pending while Procedure C is executing. If an error occurs in
Procedure C and the procedure does not have an enabled error handler, Visual Basic
searches back through the invocation path - first Procedure B, then Procedure A, then
Form_Load . Visual Basic executes the first enabled error handler it finds. If it reaches
completely back along the invocation path without encountering an enabled error handler in
any of the pending procedures, it di splays the appropriate message and halts execution .
If Visual Basic finds an enabled error-handling routine, execution continues in that error-
handling routine. If a Resume ora Resume Next statement is executed in the error-handling
routine, execution continues as shown in the following table.
Statement Result
Resume Visual Basic re-executes the call to the procedure that
Visual Basic just searched back through. In the invocation
path given earlier, if Procedure A has an enabled error-
handler that includes a Resume statement, Visual Basic re-
executes the call to Procedure B.
Resume Next Execution retums to the statement following the last
executed statement in that procedure. This is the statement
after the call to the procedure that Visual Basic just searched
back through. In the invocation path given earlier, if
Procedure A has an enabled error-handler that includes a
Resume Next statement, execution retums to the statement
after the call to Procedure B.
Note that the statement executed is in the procedure where the error-handling procedure is
found , not necessarily in the procedure where the error occurred. If you don't take this into
account, your application may perform in ways you do not intend.
An unanticipated error can occur within a procedure that has an enabled error handler, if the
range of errors does not include the one that actually occurred. In such a case, the procedure
could execute endlessly, especially if the handler executes a Resume statement To prevent
such situations, use the Error statement in a Case Else clause to actually generate an error
within the error handler; Vi sual Basic th en searches along the invocation path far a handler
that candeal with the error.
In the preceding example, the VerifyFile Function procedure, the number originally
retumed by Err was given asan argument to the Error statement in a Case Else clause,
generating an error. When this occurs within an active error handler, the search back through
the invocation path begins.
Note The effect of the search back through the invocation path can be hard to predict, since
it depends on whether Resume or Resume Next is executed in the handler that finally
processes the error successfully. For exampl e, if a Resume Next statement is executed to
exit the successful error trap, it retums to a statement in the procedure in which Resume
Next is executed, but that procedure may not be the one in which the error originally
occurred.
This Function procedure handles common file- and disk-related errors. If the error is not
related to disk VO , it returns the value 3. The procedure that calls this Function procedure
should then either handle the error itself or call another procedure to handle it.
Note As you write larger and larger applications you'll find that you are using the same
constants in severa! procedures in various forms and modules . Moving the declarations for
those constants to the global module may better organize your code and save you from
typin g the same declarations over and over.
You can simpli fy error handling by calling the FileErrors procedure wherever you have a
procedure that reads or writes to disk. For example, you' ve probably used applications that
warn you if you will be overwriting a preexisting disk file when you try to save a file with a
certain name . Conversely , when you try to ope n a nonexistent file, many applications warn
you that the file does not exist, and ask if you want to create it. In both instances, errors can
occur when the application passes the filename to the operating system.
The following checking routine uses the value returned by the FileErrors procedure to decide
what action to take in the event of a disk-related error:
Function ConfirmFile (TheName As String, Operation As Integer) As Integer
' Parameters:
' TheName File spec to be checked for and confirmed.
'Operation Code for sequential file access mode (Output, Input, etc).
Note procedure works for binary and random because messages are
conditioned on Operation being <> to certain sequential modes.
' Returns:
1 Con firm s operation wil l not cause a problem.
' 0 User decided not to go through with operation.
The ConfirmFile Function procedure recei ves a specification for the file whose existence
will be confirmed , plus information about which access mode will be used when an attempt
is made to actually open the file . If a sequen ti al file is to be saved (RE PLACE FIL E), and a
file is found that already has that name (and will therefore be overwritten), the user is
prompted to confirm that overwriting the file is acceptable.
If a s~quential file is to be opened (READFI LE), and the file is not found, the user is
prompted to confirm the desire to create the file . If the file is being opened for random or
binary access, its existence or nonexistence is either confirmed (return value 1) or refuted
(return value O) . If an error occurs in the call to Dir$, the FileErrors Function procedure is
called to analyze the error and prompt the user for a reasonable course of action. Like
FileErrors, ConfirmFile is used in the applications presented in chapter 21, "Processing
Files."
LOOP
' Now see if an e rr or occur red and if so take action.
Se l ect Case Err
Case 0
' No error-continue with applicatio n.
Case Err _Overflow
' Deal wi th overflow error.
Ca se Err _Divi s ionByZero
' Deal with division by zero.
End Select
Program cont i nues here after checking far errors.
In Chapter 20, "Using the File-System Controls," the event procedure Drivel _Change
illustrates the use of On Error Resume Next.
There are four points to remember when using delayed error handling:
• The code that detects and deals with the error differs from the error-handling routines
discussed earlier in this chapter-it does not contain any Resume statements.
• The error number returned by Err is the number of the most recent error. Any other
errors that occurred earlier in the preceding code are lost.
• If a Resume, Resume Next, oran On Error statement is executed, or if a procedure call
is made, Visual Basic resets Err back to zero. If you are going to use the value returned
by Err, store it in a variable before executing any of these statements.
• Finally, if errors occur and handling is deferred, logic errors in the intervening code
could com plicate things significantl y.
Another reason for using On Error Resume Next is to tailor error handling to each group
of related statements rather than have a single error-handling routine per procedure.
Exit Sub
SubHandler:
' Error - handling routine goe s here .
Ms gBo x "Caug ht error . "
Resu me Nex t
End Sub
For more information on the various functions and statements you use to handle errors, see
the Language Reference, or:
Note Visual Basic doesn't use all available numbers for its own errors. As new errors are
defined for the Basic languages, the interna! error numbers increase. Also, other applications
may return error codes . If you want to generate and trap your own errors, begin your
numbering scheme with 32,767 and work your way down . This will ensure your error
numbers don ' t conflict with those of Basic or other applica ti ons.
Many applications must present information about disk drives, directories, and files. Visual
Basic includes powerful support for enabling users of your applications to explore the file
system. You can use three specialized file-system controls - the drive list box, the directory
list box, and the file list box - to display the system's drives, directories, and files , all with
1~ a few mouse clicks or keystrokes. This chapter explains the file-system controls and shows
you how to use them so users can investigate, and choose, among available disk files in your
applications.
The main sections in this chapter are:
• Examining the File System
• The Launch Pad Application
• A File + Open Dialog Box
• Other Ways of Using File-System Controls
296 Part 4 Advanced Applications
Each of th e co ntrol s - th e drive li st box , the directory li st bo x. and th e fil e lis t bo x - have
been carefully designed to combine flexible and sophi sticated file-system inspection
capabilities with easy programming. Figure 20.2 shows the three co ntrols used together.
= calendar. exe
Forml
. li;;:Jc: [DISK) ªª
w- r- Orive list box
cardlile. exe
clipbrd. exe
clock.exe
control.exe
--E:}c: \
L]
..
games
icondraw.exe L] icons
msdos. exe L] system
pbrush. exe
L] winstuff
pifedit. exe •
1
1 File list box Directory list box
Figure 20.2 The file-system controls in action
The controls themselves obtain all the information they display frorn th e operat ing system;
you can access this information through their properties . You can use the co ntrol s
indi viduall y, or combi ne them in different ways by programming their interactions. For
example, you can display a list of the files in the current working directory with names
matchin g the pattern *.FRM. Just draw the Filel control on the forrn , th e n set its Pattern
property , either by typing *.FRM in the Properties bar, or by using thi s code at run time:
Filel.Pattern = "*.FRM"
Which event procedures you use or which properties you change depends on the way your
application is using the combination of controls . The next section illustrates one combination
that launches applications.
For more information on file-system controls, see the Language Reference, or:
Note that in the drive list box a Change event is triggered by a single mouse click on an
item, but in the directory list box a double-click is necessary to generate the Change event.
(In the drive list box a Change event also results from selecting an item, then changing the
focus on the form.) In both the directory and file list boxes, the single click just selects
(highlights) the item, rather than choosing it.
= Launch Pad aa
calendar.exe
cardlile.exe
• li;;Jc:
E':>c:\
[DISK) w
clipbrd.exe
clock. exe L) games
control.exe L) icono
msdos.exe
notepad. exe L) system
pbrush.exe L) winstuff
piledilexe
omcao. exe •
Note You should draw the frame control befare you draw the first three command buttons
inside it. Also, the file-system controls do not have caption properties, although you can use
labels to name them and give them access keys. (For more information on using labels this
way, see "Shortcut and Access Keys" in Chapter 10, "Responding to Commands.") The
captions used for the frame and command buttons include ampersands to give them access
keys.
The variable LastChange contains a value associated with the symbolic constant
FIL EBO XC L I CK or DI RS BOX CLIC K. Under certain circumstances one of these values is
assigned to Las t Ch an ge to help track what the user is doing. For example, in the procedure
Dirl_Click, Las te ha nge is set to DI RSBO Xe LI e K.
Launch Pad uses the procedures shown in the following table to handle the significant
events.
Procedure Description
Dri ve l _Change The Change event is generated when the user clicks a dri ve
specification . The Change procedure assigns the new drive
info rmation to the Dirl.Path property. This assignment
triggers a Change event in the Dirl control, forcing it to
update its di splay.
Di r l _C hange If the user double-clicks a directory name, the di splay is
updated and the Change event is generated . Thi s procedure
passes on the new path information and resets the focu s to
the File l control , fo rcing a di splay update anda Change
e\·ent in the File l list box.
Dir l_Cl ick If the u ser clicks a directory name, the DIR S BOXC LI CK
value is assigned to the variable LastChang.áf thi s is stil l
the value of LastChange when a command button is
chosen, the directory and fil e-system controls are updated.
F iJ e l _Click T he Click procedure resets the Caption property of the
frame around the command buttons to reflect the name of
the program the u ser clicked. It also assigns FI LEB OXCLI CK
to Last Change.
F ile I_DblC li ck A double-click meaos the user has made a fin al choi ce, so
this procedure calls the Button_Click event procedure and
passes the index of th e defa ult co mmand butto n to ini tiate
the program.
Button_ Cl ick Checks what the last change was before the user chose th e
defau lt command button. If the las t change was not in the
Dri ve l or Dirl box, the drive and path are reset at the DOS
leve!, then the fil ename is passed to the Shell functi on to run
the program .
The preceding code assigns the u ser' s choice to the Path property for Dir 1, changing the
Dir l display to show the files in the current directory on the new drive. This assignment also
triggers the Dirl_Change event. Note that the Change event in a Orive list box occurs when
a new drive is chosen, either with a single mouse click, or when the user moves the selection
(for example, with an arrow key), then changes the focus .
The second line of the procedure assigns the Path property of the Dirl box to the Path
property of the Filel box. This causes a change event in the Fi le ] control, which is redrawn .
However, you don't need to .add code to the Filel_Change procedure, because for this
application , no event chain continues after changes to the File l box have been made .
The frame's caption is set to reflect the name of the chosen program, and the constant
FI LEBOXCLICK is assigned to LastChange Remember, a Change event is not initiated by
a si ngle click in either Dirl or File 1, although the change event is triggered by a single click
in Drivel.
The File1 DblClick Procedure
Although you don ' t add code to the Filel _Change procedure, it is necessary to add the
following code to File l _DblClick: .
Sub Filel_DblCli ck ()
' If the user double -clicks a filename, choose the default command button
' so the application will start Maximized.
Button_Click (0) ' Pass the default index value.
End Sub
The single line of code in this procedure sim ulates choosing the default command button ,
which is named Button(O) and labeled Run Maximized .
lf the user is indeed tryin g to launch the application, a check is made to be sure there is a
filename selected in the File] box by examining the Filel.FileName property . Then the drive
and path are updated at the DOS level. The Shell function starts the application represented
by the first argument, File] .FileName. The second argument describes how the application
should be displayed: Normal (1), Minimized (2), Maximized (3), and so on. The indexes for
the command buttons are chosen so that subtracting them from 3 produces the appropriate
argument-for instance, 3 minus the index of 1 for the command button labeled Minimized
produces the argument of 2.
When you handl e errors thi s way, you assume one solution for any possible error. You can
combine thi s with the error-handling techniques discussed in Chapter 19, "Handling Run -
Time Errors," to make it more foolproof.
Now that you 've entered the code, press FS to run Launch Pad. You should be able to use it
to start appli cation s ju st as you do from the File Manager.
= Filelnfo
OK Cancel
ªª
c:\winword
a rti el e . dot • 1o c:\
basic.dot !2::7winword
brief.dot L] winword.cbt
brochdat.dot
brochmrg.dot
brochure.dot
contract.dot
conv-wrd.dll
conv-wri.dll
conv-ww .dll • !IEJc: [DISK) w
Figure 20.4 The Filelnfo Dia log Box
Start building Filelnfo by creating a new form and setting the forrn ' s FormName and
Caption property to "Filelnfo." The following table summarizes the controls, properties to
set, and significant events for the application.
Control Property settings Significant events
Textbox CtlName = TextBox Change
Label CtlName = PathSpec
Orive list box CtlName = DriveDropDown Change
File list box CtlName = FileListBox Click, Db!Click,
PatternChange, PathChange
Directory CtlName = DirsBox Change, Click
Command button CtlName = DlgButton(0), Click
Caption = OK,
Default = True
Command button CtlName = DlgButton(l), Click
Caption = Cancel
Filelnfo uses the procedures shown in the following table to handle the significant events of
th e control s.
Procedure Description
Form_ Load Initializes the dialog box. Places a default filename (or
matching pattem) in TextBox, as well as a drive and path
specification in the DriveDropDown and DirsBox boxes.
FileListBox_PathChange If the Path property in FileListBox is altered, this procedure
initiates synchronizing of the information in the other
controls (both the DriveDropDown and DirsBox list boxes
and the PathSpec label).
TextBox_Change Assigns TEXTB0XCHANGE to LastChang e.
Drive DropDo wn_ Ch ange If a new drive is elected from Dri veDro pDown (e ither by
the user clicking the control or from code) , assigns the new
drive to the DirsBox.Path property to update DirsBox.
DirsBox_Click Assigns DIR SB0XCLICK to the variable La s tChange to
indicate DirsBox was the last one changed.
Note that in the Launch Pad application, the code to launch the application appears in the
Button_Click procedure, and the lndex property of the button chosen determines whether the
program starts in maximized, minimized, or normal size. This dialog box is slightly
different. The command buttons here indicate only whether or not the user has chosen a
filename:
• If the Cancel button is chosen, the dialog is cancelled and no information is made
available to the application.
• If the OK button is chosen, the global variables containing the filename and path are
modified. This is carried out in the file control' s DblClick procedure, rather than in the
button' s Click procedure, so the code appears only once.
When you want to use the dialog box in an application, merge the global module of the
Filelnfo project with the global module of the application from which you intend to display
the dialog box.
Define the following in the Filelnfo form-leve l Declarations section :
' Code indicating where the la s t s ignificant event took
' place befare the user chose th e OK button.
Dim LastChange As Integer
The Filelnfo example assumes the following Show method has been executed, and it starts
with the Form_Load procedure:
Filelnfo . Show MODAL
The argument MODAL is defined in the file CONST ANT.TXT. The constants TRUE and
FALSE also are defined in CONSTANT.TXT, and are necessary for Filelnfo to work
properly. Merge CONST ANT.TXT with your global module. Information exchan ged
between the form and the application using it is placed in global variables - in this case, the
global string variables TheNewPath and TheFi l eName. Information about the user's choice
is assigned to these variables in the FileListBox_DblClick procedure. Once the Fi lelnfo form
is hidden or unloaded the Filelnfo dialog information in TheNewPath and TheFi l eName
can be used by the app lication.
' If the globa l variable TheF ileName is not null. check item s in the lis~
' box to see if it is in the re . If so , put it in the text box.
I f TheFi l eName <> '"' Then
Far Ind% = 0 To FileListBox.ListCount
If Fileli stBox.List(ind) = TheFileName Then
TextBox.Tex t = TheFi leName
Exit Far
End I f
Next Ind%
End I f
As with Launch Pad, ass igning the new drive name to DirsBox.Path causes the contents of
the DirsBox control to change, reflectin g the current directory on the new drive. This in turn
tri ggers the DirsBox_Change event. The only events you must respond to in the
DriveDropDown control are the Change events. A Click event is equivalent to choosing the
item (rather than just selecting it) .
A Click event in th e DirsBox control means the user has selected, but not chosen, a new
directory . This may be a result of ei ther clicking a mouse in the box or pressing an arrow key
while the box has the focus. Rather than responding by refilling the related list boxes, just
note in the DirsBox_Click procedure that this was the user's last action. No Change event is
triggered by a click in the DirsBox control.
If the last action was a change in the TextBox control, the code examines the contents of the
box to see whether the user simpl y typed a filename, typed in new drive or path or pattern
specifications, and so on .
Note th at if a strin g assigned to FileListBox.Filename contains wildcard charac ters, no
Db!Click event occurs, but the stri ng becomes the FileListBox.Pattern. A filename with no
wildcards is also a valid pattern , and it also changes the pattern property, and th e only item
in tne li st box becomes the matching filename. Finally, the fact that the ass igned string
represented a filename in the box triggers a FileListBox_Db!Click event. The code below
handl es the possibilities . Then thé new text is selected in the text box, it receives the focus ,
and the Yariable LastChange is reset to O:
Sub DlgButton_Click (Index As Integer)
' Index tells whether DK or Cance l wa s cho sen. This procedur e checks
' wh ere the last change occurred . If i t was in the text box , the code
determines whether a valid filename now appears there . If so , that
' name i s assigned to FilelistBox.FileName. If not. the code c he cks to
' see if a new pattern was ente red , and pla ces it in FilelistBox.Pattern .
' If it wa s neither a valid filename nora val id pattern, the previous
' pattern is shown in the text box . If LastChan ge wa s DIRSBO XCLICK,
,· assigning t he clicked directory to Dir sBox.Pat h i nitiates events to
' update other pieces i n t he dialog.
Many of the applications you'll create with Visual Basic will need to write data to disk, read
data from disk, or both. In fact, many applications would be ali but useless if you could not
save the data you have entered, or read in old data to be displayed and modified.
This chapter presents two sample applications, Text Editor and Record Editor, to show you
how to use the file input and output (I/O) functions and statements in Visual Basic to access
data stored in files. It includes material on a variety of programming tasks related to
retrieving, storing, and formatting information .
The main sections in thi s chapter are:
• Working with Data Files
• Using Sequential Access for Text Files
• Records in Random-Access Files
• Binary File I/O
The sections th at fo llow introduce the concepts of records and fields, and contrast different
ways to access data files from Visual Basic. They show yo u how to :
• Create new data fil es.
• Open ex istin g fil es and read their co nte nts.
• Add new info rmation to an existing data fil e.
• Change the contents of an existing data fil e.
Ali types of fil e access use the FreeFile , EOF, and LOF function s to determine an available
fil e number, the end of a file, and its length, respectively. Also, you can use statements such
as Seek, Get, Put, and Input$ with file types other than those with whi ch they are normall y
used . The keywords are simply gro uped with th e access type with which they are most
commonly associated.
Sequen ria/ access assumes the fil e is a plain teitt fil e (o ne whi ch, if viewed with the DOS
TYPE comma nd, always appears as normal tex t). Each byte is ass umed to representa
character. Numbers in a file created with sequ e ntial access are represented by character
strin gs, j ustas wo rd s are. Sequential access makes it easy toread and modify the kinds of
file s produced with a text editordvbpgapafiles in which th e data is ,w t divided into a seri es
of individual record s.
In a random-access file, string data also appears as normal text when viewed with the TYPE
command. But numbers are stored in binary format, rather than as strings of characters, so
there is no obvious relationship between the actual number and a number displayed with the
DOS TYPE command. Random access makes it easy to work with files whose data is
organized into man y discrete records, each of which has the same form and length, but each
of which contains individualized data.
Binary access uses statements similar to random and sequential access, but makes no
assumptions about what the individual bytes representdvbpgapathey could represent
anything from ASCII text to a series of records, or even the executable image of a program.
Although you can use sequential access to work with record-oriented files , random access is
simpler for that purpose, and more efficient. Although not commonly used now, Write # and
Input # were once used for record-oriented file access before Basic supported random file
access. These statements are sti ll supported in Visual Basic and you mi ght find them useful
for working with record-oriented sequential files that use the comma character as a field
delimiter.
Thi s chapter concentra tes on using sequen tia! access for the kinds of text files normally
produced by text edi tors. Random access is illustrated using the types of structured data you
mi ght find in a database . Binary access is only briefly summarized .
Note With the exception of sequential Output and Append modes, you can simultaneously
open the same file multiple times in the various modes . If a file is opened for any other
mode, it cannot be simultaneously opened for sequential Output or Append. When opened
for Output or Append, it cannot be simultaneously opened in Input, Random , or Binary
mode. All other combinations of simultaneous file opening are permitted.
If the same fil e is opened simultaneously under different file numbers, Visual Basic
independently tracks such things as file position for each file number. Y ou must use caution
under these circumstances, however, since different buffering of the same file opened in
different modes can foster inconsistent images of the file' s contents if both reading and
writing operations are being performed ..
The argumentfile$ is a string expression specifying the file to open. It follows the operating
environment rules for naming and specifying files . It can therefore contain an optional drive,
as well as a complete, partial, or relative path specification. The mode is one of the fi ve
modes previously mentioned.
The filenumber is an integer identifier between 1 and 255, inclusive. lt is used by subsequent
file I/0 statements in the application as a shorthand way to refer to the fil e. As long as th e
file is open, this number remains associated with the file . When the file is closed, th e fil e
number is freed for use with another file. Your Visual Basic applications can open more th an
one file at a tim e. Use the FreeFile function to retrieve valid fil e numbers.
For informa ti on on the other arguments used in the Open statement, see th e Language
Reference, or:
The Fileüpener Function procedure illustrates the syntax of the Open statement used for ali
three sequ ential modes, as well as random and binary access. It accepts a filename and a
code representing the mode in which the file is to be opened. Fileüpener also accepts an
integer representing the length of a single record if the file is to be opened for random
access. It uses FreeFile to obtain a file number. If it succeeds in opening the fil e, Fileüpener
returns the fil e number to use in subsequent references to the file. Fileüpener also uses th e
FileErrors Function procedure outlined in Chapter 19, "Handling Run -Time Errors."
Note that the constan ts READ FILE , REP LACE FIL E, ADOTO FIL E, RAN DOM FILE, and
BINA RY FI LE are defined here as local constants. If their scope is greater in yo ur programs
(that is, if yo u defin e them globaily or at the module leve!), the local definitions should be
removed .
Note the Len= clause in the Open statements. The default is 128 bytes for both random and
sequential access, but when opening a file for random access, Len must specify the exact
size of a single record . For sequential-access files you can use Len to specify how much of
the data file's contents are read into memory at once.
lf you increase thi s " buffer" size, large files are transferred faster between file and program
Yariabl es . Smaller values use less memory, but the transfer rate is slower. Len is ignored for
binary access, because the unit of tran sfer is always a single byte.
Note When you use sequential access to open a file toread from it, the fi le must already
exis t, ot herwise Visual Basic generates an error. However, when you try to open a
nonexi stent fil e in a mode other than sequential Input, the Open statement creates the fil e
first , th en opens it.
1m Text Editor aa
+
+I + 1!!11
Remember to give each control the CtlName and Caption properties shown in the preceding
table. Otherwise code that relies on these properties won ' t work properly.
The procedures used in the Text Editor are shown in the following table.
Procedure Description
ExitButton_Click Enables the user to close the application . If there is text in
the text bo x, asks the user whether it should be saved, and
<loes as instructed. Closes all files , then terminates the
program by unloading the form .
Checkltüut Determines if there is text in the text box that may need to
be saved, then asks the user whether or not to save it.
GetName Gives the user an opportunity to name or rename a file to be
opened or saved.
OverWrite When the user wants to save a file , thj s procedure is called
no matter whi ch button click initi ated th e save ac tion .
Form_Load Starts the application. Tells the user what can be done and
how to proceed.
SaveButton_Click Enables the user to save the text as a file on disk. If a file is
loaded, this button can be used to clear the old text in
preparation for creating a completely new file.
OpenButton_Click Enables the user to edit an existing file. If there is already
text in the text box, asks the user whether it should be saved.
Does as instructed, then closes the file . Next, shows a dialog
box to get the name of the new file to display. If the file
exists, ope ns it and reads its contents into the multiline text
box . If the fil e cannot be found, the user can choose whether
or nol to crea te it, or try a new name.
Fileüpener Given a fil ename and mode in which it is to be opened ,
Fil eüpener ope ns the file and retums the number by which
the fil e is thereafter to be known.
FileErrors If a run-time error occurs during an attempt to open a file or
read from the di sk, this procedure examines the errors and
retums a code indicating what action to take.
Co nfirm Fi le Checks to make sure a file exists. If the user is saving text
and the file ex ists, he is remjnded that the save will
overwrite the current contents. If the user is trying to open a
nonexistent fil e, he is given the option of creating the fil e or
trying another filename.
Note The Fi leErrors and ConfirmFile Function procedures were created in Chapter 19,
" Handling Run -Time Errors," and are called from procedures in the Text Editor application
when appropri ate. The Fileüpener Function procedure was created in the previous section
in thi s chapter. Be sure to enter or load th ose procedures into the Tex t Editor module.
The example code presumes you have retained the default form name for the application .
Merge the contents of the file CONSTANT.TXT with the global module, then enter the
following lines:
' Constants to represent the file-access modes.
Global Const SAVEFILE = l. LOADFILE = 2
Global Const REPLACEFILE = l. READFILE = 2, ADDTOFILE 3
Global Const RANOOMFILE = 4, BINARYFILE = 5
End Sub
WriteError:
Action% = FileErrors(Err) ' If there was an error accessing the file,
Select Case Action% ' find out what to do, then do it.
Case 0
Resume ' Try the statement that failed again.
Case 1
Resume Next ' Forget the statement that failed; just
Case 2 ' go ahead and do the rest of procedure.
Exit Sub ' Exit the Sub procedure right away .
Case Else
Error Err ' If the error is completely unanti cipated.
End ' display system error message, then quit .
End Select
End Sub
lf an error occurs in OverWrite, Fileüpener, or ConfirrnFile, their error handlers cal! the
FileErrors Function procedure to analyze the error.
Other than Form_Load, the only events your application code must respond to are the Click
events for the command buttons. The Click procedures are listed in the following sec tion s.
Sub OpenButton_Click ()
CheckltOut FileTextBox ' See if there is text to save.
GetName ("File To Open:")
If WorkingFileName <> "" Then
OpenMode% = LOADFILE
If ConfirmFi le(WorkingFileName, OpenMode%) = 1 Then ' If file exists.
FileNum% = FileOpener(WorkingFileName . OpenMode%. 0) • try to open.
If FileNum% - 0 Then Exit Sub · If open fails,
If OpenMode% = ReplaceFile Then · just exit; if
Clase FileNum% ' OpenMode was set
Exit Sub ' to Rep l aceFile, it is
End I f ' empty, so you can
Else ' clase it and exit .
Exit Sub ' If the file s till doe sn ' t exist...
End I f
Else ' _or if the user failed to enter
Exit Sub ' any filename at all.
End I f ' then just stop trying.
' Several stateme nts in this procedure use file numbers as arguments,
· so turn on an error tra p and leave it on far remainder of procedure.
On Error GoTo ReadError
' If the file ' s text won't fit comfortably into the text box. exit.
If LOF(FileNum%) > 60000 tnen
Msg$ = "Sorry your file is too larg e to edit."
MsgBox Msg$, 16. "File Too Big"
Exit Sub
End I f
' Otherwise. read one line ata time into a variable .
' Do Un ti 1 EO F( Fi 1e Num%)
Line Input #FileNum%, Nextline$
' As eac h line is read, add it to those preceding it. then
· replace the terminator (Line Input# drops the line-break
· characters so you have to add ,them back).
LineFromFile$ LineFromFile$ + Nextline$ + Chr$(13) + Chr$(10)
Loop
ReadError:
Action% = FileErrors(Err)
Select Case Action%
Case 0
Resu me
Case 1
Re s ume Next
Case 2
Exit Sub
End Select
End Sub
When text is loaded from a di sk fil e into the tex t box , the caption on SaveButton changes to
"New/Save Fil e'· to remind the user th at tex t can be di scarcled w ith out be in g saved.
Otherwise. the caption is "Save/New File. "
The argument MODAL di sables the res t of the application until the user closes the Filelnfo
dialog box by choosing either DlgB utton (0) (the OK button) or DlgB utto n( 1) (the Cancel
button) . MODA L is defined in the CONSTANT.TXT file , which should be merged w ith
yo ur global module.
T he Text Ed itor application is written to preserve line break s as they exist in the
filedvbpgapaafter eac h Line Input# statement , a carri age return-linefeed is appended to the
line. l f you do not add the line breaks, how the tex t wraps in the text box depends on
whe the r or not the tex t box has a hori zon tal scroll bar.
lf no ho ri zontal sc roll bar is prese nt, the lines are wrapped to fit in th e current wi dth of the
tex t bo x. If the box has a horizontal scro ll bar, text is added to the box until the max imurn
line leng th (255 characters) is reac hed , the n another line begins.
Note that when you call procedures from a separate module or invoke other forms, any
global variables used in the procedures must be declared in the global module of the
application, rather than at the form level of either the application 's start-up form, or the form
level of the new modul e.
Later in thi s chapter the GetName, Fileüpener, ConfirmFile, and FileErrors procedures are
used in building an application that uses a random-access file systerp.
Note In gtaphical user interface applications the TAB key is used for moving among
controls. Therefore, pressing TAB within a multiline text box moves the focus to the next
control, rather than inse rtin g multiple spaces. A user who wants to use tabs for spacing
within a multiline text box can press CTRL+I rather than TAB.
Pass it the empty string L i neFro mFi le$ and the file 's file number (FileNum o/o).
CheckNewLines uses the Input$ statement to check each character in the file individually.
If CheckNewLines finds the line- break sequence recognized by Line Input#, only th at first
line is assigned to L i ne F r om Fi l e. Then, Line Input# is u sed to read the rest of the fil e' s
contents. If the file has a differe nt line-break character, CheckNewLines reads every
character in the file indi vidual ly, replacing the !in e-break characters with the Ch r $ ( 13) +
Ch r $ ( 10) sequence.
If the user saves the file later, it is written to di sk using the carriage return-linefeed
combination as a line- break seq uence. If the file contains no newline characters of any kind ,
L in e F romF i le$ contains the whole contents of the fil e, but without newline characters.
Sub Che ck Newli nes ( LineFromFile As String, FileNum As Integer)
· Sta rt read ing file one byte ata t ime , l ook ing for carriage return.
Do Until EOF(Fil e Num )
char$ = In put$(1 , Fil eNum)
If char$ <> Chr$ ( 13) Then ' If it isn't a carriage r et urn,
If char$ <> Chr$(10) Then ' c heck wh et her it' s a line f eed.
LineFromFil e$ = LineFromFile$ + c ha r$ ' If not, add it t o
El se ' i ts predecessors .
GotFeed % - Tr ue ' Otherwise, set a flag
Endlin e$ = Inpu t $(1, 1) ' and che ck the next
If Endl ine$ <> Chr$(13) Then ' character .
Endline$ = Chr$(13) + Chr$(10 ) + Endline$
Lin eFromFil e$ = LineFromFile$ + Endline$
End I f
End I f
Else
Although creating the form naturall y precedes the other steps, we'll look at Steps 2, 3, and 4
first for an overview of using random file access. Then we'll put the Record Editor
application together.
Defining Records
To accept records from a random-access file, yo u need a variable in your program th at can
treat the collection of individual data fields as a single variable. The Type ... End Type
statement enah les you to create a com pO~i lC clalél type th at mixes strin g and numeric
elements. You then use this data type to define a variable to accept records from th e file.
You can defin e these user-defined types only in the global module.
For more information about user-defi ned types. see Chapter 17, "Advanced Language
Features ... or:
The first field contains a value corresponding to the record's position in the file.
Note that whi le Vi sual Basic permits variable- length strin gs within user-defined types, you
must use fixed- length strings in records that will be placed in a random-access file , because
the correspo ndin g data in each record field must be the same length.
When definin g the field s for random-access records, you must allow for the larges t possibl e
value th at eac h field will contai n. Far example, whi le a person's age will not exceed the
range for an integer, it is quite possible that in a large corporation, the number of employees
may exceed the largest acceptable Integer value. In the example, this would mean that you
should use the Long data type far the Re cor dNum variable. You should make RecordNum
Long.
When fi elds contain strin g data, sorne space is necessarily wasted, because data such as
people 's names vary in length . When a value is assigned to the field, if the ac tual string data
entered in a fie ld is less th an the length with which the field was defined, the trailing space is
automati call y padd ed with blanks (Chr$(32)). Conversely, if you are storing record s
co ntainin g numbers, using random -access file s can conserve disk space when co mpared with
using sequential fil es. Thi s is because sequential files save numbers as a seq uence of
characters representing each digit, whereas random-access file s save numbers in binary
format.
For example, th e number 17000 is represented in a sequential fil e using five bytes , one far
each di git. However, if 17000 is stored in an integer field of a random-access record , it takes
on ly two bytes of disk space.
Integers in random-access files take two bytes , lon g integers and single-precisio n numbers
take four bytes, and double-precision numbers and currency data types take eight bytes.
Recall that after declaring the form of the user-defi ned type, you must define a variab le of
the type the same way you define any other variable:
' Declare t he variable RecordVar having the type RecordType:
Dim RecordVar As RecordType
The program fragments in the next section assume th at this variable has been dec lared in the
global module .
If you recall the Fileüpener example in the section "Opening a File," the case that opened a
random-access file used a Len = clause in the Open statement. A value for Len = was
passed into Fileüpener as the argument RecordLen. The "buffer" for a random-access file
must be exactly the size of one record in the fil e. This must in turn correspond to the size of
the variable of the user-defined type used to receive the data from the file. The length of a
user-defi ned type can be obtained by passing a variable of the type to the Len function . For
ex amp le. to open a file whose records correspond to the Reco rdType type, a value for th at
argument in Fileüpener could easily be calculated in the call as follows , by passing the
variable name RecordVa r to Len:
Con st RANDOMFILE - 4
AName$ = "RecFi l e. XYZ"
' Open a file to hold records of RecordType.
Fi l eNum% = FileOpener(AName$, RANDOMFILE. Len(Rec ordVar))
Example The Function procedure CopyFile receives the names of the files to copy from and copy to,
plus the type of fil e access. A variable of the type used to receive the file 's records is defined
as Re e Va r. The user-defined type RecordType must be defined in the program 's global
module.
CopyFile first determines the length of a single record, then checks that the names are val id
and that a record has a length. After that, each file is ope ned. The number of records in the
source file is determined by dividing the length of th e fil e by the length of a single record . In
a loop that starts with the first record and progresses to the last, the Get statement retri eves a
record from the ex istin g fil e and the Put statement places that record into the new file . When
th e loop conc ludes, both files are closed, and the Function procedure returns True if no
signi ficant eITor was encou ntered . The FileErrors Function procedure, called from the error
handl er, is the sa me one th at was created in th e preceding chapter and used in the Text
Editor example.
Note that the second argu ment to the Get and Put statements co uld be omitted in this
example, because the loop proceeds one record at a time:
Get #O ldNum%, RecVar
Put #NewNum%, . RecVar
No te that each text box has the same name, FieldBoxes. When you type in the CtlNarne
property of the second text box, Visual Basic asks if you want FieldBoxes to be a control
array . An swer Yes. Thereafter you can refer to each box with the name FieldBoxes followed
by its index number in parentheses. For example, the text box labeled First Name will be
FieldBoxes(0). Last Name will be FieldBoxes(l) and so on (assuming you name them in that
order).
The global module far the Record Editor application is similar to that far Text Editor. In
fact, all the Global Const definitions are the same. In addition to the definitions copied from
the file CONSTANT.TXT, the global module should contain the fallowing:
Global Const NUMBOXES - 5
Global Const SAVEFILE = 1, LOADFILE = 2
Global Const REPLACEFILE = 1, READFILE = 2, ADDTOFILE 3
Global Const RANDOMFILE = 4, BINARYFILE - 5
' Display a message telli ng the user how to start using the editor.
Msg $ - "If you want to create a new record file, choose OK,"
Msg$ = Ms g$ +" then choose Add Record to add a new record."+ NL$
Msg$ - Msg$ + NL$ + "To load a file that already exists"
Msg$ - Msg$ +" on disk," + NL$
Msg$ - Msg$ + "choo se the Open File button and type the name"
Msg$ - Msg$ +" of the file you want to open."
MsgBox Msg$, 64, BoxCa ption$
The name for the temporary file is designed to increase the likelihood of its being unique. lf
no such file is found , the temporary file is created with the Fileüpener call and
NewRecordFl ag is set to True, because the only thing you can do with an empty file is to
add records to it. Using the SetFocus method places the cursor in the first text box (you
could !abe! it First Name), so the user can begin entering data right away. Later, when
closing the application, the user can give the file a permanent name, or simply abandon it. In
either case. the temporary file is deleted.
If the temporary file already exists (unlikely, but possible), the user can choose either to
delete it or load it and display the first record. The user could then add more records to the
file without overwriting any that were already in the file. The following key statement makes
thi s work:
LastRecord = LOF(WorkingFileNum%) \ Len(RecordVar)
Su b ShowRecord ()
I f Last Record > 0 Then
' Co nv ert di sp l ay - a rd e r posit i on to a file - record positio n.
Record Number = Position
Get WorkingFi l e Num, RecordNum ber, Record Var
Fi el dBoxes(0).Text = Reco rdV a r . Fi r s tN ame
Fie l dBoxes(l).Text = Reco rdVa r . Las tName
' Don ' t put ze r oes i nto text boxes.
If RecordVar . Salary <> 0 Then
Fie l dBoxes(2) . Text = Str$(Recor dV ar . Salary)
El s e
Fie ld Boxes(2). Text
End I f
I f Reco rdVar.Ag e <> 0 Th en
FieldBo xes(3) . Text - Str$(Record Var . Age)
El s e
FieldBoxes(3). Text
End I f
FieldBoxes(4).Text = Record Var.Gender
' Sa ve val ues s hown in text boxes later compariso n.
Ol dConte nts(0) = Fi eldBoxe s (0 ) . Text
Ol dCo nte nts(l) - FieldBoxes(l) . Text
Old Content s (2) = FieldBo xes (2).Text
Old Co ntent s( 3) = FieldBo xes (3) . Text
Old Co ntent s( 4) FieldBox es (4) . Text
El se
Clea rFi eld s ' I f th e r e a r e no rec ord s , ma ke s ur e fie l ds a re cl ear ed .
End I f
En d Sub
Note th at ali th e variables in thi s procedure are global ( th at is, Wor ki ng Fi l e Num ,
RecordNum ber, Pos i t i o n, Re cordVar, LastRecord and the 01 dConte n ts array). The
FieldBoxes contro l array is known throughout the form mod ule as well.
Sub OpenFile_Click ()
' If the file needs sa ving, get use r' s pe rm ission, then clean up .
If LastRecord > 1 Or CheckEmüut() Then
If WriteOuery(NewFileName$) = True Then
Clean Up File ( NewFileName$)
End I f
End I f
Get Name "Please enter fi l e to open:»
TheName$ = WorkingFi l eName
I f TheName$ = "" Then Exit Sub ' If fil e doesn' t exi st. and user doesn 't
Result% = 1 want to create it, use r will change thi s valu e.
If Confi rmFi le( Th eName$, RAN DOMFILE) - False Then
Msg$ = "Couldn ' t find "+ TheName$ + "."
Msg$ = Msg$ + " Do you want to create " + TheNa me$ + " ?"
Result% = MsgBox(Msg$, 65, "Fil e Not Found" )
End I f
If Result% = 1 Then ' Mak e a backup file . Fi r st.
Period% = InStr(l, The Name$ , " . " ) ' check far an ext ens ion. then
If Peri ad% Then ' co nstr uct the name.
BakNa me Left$(The Nam e$, Pe riod %) + "BA K"
El se
BakName TheName$ + ".BAK"
End I f
' Create a . BAK f i le befare lo ading record s.
If TheName$ = "" Or Bak Name = "" Then Exit Sub
Result% = CopyFile(T heName$, BakName$, RANDOMFILE)
' If there was a prob l em. warn t he user.
If Result% <> Tru e Then
BakName = ""
MsgBox ( "Cou ld n ' t c reate . BAK file " )
End I f
FileNum% = FileOpener(TheName$, RA NDOMFILE. Len(RecordVar)l
If Fil eNum% Then ' Initialize the globals.
WorkingF ile Num = FileNu m%
Wor kingFil eName = TheNa me$
RecordNumber = 1
Po sition = 1
La stRecord = LOF( WorkingFileNum) \ Len(Record Var )
ShowRecord ' Di splay record, t hen turn
TempFileFlag = False ' off Te mp Fil e Flag.
End I f
End If
Forml.Caption "Rec ord Edito r : " + Worki ngFi l eName
End Sub
End If
· If user decided not to add a new record turn the flag off .
If NewRecordFlag Then NewRecordFlag = False
End Sub
Sub DeleteRecord_Click ()
Start with file position of the currently displayed record
(Posi tion) and copy each RecordNumber+l to RecordNumber .
' This leaves a duplicate of the last record at end of the file,
so reset LastRecord to LastRecord - 1. When user exits,
' any duplicate records are expunged using CleanUpFile.
Dim TempVar As RecordType
If Position = LastRecord And LastRecord = 1 Then
Msg$ "Thi s is the last record in the file . Deleting it will destroy"
Ms g$ Msg $ +" the whole file."
Msg $ Msg$ + " Record Editor will also be closed."
Msg$ Msg$ + "Choose OK to destroy file"
If Msg8ox(Msg$, 65, "About to delete file!")= 1 Then
Clas e
Work ingFileNum = 0
TempFileFlag = 0
Ki l l Worki ngFi l eName
WorkingFileName
Cle arFields
End If
End
End If
For Ind% = Po s iti on To LastRecord - 1
Get #WorkingFileNum, Ind% + 1, TempVar
Temp Var.RecordNum = Ind%
Put #WorkingFileNum, Ind%, TempVar
Next I nd%
LastRecor d = LastRecord - 1
ShowRe co rd ' Note thi s display s record
En d Sub ' following deleted record .
lt is crucial to assign the old record number to each new occupant of each position. In the
DeleteRecord_Click procedure, this was done with the statement RecordVar RecordNum
In d% beca use In d %represents the true current position of the record in the file .
Sub ExitButton_Click ()
RecordWasStored% = CheckEmOut()
If TempFi leFlag = True Then
' Ask if user wants to save records to a permanent file ...
If WriteQuery(NewFileName$) = True Then
Writelt% = True ' If so, set flag True.
Else ' Otherwise close all files and
Close ' delete the temporary file, then
Kill Wor kingFile Name ' set the flag to False.
Writelt% = False
End If ' If it wa sn ' t a temporary file,
El se ' see if user want s to sa ve it.
If WriteQuery(NewFileName$) True Then
Writelt% = True ' If so , set flag to True .
Else ' If user doesn 't want to save ...
If BakName <> "" Then
Close ' ... el ose all file s, then delete the file
Kill ijorkingFileName ' befare rewriting it with BAK file contents.
Result% = CopyFile(BakName, WorkingFileNam e, RANOOMFILE)
End If
End I f
End I f
If Writeit% = True Then ' If records are to be sa ved,
CleanUpFile (Ne wFil eName$) ' pass NewFil eName$ (recei ved from
End I f ' Wri teOuery ). and el ean i t up.
Close ' Dn close. anything not written to di sk is wr itten to disk .
End
End Sub
T he way seq ue nti al-fil e access was used in the Tex t Edi tor applicati o n, w he n th e state o f th e
rnul ti line tex t box was saved, the old fi le was overwritten. Because ali the edits to be saved
were in the text box, overwriting the old fi le was the o nl y thin g necessa ry to rn ake the state
of th e fil e the sarne as the state of the tex t box. W ith a rando rn- access fil e, the same is true
whe n a record is changed, then sto reddvbpga path at record overwrites the prev ious record
hav ing the sarne number. When a record is added, it is appended to the end of the file by
givin g it a record nurnber o ne g reater th an th e prev ious La s tR ec ord number. However,
when a reco rd is de leted , it is possible to have old record s still in the fil e, thou gh
inaccess ible.
In the Exi tButto n_C lick procedure, possible dupl icate record s are ex punged permanentl y
fro m the fi le by callin g CleanUpFile. It creates a tem porary fil e containing o nly valid
records, then deletes th e old record fi le, ope ning a new fil e w ith the name of the old record
fi le, and copy in g th e record s fro m th e te mporary file to the new fil e with the old fil ename.
Sub CleanUpFile (NewFileName As String)
CleanF i le Num% = Fil e0 pener( "- T2m3p 7-.Tmp " , RAND OMFILE, Len(Reco r dVar))
Far Ind& = 1 To Last Record
' Place all vali d r eco r ds (i.e. thase preceding LastRecard)
' in a temparary f i le .
Get #WarkingFileNum, Ind&, RecordVar
Put #CleanFileNum%, Ind&, RecordV ar
Next I nd&
Clase WarkingFileNum% · Clase bath files. If it was a temp
Clase CleanF i leNum% · ar renamed file. use CapyFile.
If TempFileFlag Or (UCase$(WarkingF ile Name) <> UCase$(NewFileName$)) Then
Resul t% = CapyFi le( "-T2m3p7-. Tmp", NewFi l eName$. RANDOMFILE)
Kill "-T2 m3p 7-.Tmp "
Else
' Otherwise. if it is justa file being cleaned up, but not renamed,
' delete original file, and rename the temp file with orig inal name.
Kill WarkingFileName
Name "-T2m3p7-.Tmp " As WarkingFi leName
End I f
End Sub
So far, finding a specific record using Record Editor is a matter of stepping past each one
with the Next Record or Previous Record buttons, until you find the one you want. You can
change this so the Record Editor can skip among records, displaying any record without
stepping past the others individually. Far example, add a horizontal scroll bar to the bottom
of the form, as shown in Figure 2 1.4, and set its Ct!Name property to HScroller.
Sera// bar
Figure 21.4 Adding a horizontal scroll bar to Record Editor
In addition to calling the ScrollerUpdate Sub procedure from HScroller_Change, you will
have to call it from the Form_Load procedure to initialize the scroll bar, as well as the
NextRecord_Click and PreviousRecord_C lick procedures, which are often called after a
record is added or deleted. Also, add this line at the end of the NextRecord_Click and
PreviousRecord_ Click procedures:
HScrol l e r . Valu e = RecordNumber
Thi s will keep the scroll box on the scroll bar positioned correctly when the user moves
among records using the Next Record and Previous Record command buttons. There is no
need to update the scroll bar when the user deletes a record or adds a record, because
Re cord Number does not change in ei ther of those situations. The only change is to the data
to which the record number refers. LastRecord is altered, but the next time the scroll bars
change, these new values are taken into account.
Binary access is a way to get at the raw bytes of any file , not just ASCII- or ANSI-form al
text files. This makes it very useful for reading or modifying files saved in other formats,
such as Microsoft Word files or executable files.
Files opened for binary access are treated asan unformatted sequence of bytes. Although
you can read or write a record (a variable declared as having a user-defi ned type) to a fil e
opened in the Binary mode, the fil e itself does not have to be organized into fixed-len gth
records. In fac t, binary 1/0 does not have to deal with records at ali, unless you consider
eac h byte in a file as a separare record.
Here, variable can have any type, including a variable-length strin g ora user-defined type,
ancl positio11& points to the place in the fil e where the next Get or Put operation will take
place. (The value of position& is relative to the beginning of the fil e; that is, the first byte in 1
the fil e has position one, the second byte has position two, and so on.) If you leave off
position& , successive Get and Put operations move the file pointer sequ entially throu gh the
file from th e first by te to the las t.
The Get statement reads a number of bytes from the file equal to the length variable.
Similarly, the Put statement writes a number of bytes to the file equal to the length variable .
For example, if variable has the integer type, Get reads two bytes into variable; if variable
has the single-precision type, Get reads four bytes. Therefore, if you don't specify position
in a Get or Put statement, the file pointer is moved a distance equal to the length variable.
The Get statement and Input$ function are the only ways to read data from a file opened in
Binary mode. Put is the only way to write data to a file opened in Binary mode.
Binary access, unlike random access, enables you to move to any byte position in a _file and
then read or write any number of bytes you want. In contrast, random access can only move
to a record boundary and read a fixed number of bytes (the length of a record) each time.
Example In the following example the CopyFile Function procedure used in Record Editor is
rewritten using binary access, as BinaryCopy. Because it simply makes a byte-for-byte copy
of the file to be duplicated, you can use this procedure for any file, regardless of the type of
access normally used. For example, the procedure could be used in Record Editor, in place
of CopyFile. Because the variable used in the transfer is an integer, the bytes are transferred
two ata time, which is why the loop proceeds with a Step 2.
Function BinaryCopy(Namel As String. Name2 As String) As Integer
On Error Goto BinaryCopyHandler
Name1Num% = FileOpener(Namel. BINARYFILE. 0)
Name2Num% = FileOpener(Name2, BINARYFILE. 0)
If Name1Num% <> 0 and Name2Num% <> 0 Then
Filelen& = LOF(Name1Num%)
For Ind& = 1 to Filelen& Step 2
Get #Name1Num%, Ind&.Holder %
Put #Name2Num%. Ind&.Holder%
Nex t Ind&
Binary Co py = True
El se
BinaryCopy = False
End If
Exit Fun ction
BinaryCopyHandler:
Action% = FileErrors(Err)
Select Ca s e Action%
Case 0
Res ume
Case 1
Res ume Ne xt
Case 2
BinaryCopy - False
Exit Function
Ca se Else
Error Err
End Se l ec t
End Funct i on
Note that the record length argument used with Fileüpener is zero. With binary files, the
record length is not used . Even if it is specified in the Open statement, it is ignored .
After a Seek statement, the next read or write operation in the file opened withfilenwnbero/o
begins at the byte noted in position& .
The counterpart to the Seek statement is the Seek function , which uses thi s syntax:
Seek (file11111 11bero/c )
The Seek functi on tells you the byte position where the very next read or write operation
begins . (lf you are using binary VO to access a file , the Loe and Seek function s give similar
res ult s, but Loe returns the position of the last byte read or written, while Seek return s the
position of the nex t byte to be read or written .)
One of the most powerful aspects of the Microsoft Windows and Presentation Manager
operating environments (compared with earlier operating systems) is the ease with which
data can be shared among applications. In Chapter 18, "Interacting with the Environment,"
you saw that Visual Basic applications can use the Clipboard to share data with other
Windows or Presentation Manager applications.
But Visual Basic provides capabilities that go farther than that. Vi sual Basic implements
dynamic data exchange (DDE), a standard method for transferring data between applications
runnin g in the operating environment. Using DDE, your Vi sual Basic applications can
automatically obtain data from other applications, whenever that data changes, without
requiring any work on the part of the user. Similarly, Visual Bas ic applications can provide
data - such as commands and even individual keystroke input - to other running
..-.
···-··.
. • ••
applications on an ongoing basis. This gives your Visual Basic application the ability to
comrnunicate with any running program.
The main sections in this chapter are:
• What Is Dynamic Data Exchange?
• Creating Links at Design Time
• Link Properties
•
•
•
•
Link Events
E nabling Users to Create Their Own Hot Links
Using Methods to Perform DDE Operations
Handling Errors
•• -- •• •
••••
• Sending Key strokes to Other Applications
•••
•
••
•
••
•
11
• •
• •
354 Part 4 Advanced Applications
Note Not all applications support DDE. Consult the documentation for your other
applications to see if they support DDE.
l
Microsoft Visual Basic Programmer's Guide
Chapter 22 Communicating with Other Applications 355
Application Name
Every application that can be a DDE server has a unique application name. Usually this is
the executable filename without any extension. The names of a few Microsoft applications
are shown in the following table.
Application DDE application name
Microsoft Excel Excel
Microsoft Word for Windows WinWord
Microsoft Word for Presentation Manager PMWord
When a form in a Visual Basic application is the server in a conversation, its application
name is the name you choose for the application when you make it into an executable file . If
you are running your application within Visual Basic. the application nam e is the name of
the project without any file extension.
Note For the application name of other Windows applications, see the documentation for
those applications.
Topic
The tapie defines the subject of a DDE conversation and is usually sorne unit of data that is
meaningfu l to the server application. Most applications recognize a document name as a
tapie for a DDE conversation. For example, Microsoft Excel recognizes a filename
(including the path if necessary) ending in .XLS or .XLC, while Word recognizes a filenam e
ending in .DOC.
When a form in a Visual Basic application is the server in the conversation, you can specify
the tapi e by setting the LinkTopic property for the form. The LinkTopic property is
described later in this chapter in the section "Link Properties."
Many app lications that perform DDE support a tapie called "System." You can use this tapie
to request information from the application (what other tapies it supports, what data formats
it supports, and so on). Check the documentation for the application to see if it supports this
tapie.
ltem
The item identifies the piece of data actually being passed during the DDE conversation. For
example, Excel recognizes cell references (such as RlCl) as items in a conversation.
When a co ntrol in a Visual Basic application is the client in a conversation, it defines the
ítem for the conversation by setting the Linkltem property for that control. The Link.Item
property is described later in this chapter in the section "Link Properties."
When a form in a Visual Basic application is the server in a conversation, the name of each
of the text boxes, label s, and pictures on the form can be the itero for a DDE conversation .
Links
A DDE conversation is often called a link because the two applications in the conversation
are linked by the data they are exchanging. There are two kinds of links, distinguished by
how the server updates the client when data in the server changes:
• Hot link: The server supplies new data to the client every time the data defined by the
Linkltem changes.
• Cold link: The server supplies new data only when the client requests it.
If the link is successful, the contents of the control (the Text property of a text box, the
Caption of a label , or the Picture of a picture box) change to display the cuITent state of the
data in the server application. If the Paste Link command on the Edit menu is unavailable,
then the server application you attempted to paste the link from does not support DDE, or
cannot provide data in a format that Visual Basic recognizes .
Remember that this is a hot link; once the link is established, the contents of the control will
l
change whenever the data in the server application changes. This will happen whi le yo ur '
application is running (causing a Change event) and whi le you're building the application ,
so don 't be surprised if you see the contents of controls changing at design time.
This link is saved wi th the form and is "permanent. " Whenever the application is opened (in
des ign time as we ll as run time) , it attempts to re-establish the conversation with the server
a pplicati o n.
Note W hen a Visual Basic application containing hot links is opened or run , Vi sual B asic
checks to see if there are any server applications running that recognize the topic of the
conversatio n. lf there is another application that recognizes the topic , Visual Basic
esta bli shes the conversation. If no application responds , Visual Basic di splays a message
askin g the user i f it should attempt to start the other application . If the user chooses Yes,
Visual Basic atte mpts to run the application , with the spec ified topi c .
If the lin k is s uccessful , the contents of the control (the Text property of a tex t bo x, the
Caption of a label , or the Picture of a picture box) are di spl ayed in the cli ent ap plica ti on. lf
there is no Paste Link co mmand in the cli ent application , th en it does not support DDE hot
links. If the Pas te Link comm and ex ists but is unavailabl e, then the c li ent does not recog ni ze
the data you attempted to suppl y from your Visual Basic appli cati on . Many a ppli catio ns do
not recogni ze picture d ata, for example, and sorne restrict the kind of info rmati o n that can
appear in certain parts of their documents. Consult the documentation for the cli ent
application if thi s is the case.
Once yo u ha ve establi shed a hot link between a contro l in your appli cati on anda client
appli catio n, V isual Basic autom aticall y suppli es new data to the cli ent appli ca ti on every tim e
the contents of the control change. You can change the co ntents of th e co ntrol at design tim e
and watch as Visua l Basic suppli es the new data to the other appli cation.
However, w hen yo u run yo ur app li cati on Visual Basic mu st break the links as it sw itches
from des ig n time to run tim e . Sorne app li cati ons handl e thi s and auto mati call y at te mpt to re-
estab li sh the ir DDE co nversati ons, but you may find that the serve r links you esta bli shed at
design tim e no lon ger work at run tim e . Most app li cati o ns that suppo rt DDE provide sorne
way to refres h the ir links manuall y ; consult the docum entation for that application .
Link Properties
Us ing the Copy and Paste Link commands to establish DDE conversations is fine for quick
programming tasks, but they aren't flexible enough for most sophisticated applications. In
add ition , they don ' t enable you to set up conversations with other applications that support
DDE but do not provide Copy and Paste Link commands.
To go further with DDE in Vi sual Basicdvbpgapato create and use DDE conversation s from
code, orto manu all y establish conversations without using Paste Linkdvbpgapayou mu st
exp lore and use the Link properties of forms and controls.
Th e nam e o f th e se rver application is separated from the topic by a vert ical bar or " pipe·'
character (c haracter code 124). For example, a link with a Microsoft Exce l spreadsheet
mi g ht loo k like th is:
Ex ce llc:\exce l\pay .x Is
You can ~et thi s property for any text box , !abe! , or picture cont ro l. Jf you know the
appl ica ti on na me for an app li cation , and a topic ii: support s, you can establi sh a DD E
con ve rsa tion w ith that applicati on .
Note If the server application terminates a conversation, the LinkMode property is not set
to None. Instead, a LinkClose event (described later in "Link Events") occurs, but the
LinkMode property retains its value. Once the conversation is terrninated, performing any
DDE operation on this link causes a run-time error.
Example The following code for a form Click event attempts to establish a hot link conversation
between a text box on the form and Microsoft Excel when the form is clicked the first tim e.
Each time the form is clicked after that, the item for the conversation is changed (notice that
this <loes not terminate the conversation):
Sub Form_Click ()
Const HOT = l. NONE = 0
Static Row as integer
Row = Row + 1
If Row = 1 Then
Textl.LinkMode = NONE
Textl.LinkTopic = "E xce l Jc:\excel\amortize.xls"
Textl . Linkltem "RlCl"
Textl.LinkMode HOT
El se
Textl. Li nkltem "R" + LTrim$(Str$(Row)) + "Cl"
End I f
End Sub
Note The co nstants HOT, NONE, COLD, and SERVER, and the constants for the various
DDE error values, are contained in the CONSTANT.TXT file . You can use these constants
in your code if you load this file into the global module for your application .
You also ca n se l lhe LinkMode property to Cold (2). When LinkMode is Cold, a
conversat ion ex isls, but the control does not automatically receive new data whenever il
changes . To obtain the most up-to-date data, you must use the LinkRequest method on the
co ntrol.
Example The fo llowing code for a form Click event attempts to establish a warm link conversation
betwee n a tex t box on the form and Microsoft Excel when the form is clicked the first tim e.
Each time the form is clicked after that, new data is requested:
Sub Textl _Click ( )
Const CO LO = 2, NONE = 0
If Textl .LinkMode = NONE Then
Textl. LinkTopic = "E xce l lc:\e xcel\ amortiz e.x l s "
Textl.Linkltem "Rl Cl "
Textl.LinkMode = COLO
End 1f
Textl.L inkRequest
End Sub
If th e LinkTopic or Linkltem property is not set to a valid value, then setting LinkMode to
Hot or Cold causes an error.
Note If Vi sual Basic seems to be "hung up" during a DDE conversation , and you don'l
want to wa it for th e time-o ut error to occur (or you have set the LinkTimeüut property to - 1
so il wi ll ncver occur), you can recover by press ing the A LT key. Press ing ALT interrupts any
pend in g DDE operation s in Visual Basic and generates a trappable run-time error.
If there are controls on the form called Interest, Principal , and Balance, then these are al i
va lid items for this conversation .
If you change the LinkTopic property, Visual Basic terminares ali conversations on that
topic. The client applications can then re-establish links with the new topic.
For more information on the Link properties, see th e Language Reference, or:
Link Events
As you might expect, there are events associated with links, and you can write event
procedures to respond to these events. The controls that can be clients in a DDE
conversation recognize these DDE-specific events:
• LinkOpen
• LinkClose
• LinkError
When form s are ac tin g as DDE servers, they recognize these events:
• LinkOpen
• LinkCl ose
• LinkError
• LinkExecute
Client Events
There are three even ts that can only occur when a control is engaged as the client in a DDE
conversation: LinkOpen, LinkC!ose, and LinkError.
This is useful for deb uggi ng purposes, as in the example above, or whenever you want to
perform sorne opera ti on (suc h as reading a file) every time th e control successfull y initi ates
a DDE conversa ti on.
Server Events
There are four events that can occur only when a form is engaged as the server in a DDE
conversation: Linküpen , LinkClose, LinkError, and LinkExecute.
Ir a fom1 has no eve nt proced ure for the LinkExecute event, then when a el ie nt attempts to
se nd a corn mand to the ~orm it always receives a negative acknowledgernent.
For more informat ion on Link events, see the Language Reference, or:
Note While you are exploring thi s, you' ll find the Clipboard appli cation (CLIPBRD .EXE)
invaluable. Supplied with your operating environment, it enables you to observe the ac tual
data that your code is placing on the Clipboard.
T he examples in thi s secti on ass um e that yo ur appli ca ti on includes a menu co ntro l array
called MenuB ar that includes an Edit me nu with the usual commands: Cut, Copy, Paste, and
Paste Link .
T he Appliccil ion and Tapie are separated by a vertical bar or " pipe" charac tcr (c harac ter code
124 ), and the Tapie and ltem are separated by an exclamation point (c harac te r code 33).
No ti ce that thi s is just an ex tension of the conve ntion used in the L in kTopic property for
co ntrols (described earlier in thi s chapter). Thus, to perform a Paste Lin k opera ti on:
• Obtain the link information from the Clipboard.
• Split the information into a string fo r the applicati on and topic, and a st rin g for the item.
• Use these strings to set the LinkTopic and Linkltem properti es for th e co ntro l th at is
acce pting the Paste Link.
You ca n then determine the active control by using the Acti veContro l prope rty of th e
Screen object.
For more in formati on on the Screen object, see Chapter 18, "Interactin g with the
Enviro nment"; the Language Referenee; or:
The code assumes th at the constant PASTELJ K is defined in the Declarations section of
the form code and is et equal to the index of the Paste Link menu item .
This code makes the Paste Link command unavailable if there isn't valid link data on the
Clipboard, or if the active control is nota text box or picture box . You do not have to
consider labels because the user can't select them; thus, a label will never be the active
control.
In addition , thi s code ensures that the Paste Link command is enabled only if the data on the
Clipboard is avail able in a form at appropriate for pasting into the active control: CF_ TEXT
for a tex t box , and CF_BITMAP for a picture box. You also may want to test for CF_DIB
and CF_MET AFILE for a picture box .
For the Application use the project name (if you are runnin g your appli cati on in V isual
Basic) or the appli cati on titl e you provide in the Make EXE File di alog (if you are runni ng
your app lication asan executable fil e). Tapie is the LinkTopic property for th e fo rm , and
It em is the name of the contro l that provi des the data in the link . Because the Ct!Narne
property is not avai lable at run time, you m ust store the nam e of each co ntrol in its Tag
property.
l t is good prac tice to place the ac tu al contents of the contro l (the Text property of a tex t box
or the Pict ure property of a picture box) on the C lipbo ard along with the link in fo rmati on.
You can place m ul tiple pieces of data on the Clipboard as lo ng as you use a d iffere nt forma l
for eac h piece.
Sub Edi t _Click ( Index As Integer)
Select Case Index
Case CU T
' Code to su pport Edit Cut (omitted ).
Case COP Y
Clipboard.Clear
AppTopName$ = App Name() + "I" + LinkTopic
AppTop Name$ = AppTopName$ + "!" + Screen .Acti veContr ol . Tag
If Ty peOf Scree n. Act iv eCo ntrol Is PictureBox Then
Cl ipboard.SetText AppTop Name$, CF_ LINK
Cl ipboard.SetData Sc r ee n . Acti veControl .P i ct ure
Else lf TypeOf Screen.Acti veControl Is TextBox Then
Clip board . SetText AppTo pName$, CF_ LINK
Cli pboard.SetText Sc reen . Activ eCont rol .Text
Elself TypeOf Sc reen.Acti veControl Is CheckBox Then
Clipboard.Se tText St r$(Scre en.ActiveCo ntr ol .Value )
Else
' Copy appropriate data from other types of control s.
End I f
Case PASTE
· Co de to support Ed it Paste (omi t t ed).
Case PASTELINK
· Code to su pport Edit Paste Link (omitted).
End Select
End Sub
T hi s code ass um es the ex istence of a Function procedure call ed App ame that re tu rn s the
na me of the app li cati on. If yo u're ru nning th is code in V isual Basic , th e procedure should
re turn th e name of the projec t without any fil e extensio n. If you are run ni ng an exec utable
file , it sho uld retu rn the appli cation title you prov ide in the Make EXE Fil e dialog .
Note Jf the con tro l th at provides data in the lin k is pa rt of a con tro l array , th en l!em should
inc lude the array index enclosed in parentheses.
Sorne applications provide a topic called System that you can use to request information
about that application, such as what other tapies the application supports. Microsoft Excel
and Microsoft Word for Windows both support a System tapie ; for other applications,
consult the documentation for that application. If you are creating a sophisticated Visual
Basic application, you may want to provide a System tapie by including a form with its
LinkTopic property set to System and controls for various system items.
For more info rmation on the Shell functi on, see the Language Reference, or:
W hen used with a pictu re box control, the LinkPoke meth od sends the contents of the
Picture property (ra ther th an the Image property).
oti ce that whcn you firs t establi sh a warm lin k, no da ta is immedi ately transferred. Yo u
must perform an exp li cit LinkRequest me th od to ge t any data in a warm link.
Every appl ication accepts different command strings, so you should consult the
documentation for the application to see what commands it will accept. Microsoft Excel, for
instance, enab les yo u to send a series of macro commands with a si ngle LinkExecute
statement by enclosing each command in square brackets. For example, this code commands
Excel to save the current file and then quit:
Link .LinkExecute "[ SA VE () J[QUIT()]"
For more information on Link methods, see the Language Reference, or:
Handling Errors
As with other ac ti vities, errors can sometimes occur whe n a Vi sual Basic application is
pe tiorming DDE. The kinds of errors that occur ca n be divided into two groups :
• Errors that occur in statements , function s, or express io ns w ithin executing code in the
same way that run -time errors occur in any exec utin g code .
• Errors that occ ur when no code is being executed.
Errors of th e first kind are no differe nt th an any other run -tim e errors, and can be handl ed
with standard erro r-handling statements and function s prov ided in Visual Basic. For more
inforrnation on handling these kinds of errors, see Cha pte r 19, " Handlin g Run -Time Errors."
rora li st of ali trappable run-time errors, in c ludin g the DDE errors, see the Language
Refe rence , or:
The second group of errors may seem somewhat unusual. How can an error occur if no code
is executing? To understand this, remember that Visual Basic is always performing a variety
of operations, even when none of your Visual Basic code is executing. One thing Visual
Basic does is update hot links whenever data changes. Many errors can occur at this point;
for example, the data may be in the wrong format, or it may be so large that copying it
causes Visual Basic or the operating environment to run out of memory . Visual Basic deals
with this by generating a LinkError event. You can write an event procedure to handle this
event like any other event, as explained in the next section.
For example, suppose you have a text box called CurrentPrice that is engaged as the client of
a DDE conversation. To handle errors that might occur durin g the DDE conversation, write
an event procedure like this:
Sub CurrentPrice_ LinkError (ErrNum as Integer)
Select Case ErrNum
Case OUT_OF_MEMORY
Msg$ - "Not enough memory to perform DDE . "
Case WRONG_FORMAT
Msg$ = "DDE data is not in the ri ght format. "
Case Else
' Handl e other er ror s.
End Se lect
MsgBox Msg$
End Sub
Of course, if the control is an element in a control array, there will be a second argument for
the array index .
Note The constants for various kinds of errors (for example, WRONG_FORMAT) are
defined in the CONSTANT.TXT file . If you merge this file into the global module, you can
use th ese constants in your code.
Calling the DoEvents function causes Visual Basic to "yield" briefly and allow other
application s to execute. In the example above, calling DoEvents after performing th e
LinkPoke method enables Microsoft Excel to handle its side of the DDE conversation.
Sorne applications have to do more work to handle DDE than others; you may find that one
call to DoEvents is not enough, and that you must call DoEvents several times in a short
loop.
If you get a lot of run-time errors indicating that the other applications are busy or not
handling DDE properly, try placing a call to DoEvents in your error-handling code:
On Error Goto ErrHandler
' DDE code her e.
ErrHandler:
If Err = DDE_ ERROR Then
dummy%= DoE vents()
Resume
Else
Error Err
End I f
For more information on DoEvents, see Chapter 18, "Interacting with the Environment"; th e
Language Refe rence; or:
Note You can send keystrokes to any application running in the operating environment,
whether it supports DDE or not. However, you cannot send keystrokes to a DOS virtual
machine (a DOS sess ion running in a window).
The key strokes don ' t actuall y get sent until yo ur Visual Basic application is
" idl e"dvbpga paw hen none of yo ur Visual Basic code is exec utin g or when the DoEvents
fun ction is called .
But where do the keystrokes go? They go to the acti ve applicati o n (the app lication that has
the focus) . However, if the currentl y active application is not the o ne to which you want to
send keystrokes, then you ' 11 need to know how to activate other applications.
1f the application is not already running, you must start it w ith the Shell function (described
earlier) befare you can actívate it and send keystrokes to it.
For more information on the AppActivate statement, see the Language Reference, or:
T he names of the keys are not case-sensitive, so {enter}, {En ter}, and {ENTER} a li mean
the same thing.
For a complete list of the special key names, see the tapie for the SendKeys stateme nt in the
Language Reference, or:
You have reached the last chapter of this manual, but not the end of what Visual Basic can
do. One of the most distinctive features of Visual Basic is its open-endedness. Visual Basic
was designed to provide you with all the features you need to create many kinds of
applications. But at sorne point you may want to do something that seems to be beyond its
capabilities. When this happens, you can extend the capabilities of Visual Basic itself.
There are two fu ndamental techniques for extending the capabilities of Visual Basic:
• Loading a custom control fil e
• Calling a routine in the operating environment or in third-party dynamic-link
libraries (DLLs)
Custom control files provide new types of controls that become part of the development
environment and supply new capabilities to your applications. When you load a custom
control file , Visual Basic adds the custom control to the Toolbox. You then use custom
controls just like any other type of control. Custom control files are difficult to build, but
they are easy to use.
You also can make direct calls to routines in the operating environment DLLs. DLLs expand
the capabilities of the language beyond the keywords supported in Visual Basic. The
operating environment is actually made up of severa! DLLs that provide a rich set of routines
(Visual Basic itself works by calling these routines). You also can call routines in other
DLLs that you have in your sys tem. By calling these routines, you can accompli sh
speciali zed tasks that are otherwise difficult or impossible to perform with Visual Basic
alone.
The main sections in this chapter are:
• Loading Custom Controls
• Declaring and Calling DLL Routines
• Special Considerations When Declaring DLL Routines
• Calling DLL Routines with Specific Data Types
• More Information About Dynamic-Link Libraries
378 Part 4 Adv anced Appl ic ation s
Yo u now can use th e new co ntro ls just as if they were standard controls. You ca n add them
to any of the form s in yo ur proj ec t.
Each cus tom co ntrol has its ow n se t of propert ies and events, whi ch you can see by using the
Prope rti es bar and Code w ind ow . Certain properti es - such as Ctl Name-sho uld be present
in e very cont ro l, but custom controls ca n have new properti es and eve nts beyond the scope
of standard co ntro ls. Consul t the documen tation tha t accompani es the custo m co nt ro l fil e for
inf"orma tio n o n how Lo use th ese prope rt ies and eve nts.
Note You ca n use custom controls with Visua l Bas ic, but you cann ot use Vi sual B as ic to
create c ustom co ntro ls. If you wa nt to creare custom control fil es yourself, yo u need the
Vi sual Basic Co ntro l Develop ment Kit, a se t of tools and documentati on for writin g custom
co ntro ls (ava il able fro m M icrosoft). l n add itio n. you need a software development product
that all ows yo u to create D LLs, such as M icrosoft C and the Mi crosoft Wind ows Soft wa re
Deve lopment Kit (SDK ). Wrilin g custom co ntro ls requires greater technical kn o wl edge than
what's req ui red to progra m in V isua l Basic. H owever, if you create c ustom co nt roJs, you ca n
d istribute th em to any V isua l Basic user.
You declare a DLL routine only once . You then can call it any number of times.
If the routine does return a value, declare itas a Function procedure. For example:
Declare Function IsZoomed Lib "U ser " (By Va l hWnd %) As Integer
Notice the Lib and ByVal keyword s in the Declare statement. It also ca n co ntain an
opti onal Alias keyword . The use of these keywords is explained in the sec ti on "Special
Considerati ons When Declaring DLL Routines" later in thi s chap ter.
For the complete syntax of th e Declare statement, see th e Languag e Refe rence , or:
lmportant Visual Bas ic can' t veri fy you are passi ng correct values to a DLL routine. If you pass
incorrec t va lues, the ro utin e may fa il , whi ch may cause yo ur Visual Basic application to
crash. This doesn ' t cause perm anent harm , but yo u' ll have to reload and start your
application. Take care when ex perimentin g with DLL ro utin es and save your work often.
Note Visual Basic does not incl ude the doc ument ati on fo r the routines in the operating
e nvironment. The ro utin es are documented in the SDK, and in the Microsoft Windows
Programmer 's Reference published by M icrosoft Press.
If you are attemptin g to call a ro utine in a DLL that is not part of the operating environme nt,
you mu st determine the proper declaration fo r it. T he rest of thi s sec ti on explains the sy ntax
of the Declare state ment in deta il so that you ca n create the correc t declaration fo r the
routine.
For example, the lnvertRect routine accepts its first argument by value and its second by
reference:
Declare Sub InvertRect Lib "User" (By Val hDC%. aRect As Rectangle)
Note When you're looking at DLL routine documentation that uses C language sy ntax,
remember that C passes ali arguments by value except arrays .
You then can call this routine with either a string ora long integer as its first argument:
re su lt s% - fxCreatelmage(imageStr$, flag Var%)
results% = fx Cre atelmage(ByVal imageVal&, flagVar%)
Note that w hen you remove type restrictions, Visual Basic assumes the argument is passed
by reference. Use ByVal in the actual call to the routine (as shown in the second example
above) to pass arguments by value .
Nonstandard Names
Occasionally, a DLL routine has a name that is nota legal identifier: It mi ght have an invalid
character (such as a hyphen) , or the name might be the same as a Visual Basic identifi er
(such as Loop) . When thi s is the case, use the Alias keyword .
For example, there are routines in the operating environment DLLs that begin with an
underscore character. While you can use an underscore in a Visual Basic identifier, you
cannot begin an identifi er with an underscore. To use one of these routines, you mu st declare
the routine with an ali as:
De c lar e Function Lüpen % Lib " ker nel" Alias "_ lopen" (ByVal fn$, ByVal f%)
In this example, LOpen% becomes the name of the routine as it is referred to in your Visual
Basic procedures. The name _ l open is the name recognized in the DLL.
You can use the Alias clause whenever it' s convenient. For example, thi s Declare statement
substitutes a shorter nam e (SetBlink) for the ful] name (SetCaretBlinkTime) :
Declare Sub SetB link Lib "User" Alia s " SetCaretBlinkTime" (By Val count%)
Strings
The routines in most DLLs expect standard C strings (sometimes called ASCIIZ strings),
which endina null character (ANSI zero) , If a DLL routine expects a C string asan
argu ment, declare the argumentas a string with the By Val keyword. When used with a
strin g arg um ent, ByVal tell s Visual Basic to pass the string as a C string ending with a null
character. For exa mpl e, the RegisterClipboardForma t rout ine accepts a string th at names a
new C lipboard for mat:
De cl are Function RegisterC lipboardF ormat% Lib "U se r" (By Val FormatName$)
Because th e string argument for thi s routine is declared with ByVal, Vi sual Bas ic
auto maticall y converts a variable-length strin g passed to this routine into a standard C string:
FormatNumbe r % = Reg i sterCl ipboardForm at%( " RTF " )
Sorne DLLs m ay be written specifically to work with Visual Basic . A DLL can be written to
use standard Visual Basic strings, usin g routines that Vi sual Basic suppli es far this purpose
(th ese rout ines are doc umented in the C ustom Con trol Development Kit). If a DLL routine
eXpects a Visual Basic s trin g asan arg umen t, you do not need to declare the arg um ent with
the By Val keyword . In additi on, sorne of th e DLL routin es written far Vi sual Bas ic rnay act
as run ct ions th at return st1ings. A DLL routine cannot actas a function that return s strin gs
unl ess it was writte n specificall y far use with Visua l Basic. A DLL written specificaJly far
Vi sual Bas ic probably suppli es a file co ntainin g the co rrect Visual Basic declaration s far th e
rout in es in the DLL. Consult the doc umentation far the DLL fa r detail s.
A safe way to call this routine is by first making the returned argument at least 255
characters long by filling it with characters - in this case null (ANSI O) characters:
Path$ = Stri ng$(255, 0)
worked % = GetWindowsDirectory(Path$, Len(Path$) )
When calling a DLL routine, Visual Basic always converts fixed-length string arguments to
variable-length strings. So both of these processes amount to the same thing: creating a
variable-length string long enough to contain the largest possible string that the routine
mi ght return.
Note The operating environment DLL routines generally do not retum strings longer than
255 characters While this is true of many other libraries, always consult the documentation
for the routine in question.
Visual Basic strings can be used when the DLL routine calls for a memory buffer. Use one
of the processes outlined above to ensure that the string is large enough to accept whatever
data the routine supplies.
Arrays
You can pass individual elements of an array the same way you pass any variable of th e
same type as the base type of the array. For example, you can use the RegisterCl ipboard-
Format routine declared earlier to register a series of fom1ats stored in an arra y:
For i% = 0 to UBound(ClipboardFormats$)
FormatNumber(i%) = RegisterClipboardFormat(ClipboardFormat s $(i%))
Next i%
You cannot pass an entire array to a DLL routine as you would pass an entire array to a
Visual Basic procedure. Remember that you can pass an en tire arra y to a procedure that
accepts an array asan argument by passing the array with empty parentheses. You ca nnot do
this with DLL routines. Instead, you can pass an entire numeric array by passing the first
element of the array by reference. This works because numeric array data is always laid out
seq ue ntially in memory . A DLL routine given the first element has access to ali th e
ele ments.
This is not true of string anays , however. If a DLL routine attempts to access me mory
beyond the end of the first element in a string array, it may co rrupt memory or cause an
error. If a DLL routine expects a buffer passed by reference as an argument, yo u shou ld
suppl y either the first element in a numeric array ora strin g. In eith er case, the array or the
string sho uld be at least as large as the routine expects so that it does not write past the end
and corrupt memory.
User-Defined Types
Sorne DLL routines take user-defined types as arguments. These are referred to as
"structures" in C and "records" in Pascal. DLL documentation often uses the C terminology .
As with arrays, you can pass the individual elements in a variable of a user-defined type the
same way you would pass ordinary numeric or stri ng variables.
You can pass an en tire user-defined type as a si ngle argument if you pass it by reference.
User-defined types cannot be passed by value. Visual Basic passes the address of the first
element, and the rest of the elements of a user-defined type are packed in memory followin g
the first element. For example, severa] routines in the operating environment DLLs accept a
user-defined type with this structure, which is placed in the global module:
Type Rectangle
Left As I nteger
Top As Integer
Right As Integer
Bottom As Integer
End Type
Two of the routines that accept a rectangle are DrawFocusRect, which draws a dotted outline
around the specified rectangle, and InvertRect, which inverts the colors of the specified
rectangle. To use the routines, place these declarations in the global module:
Declare Sub DrawFocusRect Lib "U s er" ( ByVa l hDC%, aRect As Rectangle)
Declare Sub InvertRect Lib "User" (By Va l hDC% , aRect As Rectangle)
Now you can use the following Sub procedures to cal! the two routines - one to display a
rectangle as you drag the mouse, and one to inven the rectangle when you release the mouse
button:
Sub Form_MouseDown (Button As Integ e r. Shi ft As Integer, X As Single,
• Y As Sing l e)
ScaleMode = 3
If Button And 1 Then
MouseRect.Left = X
MouseRect.Top = Y
MouseRect.Right = X
MouseRect.Bottom = Y
End I f
End Sub
Notice that these routines expect the values for the rectangle to be expressed in pixels, so
you should set the ScaleMode property of the form to 3 - Pixel at design time.
Most routines that accept user-defined types do not expect the user-defined type to contain
string data. However, you ca n pass a user-defined type that includes string elements to a
DLL routine. If the string elements are fixed-leng th strings, they are packed in memory li ke
any other value. However, vari ab le-length strings are incorporated in a user-defined type as
string descriptors, a Vi sual Basic data structure which takes four bytes for each variable-
length string element. Unl ess a DLL routine is written specificall y for Visual Basic, it cann ot
use a use r-defi ned type that co ntai ns variable-length strings .
Null Pointers
Sorne DLL routi nes occasionally expect to receive a null pointer as an argument. If you need
to pass a null pointer to a routine, declare the argument with As Any (as described earlier in
the section "Flexible Argument Types") and pass the expression By Val 0& .
For exarnpl e, the FindWindow routine accepts two string arguments, so you would expect to
dec lare it like thi s:
Declare Function FindWindow% Lib "U se r" (By Val Cl ass$, ByVal Captio n$ )
However, Fi ndWindow also accepts a null pointer for either or both of its arguments. If you
declare it in this way you cann ot pass null pointers to it. Passing a zero-length string (" ")
does not work ; thi s passes a pointer to null string, nota null pointer.
The so lution is to declare the routine like thi s:
Declare Function FindWindow% Lib "U ser " (C l ass As Any, Cap tion As Any)
Now you ca n call the routine and pass it two strings as you normally would. But you also
can pass a null pointer as one of the arguments if you wish :
hW ndExcel% - Fin dWin dow%(ByVa l 0&, "Mi c ro s oft Exce l " )
Noti ce the ampersand character after the zero. This informs Visual Basic that you are
passing a Long integer (32-bit) zero. This ensures that a null pointer of the right size is
passed : Pointers in Visual Basic are always far (32-bit) pointers.
You can use thi s technique to pass a null pointer to any routine that accepts an argum ent by
reference.
Handles
The operati ng e nvironment DLL routines make extensive use of handles: handl es to
Window~ (hW nd), ha ndl es to Device Contex ts (hDC), and so on . (A handle is a uniqu e
integer value defined by the operating environment and used to refer to objects such as
form s or control s.) When a routine takes a handle as an argument, always declare it as a
ByVal Integer. DLL functions that retum a handle can be declared as Integer function s.
Handl es are ID numbers; they are not pointers and they are not numeric values . You should
ne ver pe1f orm mathe matical operations on them.
The hWnd property of forms and the hDC property offorms and picture box control s suppl y
valid handles that you can pass to DLL routines. Like any other property passed to a DLL
routine, they can only be passed by value.
Properties
Properti es must be passed by value . If the corresponding argum ent is declared with By Val.
the n yo u ca n pass the property direc tly. For exa mple, you can determin e th e dimen sions of
the screen or printer in pi xels with thi s routine:
Declare Func tion GetDe vi ceCaps% Lib " User " ( ByVal hD C%, ByVal nlndex%)
You can pass the hDC property of a form or the Printer object to thi s routine to obtain th e
resolutio n of the scree n or the currently selected printer. For example:
Sub Form_Click ()
Co nst H - 8 , V - 10
Print "Sc reen resol ut i on"
Pri nt GetDevi ceCaps%( hD C. H) ; "x" ; GetDe vi ceCaps%( hDC. V)
Print " Printer resolut i on "
Print GetDeviceCaps%(Pr in ter. hD C. H) ;" x" ;Get DeviceCaps%(P rint er. hDC . V)
End Sub
To pass a property by reference you must use an intermediate variable. All strings are passed
by reference; therefore, to pass a string property to a DLL routine, you must first assign the
property to a string variable and then pass the variable to the routine. Far example, suppose
you want to use the GetWindowsDirectory routine described earlier to set the Path property
of a file list box control. You cannot do this:
work ed% = GetWindowsDirectory(Filel.Path, Len(Filel.Pathl
Use thi s technique with numeric properties as well if you want to pass them to DLL routines
that accept an argument by reference.
Code written in other versions of Basic can be imponed into a Visual Basic application,
although sorne modification usually is required. This appendix explains how to import Basic
files and lists guideli nes for making the required modifications.
Visual Basic keywords are shown in mixed case (for example, Dim) . Keywords in other
versions of Basic are shown in uppercase (for example, DIM) . However, you don't need to
alter the case of keywords when adapting Basic code. Visual Basic accepts keywords in any
case and translates them to their mixed-case form au tomatically.
The mat erial that follows uses the term "BAS ICA' ' to refcr to both BASICA and GW -
BASIC. Microsoft QuickBasic and the Microsoft Basic Professional Development System
are both referred to as "procedural Basic."
Program Structure
Form code and modules in Visual Basic are rough ly equivalent to modules in procedural
Basic. Forrn code is different, however, in that proced ure s in a formare not visible to the
rest of the appli cation.
In Visual Basic, ali exec utable code mu st occur inside a Sub or Function procedure . (The
term "execu tab le code" refers to ali statements that perform sorne action at run time.) In a
typical application , most statements are executab le.
onexecutable statements include variable declarat ions, Deftype stateme nts, and co nstant
and Type defin iti ons. These state ments can be placed ins ide Sub and Function procedures,
in the Decl ara tion s sec tion of the form or module. and in the g loba l module .
If you have code th at you want to execu te continu all y (ge nerall y unnecessary with Visual
Bas ic's event-driven stru cture), you can pl ace it in a Main procedure and use an indefinite
loop. lf yo u use such a loop and want th e appli cati on to be able to res pond to events, the
loop should start with the statement Wh i le DoEvents (). For more information on the
DoEvents statement, see Chapter I 8, "Interacting wi th th e Environment," or:
InitArray:
Far I = 1 To 100
Arrayl(I) - I
Next I
Return
GoSub ro utines can be rew ritten as Sub proccdurc~. and GoTo statements are on ly
occasionall y needed if yo u use Visual Basic ·~ control structures.
Rewrite ali DEF FN functions as Function procedures. Refer to Chapter 9, "Language
Element ," for more inform at ion abo ut th e syntax ora Function procedure.
Scope of Variables
Scope determines how much of the application recognizes a variable. For your adapted code
to run without errors, you should attempt to preserve the scope of each variable. Where you
cannot preserve scope exactly, you may need to avoid conflicts by chan ging the names of
sorne variables.
Procedural Basic supports o ther variations on scope throu g h use of SHARED statern ents
wi thin procedures: Specifically , a vari able can be declared at th e module leve!, then shared
by one proced ure but not anoth er. Visual Basic does not support thi s approach to scopin g. If
you have varia bl es declared thi s way, make thern form- leve l or modu le-leve! by plac in g a
Dim stateme nt in the form or module Declarations sec tion.
In Visual Bas ic, this statement has the same effect as it does in Basic, but the statement
prints to the current farm (that is, the fa rm to which this statement is attached) rather than
the background screen.
Alternative methods fa r displaying outpu t include:
• Printing to a picture box instead of the current form by preceding the Print method with
a reference to a picture box:
Picturel.Print " X has a value of " ; X
• Displ ay ing a string by ass igning it to the Tex t property of a text box or the Caption
property of a !abe]:
Text2 . Text - " X has a value of "+ Str$(X)
• Display ing a message by using th e MsgBox statement. The message appears in a dial og
box that is closed when the user clicks th e OK button:
MsgBox " X has a value of " + Str$(X)
Visual Bas ic supports INPUT# and LINE INPUT# statements only far working with fil es.
However, generall y you can replace INPUT statements with calls to the InputBox$
function . INKEY is not supported in Visual Basic; instead of using INKEY, design your
application to respond to KeyPress events. You also can create a text box and read input by
using the Tex t property.
The file input and output statements (far example, INPUT#, PRINT #) workjust the same
as in procedural Basic.
Language Mechanics
Certain differences in dctails of the languages can cause syntax errors. Fortunate ly , resolving
these is usually strai ghtforward :
• Variable and symbolic co nsta nt names. You cannot use a period (.) in these names. The
period has a special meanin g in property , method , and user-defined type references.
• Array s. You cannot implicitly define an array in Visual Basic. Arrays mu st be explicitly
declared with Dim or Redim .
• Line continuation . Visual Basic does not have a line-continuation character, but it has a
scro ll ab le Code window th at supports lines up to 256 characters in length .
• Name confli cts. There is no conflict if two variables in different procedures, or at
differcnt levels of scope, sharc th e sa me name. However, two vari abl es at the sa me leve!
of scope cann ot have the same name , even if they have different types: A procedure
cann ot have both X% and X$as local variabl es.
• F unction call s. A call to a Function procedure must use parentheses, even if there are no
argume nts. For exampl e:
N = Get ARandom ( )
Unsupported Keywords
Vi sual Bas ic does not support th e keywords li sted below :
BLOAD BSAVE CALL ABSOLUTE CA LLS
CHAIN CLEAR COLOR COM
CSRLIN CVD CVDMBF CVI
cvs CVSM BF DATA DEFFN
DEFSEG DRAW ERDEV ERDEV$
FIELD FILES FRE INKEY$
INP IOCTL IOCTL$ KEY
LOCATE LPOS LPRINT MKD$
MKI$ MKL$ MKS$ MKSMBF$
ONCOM ON KEY ONPLAY ON STRIG
ONTIMER OUT PAINT PALETTE
PCOPY PEEK PEN PLAY
PMAP POK E POS PRESERVE
In m any cases, a keyword is not supported because Visual Basic uses a differe nt approach to
ach ieve the same result (either simplifying the process or adding fl ex ibility). For exampl e,
the LPRINT statement is not supported because Visual Basic has a spec ial Printer objec t
which handles ali output to the sys tem printer. Check the index of thi s manual or co nsult
He lp befare dec iding th at a ca pability is simpl y not supported.
In other cases, a keyword is not supported because it attempts to carry out low -leve l
operati ons th at confli ct with th e Windows or Presentation Manager environme nt.
Declare
The Declare statem e nt is va l id only for DLL routines and for dec laration of Function
procedurcs w ith no arg umen ts. ft is req uired in the case of DLL routines.
Deftype Statements
The Defrype state men ts (s uch as Deflnt, DefSng. and so on) are valid o nl y in the
Dec laration s sec ti on of a fo rm or module, and in the global module. Deftyp e state me nts
cann ot appear at the procedure leve!. A lso, they must occur before any Declare s tate ment.
To dec lare a dynamic array, use Dim with an empty li st of dimen sions and late r use ReDim
to a ll oca te space:
Dim DynArray()
You a lso ca n crca te an array j ust by usin g ReDim . No te that ReDim is an exec utab le
statem e nt and ca n o nl y appear in side a procedure .
Input$
The statement Input$ (x, channe[) causes the end-of-file (EOF) condition only when it
attempts to read from a file in which O bytes are left. In other versions of Basic, thi s
statement causes the EOF condition when fewer than x bytes are left.
On Error GoTo
In the statement On Error GoTo line, the target line must be in the same procedure as the
statement. This follows from the rule that references to labels must be local. In other
versions of Basic, the label can be at the module leve!. Visual Basic accepts ON LOCAL
ERROR GOTO statements, but changes them to On Error GoTo.
Option Base
The Option Base statement is valid only in the Declarations section of a form or module,
and in the global module. The statement must occur before any array references. (Option
Base enables you to specify the default lower bound for arrays.)
Return
The ordinary Return statement is valid. However, Return linelabel and Return linenumber
are not.
Width
Use Width # filenumber, O to indicate th at a file or device has unlimited width. In other
versions of Basic, the number 255 was used to indicate unlimited width rather than O. In the
statement Width # fi lenumber, N, if N is greater than O, then N indica tes where to wrap to th e
nex t line.
Vi sual Basic does not support the fo ll owing Basic syntaxes:
WIDTH screenwidth o/o, screenheight o/o
WIDTH device$, width o/o
Visual Basic comes wi th a collection of about 400 icons that you can use to enhance your
applications . This appendix shows printed examples of all the icons. Bear in mind that they
were designed to be used online, where they appear in full color (16 colors) .
For information on how to add icons to your Visual Basic applications, orto see exampl es o!'
the icons online:
The icons in the Icon Library are divided into the following categories.
Graphics Category Directory Description
Arrows and Pointers Arrows Arrows, pointers
Communication Comm Networking, phones,
printers, servers
Computers Computer Computers, disk drives,
diskettes, keyboards, mice
Flags Flags International flag s
Mail Mail Mailboxes, envelopes
Miscellaneous Mise Clocks, first aid signs, locks
and keys, phases of the
moon , and so on.
Office Office Cardfiles, charts, file
cabinets, folders, graphs,
paper clips
Traffic Signs Traffic Traffic signs
Writing Writing Books, notepads, pens,
pencils
r--··-...
~
ARW02RT ARW02UP ARW03DN ARW03LT ARW03RT ARW03UP
•·
ARW04DN
~
ARW04LT
¡ ¡.
ARW04RT
•· +
ARW04UP ARW05DN
+
ARW05LT
ARW05RT
t •
ARW05UP ARW06DN
.
<-
ARW06LT
~
ARW06RT
.)
V
ARW06UP
• • •- • •
ARW07D N ARW07LT ARW07RT ARW07UP ARW08DN ARW08LT
t
ARW08RT
,. ARW08UP ARW09DN ARW09LT ARW09RT
.
{J
ARWl0NE
(}
ARWl0NW
~
ARWl0SE
~'
ARWl0SW
.i~
-'-~'
,.. ~,.
__
ARWllNE
11~;·~
ARWllNW
iif
ARWllSE
-, ~T. .,
~~
l
POINT06
l
POINT07 POINT08 POINT09 POINT10 POI NT11
Communication
,,.;.,;._~ --
~;. ·•.... .-.-.'"ftJ)J
~D_.,./ ~J:f
NET01 NET03 NET04 NET05 NET06
~
cy;J
NET07 NETOS NET09A NET09B NET10A NET10B
NET11 NET12
• '-"'--
NET13 NET14 PHONE01 PHONE0 2
PHONE09
·~
< <~:
PHONE10
~
PHONE11 PHONE12
~
.
PHONE13
Computers
~ 4
ii iil ~
._llll
DISK01 DISK02 DISK03 DISK04 DISK05 DISK06
aDISK07 DISK08
a
DISK09
~
DISK10
•
DISKl 1
.
//<:z:.....
~(~
DISK12
E]
DISK13
~
DISK14
.
A
DISK15 •
DISKS0l
~
DISKS02
~
DISKS03
~
DISKS04 DRIVE0l DRIVE02
fn
KEY0l KEY02
l!J
KEY03
'
~\
1 - ::~.
,~ r . . i:-:=:. • ~
¿~:-~~;>-~$:;::;:). :=:
~ d> t~I
KEY04 KEY05 KEY06 KEY07 KEYBRD0l KEYBRD02
~
,./~
~
~
<~~--
·-..~.- -· l~I
KEYBRD03 KEYS0l KEYS02 KEYS03 MAC01 MAC02
S.
MOUSE04 PC01 PC02 PC03 PC04 TRASH01
Flags
FLGMEX FLGNETH
•
FLGNORW FLGNZ
•
FLGPORT FLGSPAIN
FLGSWED FLGSWITZ
•
FLGTURK FLGUSA01 FLGUSA02
111
FLGUSSR
di\
---~)
Miscellaneous
.,,,.,--... _
(;~.)
'-.......:,.,,'
@
FACE03 MISC01 MISC02
A
MISC03 MISC04
o
MISC05
~-..)
MISC12 MISC13
~---
1,
MISC14
-~~--
MISC15
1~1
MISC16A MISC16B
••
MISC17A MISC17B
+
MISC18 MISC19
XMISC20 MISC21
,11~m11
MISC22 MISC23 MISC24 MISC25 MISC26 MISC27
• ~~
MISC34 MISC35 MISC36 MISC37 MISC38
,
'MISC39A
MISC39B MISC40
il
MISC41 MISC42
~-)
~-
-- ~
MISC43 MISC44
MISC44 MOONOl
e -
MOON02 MOON 03 MOON04 MOON05
MOON06 -
MOON07 MOON08 SECUROlA SECUROl B SECUR02A
*'3
SECUR02B SECUR03 SECUR04 SECUR05 SECUR06 SECUR07
~
QJ
.·····~~ ·.
... .·
·.-:···
Off ice
¡·p
/ ·•.
11
FILES02B FILES03A FILES03B FILES04 FILES05A FILES05B
FOLDRS02
.... ., ......
GRAPH01
"
GRAPH02 •
GRAPH03 GRAPH04 GRAPH05
·j J.lfi·
:lllBl 1111 11111
GRAPH06 GRAPH07 GRAPH08 GRAPH09 GRAPH10 GRAPH11
GRAPH12
..
--~
• ...
GRAPH13 GRAPH14
Traffic Signs
(~
,JI
TRFFC01 TRFFC03
~
TRFFC04 TRFFC05
1
TRFFC07
1·,1
TRFFC08
+
TRFFC09
1=·
·· ·.,
'
TRFFClOA TRFFC1 0B TRFFClOC
50 1,,--:::! ___..)
TRFFC17
• •
TRFFC18A TRFFC18B
11
TRFFC19A TRFFC19B TRFFC20
Writing
-----·•..
~----i
'-l.i/ 4
·~••
í> k:;1..1,--
.,,/?''•..,
~t:
~ '-.
~-~
NOTE12 NOTE13 NOTE14 NOTE15 NOTE16 NOTE17
~,~--~
~ Y./
~ .··
NOTE18
F-
--
PENOl PEN02
/
PEN03
/
PEN04
/
PEN05
PEN06 PEN07
'
PENCILOl PENCIL02 PENCIL03 PENCIL04
PENCIL05 PENCIL06
' ' ' '
PENCIL07 PENCIL08 PENCIL09 PENCIL10
PENCILl 1 PENCIL12
' '
PENCIL13 PENCIL14 PENS01 PENS02
PENS03 PENS04
This appendix describes technical terms or terms that have a specific meaning with regard to
Visual Basic. Note that property names and event names are not included below, but are
listed in the Language Reference and online Help.
A
access key A key that enables the user to open a menu, or select a control by typing a
designated character while holding down the ALT key. In contrast, a shortcut key enables the
user to execute a menu command by press ing a function key or key combination (such as F:i
or CTRL+A).
active The condition of an error trap when control of an error-handling routine actually
branches into the trap.
ANSI character set American National Standards Institute (ANSI) 8-bit character set used
by Microsoft Windows that enables you to represent up to 256 characters (O -255) using
your keyboard. The ASCII character set is a subset of the ANSI set.
application A collection of code and visual elements that work together as a single
program. Developers can build and run applications within the Visual Basic environment,
while users usually run applications as exec utable files outside Visual Basic.
application name A unique name given to every application that can be a server in a DDE
conversation, usually the executable filename without any extension .
array A group of variables that share a co mmon name. Each element of the arra y has a
unique index number that identifies it.
ASCII character set American Standard Code for lnformation Exchange (ASCII) 7-bit
character set widely used to represent letters and symbols found on a standard US keyboard.
The ASCII character set is the same as the first 128 characters in the ANSI character set.
attach The action of writing code associated with a control or form. Event procedures are
said to be "attached" to a form or control.
B
binary access A type of file access (typically using the statements Open, Close, Seek,
Input$ ) th at makes no assu mptions about individual bytes in a fil e
bit The sma lles t unit of data a computer can store, equal to 1 or O.
bit-field argument An argument that returns information in individual bits. Each bit
indicates whether a certain condition is on or off.
bitmap An image made up of pixels on the screen, stored as a collection of bits, in whi c h
each bit corres po nds to one pixel. On color systems, more than one bit corresponds to eac h
pixel. Usua ll y has the fil e ex tension .BMP.
Boolean An expression that can be evaluated as true or fal se. The Integer data type can be
used to rep rese nt Boolean values, with - 1 representing True and O representin g False.
break mode The state of Visual Basic when a running program has temporarily halted . In
break mode, yo u can use debugging tools, continue execution, return to design time, or
restart exec ution of the app]ication from the beginning.
breakpoint A statement at whi ch Visual Basic automatically stops exec ution , putting the
application in break mode.
e
Caption The propert y you se t to specify the text di splayed on a co ntrol or form .
check box A co ntro l used to representan option (on/off, true/false) that the user can se t or
c lear by clickin g. An X in a check box indicates that it is selected .
Clipboard The temporary storage area used by the operating environment to store text,
graphic s. and othe r data. The data is transferred with Copy and Paste commands .
Clipboard object An objec t accessed with the keyword Clipboard and used to manipulate
text and grap hi cs in th e ope rating env ironment's Clipboard .
code A ge nera l term fo r state ments written in the Visual Basic la ng uage.
code template The first and last lines of a procedure (Sub and End Sub). Nothing is
exec uted unti I yo u add a stateme nt. .
Code window The Vi s ual Basic window for entering, editin g, and debugging code. One
Code w indow ca n be ope ned for eac h fo rm and modul e.
Color palette A window used to change the colors of a form or control orto set upa
custom color scheme.
combo box A control, similar to a list box anda text box combined, in which the user can
either enter values or select items from a list.
command button A control the user chooses to carry out a command or action. Command
buttons are sometimes called "push buttons."
comment Text embedded in code but ignored by Visual Basic, used to explain how the
code works. Each comment line starts with an apostrophe (') or the keyword Rem follow ed
by a space.
constant A value that does not change during program execution , inc luding literal and
number strings and symbolic constants, designated using the Const state ment.
control A graphical object placed on a form such as a text box and comrnand button . Each
control has its own list of recognized properties and events.
control array A group of controls that share a common name, type, and event procedures.
Each control in the array has a unique index number that you can use to determine which
control recognized the event.
control structure A Visual Basic statement that controls loops and decisions in code.
Examples are lf... Then ... Else, Case Select, Do loops, and For loops.
current statement The next statement to be executed during debugging . In Visual Basic ,
thi s state me nt is indicated by a rectangular outline.
custom control files Files that provide new types of controls to the Visual Basic
development environment and supply new capabilities to Visual Basic applications .
D
data type The attribute of a variable that determines what kind of data it can hold.
Supported data types include Integer, Long, Single, Double, Currency , a nd String . Special
data types include Form, Control, and user-defined types .
DDE Dynamic data exchange. Within Visual Basic, DDE events and properties make it
possible for your application to communicate with other Windows app li ca tion s.
Debug object An object accessed with the keyword Debug and used to se nd output to the
Immediate window. ·
debugging The process of finding errors in program logic . Debugging in vol ves running
specific portions of your applications and analyzing data at each point.
declaration Nonexecutable code that names a constant or variable and defines its attributes
(such as data type).
default A value that is assumed if no other value is specified. For example, if you don ' t
assign a value to the Enabled property, it is True by default.
design time Any time when you are building an applicati on in the Vi sual Bas ic des ign
environment. In contrast, during run time you run and interact with the application as a user
does.
directory list box A control that di splays a hierarchical list of directories . A directory list
box enables the user to select directories and paths at run time .
DLL Dynamic-link library. This is a set of routines that extends the normal capabilities of
Visual Basic. DLLs provide the means to cal] routines written in another language as well as
low-level operating-environment routines.
drag and drop Features that enable the user to drag a control and drop it on a form or other
co ntrol, using the mouse.
drive list box A control that displays a li st of ali val id drives in the use r' s sys te m. A drive
li st box finds and switches between valid di sk drives at run tim e.
E
enabled A term used in Visual Basic to describe settin g an error trap ("Enab led" is also a
property name) .
event An action recognized by an object (form or control) and for which you can write
code to respond to. Events may occur as a result of a user action (s uch as clicking a mou se
or pressing a key) orbe tri ggered by the system.
event procedure A procedure th at Visual Basic in vokes in res ponse to a spec ific eve nt,
whi ch may be caused by th e user or triggered by the sys te m.
executable code Code th at performs a task at run time, such as carrying out a command or
retuming a value. In contrast, nonexecutable code defines variables and constants.
executable file An appli cati on created in Visual Basic that can run outside the Visual
Basic environment.
executable statement A statement that Visual Basic translates into a specific action at run
time. Most Visual Bas ic statements are executable. The main exceptions are declarations,
constant definitions, comments, and user-defined type definition s.
expression Any combinati on of vari ables, constants, function s, and operators that Visual
Basic can evaluate to yield a single value.
F
file list box A control th at displays a list of filenames selected according to their attributes .
A file list box fi nds and specifies fil es to be opened, saved, or otherwi se manipulated at run
time.
focus The capacity to receive user input through the mouse or keyboard. For example,
when a user types a string, it appears in a text box only if the text box "has the focu s."
form code Ali the procedures and declarati ons attached to a form . (This includes
procedures th at res pond to an event for any of the controls on the fo rm). Form code is stored
in the same fil e as the fo rm itself.
form -level variable A variable recogni zed by all procedures attached to a form .
frame A control th at appears as a rec tangle. A fra me can be used to group option buttons or
other controls.
Function procedure A procedure th at retums a value and can be used within an expression .
Function procedures are dec lared wi th the Function key word .
G
general procedure A procedure that is not executed unless another procedure calls it. In
contras t, an event procedure is in voked automatically in response to a user or system acti on.
global The broadest possible scope, in whi ch a variable or constant definition is recognized
by the entire applicati on. Procedures in a modul e can also be said to have global scope.
global module A special modul e th at contains vari abl e, type, and constant information
recogni zed throu ghout the entire applicati on. Unlike other modules, the global module
cann ot contain procedures . Eac h projec t co ntains exactl y one global module.
grid The dots or points, measured in pixel s, on the Form window when you ' re in design
mode. Usi ng the grid ensures th at control s are positioned uniformly .
H
handle A unique integer va lue used to ide ntify and access a window or control.
hierarchical menu A menu that di splays a hierarchical list of items, including one or more
subm enu s.
horizontal scroll bar A control that appears as a scroll bar along a horizontal (left to ri ght)
ax is. lt is not attached to tex t o rto a window, but is useful asan alternative way of getting
input and d isplaying outpu t.
hot link A DDE link betwee n two applications in which changes m ade to data in the server
application are immediately reflected in the client applicati o n.
idle loop A loo p that exec utes state ments on ly when nothing else in the environment
requires im medi ate attention.
lmmediate window A wind ow used to exec ute in dividu al lines of code, ofte n for the
purpose of deb ugg in g. This w indow ca n be used only in break mode.
index An integer valu e th at g ives th e position of an element in an array ora co ntro l array.
items Refe re nces to data th at is meaningful to both appli cation s in a DDE conversati on.
invocation path The chain of proced ures that has been invoked to anive at the c urrent point
of exec uti on.
J
1ump In on line Help, an underlined word yo u cli ck to go to a topic related to th at word.
K
keyword A Vi sual Basic statement , method , fun cti o n, or operator. A lso used to refer to a
sea rch term in o nline He lp.
L
label A control that consists of text (called a "caption") that the user cannot directly
change. The term " label" also refers to the target of a GoTo or GoSub statement. Within
code, specific lines can be identified with either a line number ora line label. ·
local The smallest possible scope, in which a variable or definition is recognized onl y
within the proced ure in which it appears .
logic error A programming error that can cause code to produce the wrong results and/or
halt exec ution . May be caused by mix-ups in variable names or wrong variable types,
e ndl ess loops, flaw s in logical comparisons, or array problems.
logical centimeter, logical inch The length of an ítem which is one centimeter or one inch
lon g when printed. The actual size of a logical centimeter on screen may vary dependin g on
th e s ize and resoluti on of the user's monitor.
M
menu A list of commands, available at the top of a form or window , that is di splayed when
th e use r clicks th e menu name. You use the Menu Design window to create menus.
menu bar A bar that displ ays the names of menus available for use in the active window.
menu command A command name that appears on a menu when the menu is open .
menu control An individual menu item - either a menu name, command, or separator bar.
You use the Menu Design window to create menu controls; ali other types of controls are
created with the Toolbox .
menu name The name of a menu that appears on a menu bar. Clicking a menu name open s
a me nu and di splays its commands.
metafile A Windows fil e that stores a graphical image in term s of graphics objects (lines,
circ les, polygons) rather than pixels; it usuall y has the extension .WMF. A metafile
preserves an image when resized better than a bitmap
method A Vi sual Basic keyword similar to a function or statement, that always acts on an
object (a form , control, or one of th e special objects Printer or Clipboard).
modal A type of fo rm th at retains the focu s until closed. Most modal fo rm s are dialog
boxes o r warnin gs .
modeless A ty pe of form th at is not modal. A modeless form permits the use r to do sorne
work o n th e form , move the focus to another form , then move back to the ori ginal form .
module-leve! variable A vari able declared in the Dec larati ons sec ti on of a module and
shared by ali the procedures in that module.
N
nested A co ntrol structure is nes ted when it is inside another control stru cture.
o
object A general term fo r fo rm s, controls, and the special objects Clipboard , Debug.
Printer and Screen .
Object box T he drop-dow n list box at the top left of the Code window th at li sts for ms,
co ntrols . and "(ge neral)." "
option button A co ntro l simi lar to a chec k box , exce pt th at it alway s wo rks as part o f a
g ro up. Th e user can select onl y one opti on button fro m a gro up. Opti o n butto ns are
so met imes ca ll ed " radi o buttons."
p
persistent graphics O utpu t fro m graphics meth ods (Circle, Cls, Line , Point, Print, PSet)
th at is aut o mat ica ll y retai ned when the fo rm is red raw n. Graphics are " pers istent' ' if th ey are
d rawn whc n the A uto Redraw property is set to True (- 1).
picture box A cont ro l th at contai ns a graphical im age (bitm ap, icon, or metafil e) . Pi ctu re
boxes a lso can co ntain o utput of graphics statements, tex t written w ith a Print meth od , and
o pti on bu tto ns.
pixel A n abb rev iati o n for ·• picture element"; a dot th at re present s the s mall es t g raphi c uni t
o r meas ure me nt o n th e sc ree n.
pointer The too! at the top of the Toolbox th at rese mbl es a mouse pointer, used to selec t,
move, or resize a control.
poke A DDE term descri bing attempts by the client applicati on to send data to the server
appl ication.
print zone A print area 14 columns wide, where a column is the average size of a charac ter
in the font and font size you specify. With the Print method, a column causes output to start
at the next print zone.
Printer object A drawing obj ec t accessed with the keywo rd Printer. Used in code to
contro l text and graphics printed on a page and to di rec tl y send output to a printer.
procedure A seq ue nce of Visual Basic statcmen rs exec uted as a unit, so metimes refe rred to
as a "subroutine" or "fun ction" in other programmin g languages. The term "procedure"
refers to both Sub and Function procedures.
Procedure box The combo box at the top right-of the Code window that lists procedures.
procedure stepping A debugging technique that enab les you to trace code execution one
statement at a time; does not trace into procedure call s.
project The collection of source files (forms and modul es) that make up an applicati on.
Project window A Visual Basic window that di splays ali the forms and modul es in a
proj ect or applicati on.
property A named attribute of a form or co ntro l that yo u set to defi ne one of an objec t's
characteri stics (such as size, color, scree n location) ora n as pec t of its behavior (whether it is
enabled or not).
Properties bar The V isual Basic too! for viewing and setting properti es at design time. The
lis t of applicable properti es changes dependi ng on the type of co ntrol or form that's selec ted.
Properties list box T he box at the left of the Properties bar that di spl ays a li st of properties
fo r the selected objec t.
R
random access A type of fil e access (typ icall y usi ng the state ments Type ... End Type,
Open, Put #, Len, Get$) used for fil es whose data is organi zed into di sc rete record s of fi xed
length. Y ou can access the records in an y order.
reserved word A word that has special mea ning within Visual Bas ic, including predefin ed
state ments, functi ons, methods, operators, and Visual Bas ic prope rty and eve nt names.
run time Any time when th e appli catio n is runn ing. During run ti me, yo u can inte rac t with
an ap plicati on as a user wo ul d. In contrast, during design ti me you build the applicati on.
run-time error An error that Visual Bas ic can detect onl y when an application is runnin g.
s
scope The attribute of a vari able or procedure that determines how much of the application
will recognize it.
Screen object A n object accessed with the keyword Screen and used to activate a
specified form or control at run time.
separator bar A bar that divides commands into logical groups on a long menu.
sequential access A type of fil e access (typically using the statements Open, Line
Input#, Print #, Input$, Close) used fo r tex t files and variable- length record files. The
reco rds must be accessed in a parti cul ar o rd er. Numbers in a sequenti al-access fil e are
represented by character strings, just as words are.
server An application that provides data through dynamic data exchange (DDE), at the
requ est of a client application .
server link A DDE link in which the client application requests data from the server
application .
setting The value of a pro perty (for exa mple, the setti ng of the BackColor property could
be white) .
Settings box T he box at the middl e of the Propeni es bar that di splays and accepts c hoices
for propert y settin gs.
shortcut key A fu ncti o n key or key combi nati on - such as F5 or CTRL+A - th at executes
a co mm and . In co ntrast, an access key enables the use r to open a menu , or select a control by
typing a designated letter in the captio n whi le pressing the ALT key.
single stepping A debuggin g tec hnique that enables yo u to trace code executio n one
state me nt at a ti me .
sizing handle One of the small squares di splayed on the edge of a control when it is drawn
or selected. You use the sizing handles to resize the con trol.
source An object the user drags. Thi s control can be any type except a menu or tim er.
statement A sy ntac ti cally compl ete unit that ex presses one specific kind of action ,
declarat ion. or definiti o n. Normall y, one line in a procedure or Declarations section ,
alth o ugh yo u can use the colon (:) to put more th an one statement on a Iine.
static A loca l variable or arg um ent whose va lue is preserved in a procedure , e ither
dec lared wi th th e key words Static or Dim, or dec lared implic itl y.
submenu A menu that opens when a menu item inside a higher-level menu is selec ted.
Submenu items are indented to indicate their hierarchical position or leve!.
Sub procedure A procedure that does not retum a value, and is declared with the Sub
keyword. All event procedures are Sub procedures .
syntax The prescribed order and punctuation for putting programming language elements
into statements that are meaningful to Visual Basic.
syntax checking A Code window feature that ch~cks your code for correct syntax every
time you enter a line.
syntax error An error in following the grammatical structure of the language, sometimes
caused by a simple typing mistake .
T
tab order The order in which the focus is moved from one control to the next by pressi ng
the TAB key .
target An object (either a form or control) on which the user drop s the source (the control
being dragged) . This object recognizes the DragDrop event.
text box A control that provides an area for the user to enter text. The application can
manipulate the contents of a text box by using the Text property. Text boxes are so metimes
ca lled "edit fields. "
timer A control that responds to the passage of time: specificall y, a period speci fi ed by th e
timer's Interval property. A form can have multiple timers, each with its own interval. The
timer control is the only type of control that has no graphical properties .
title bar The bar that appears at the top of a form and displays its caption .
Toolbox The set of tools you use at design time to place controls on a form. Usually
ap pears as a window with icons at the left of the screen.
topic The subject of a dynamic data exchange (DDE) conversation between two
applications.
twip One-twentieth of a point. There are 1,440 twips to an inch and 567 twip s to a
centimeter. In Visual Basic , a twip is implemented as 1/1440 of a logical inch .
u
user A person who run s a Vi sual Basic applicati on after it is fini shed. This person may or
may not be the same as the applicati on designer.
V
variable A place to hold data that can change as the application runs. Each variable has a
unique name that identi fies it within its leve! of scope.
vertical scroll bar A control that appears as a simple scroll bar along a vertical (up and
dow n) ax is. It is not attached to text or to a window, but is useful asan altemati ve way of
ge tting input and dis play ing output.
In addition to pointers to information in the Programmer 's Guide, thi s index includes pointers to related
information in online Help on menu commands, objects, the interface, and step-by-step instructions for usin g
Visual Basic . Each pointer to Help lists the keyword you should use when searching through Help.
For furth er informati on on a Vi sual Basic language keyword, property, event, or method li sted in the index
(and for informati on on those not covered in the Programmer's Guide), search Help by name, or refer to thc
Language Reference .
C,intrr,I typc See Co ntrol dat a type C tl ame propert y (co nrinued)
1·, ,ntrr,I B ox propert y 2 18. 2 19 defined 38
1 ,n, cr,a tion ( DD E) See DD E conversation labels 63
1_ .in,cr -, io n lün ction s te xt bo xes 63
LCasdi 105 tim er con tro ls 269
StrS 75 C'TRL key
LCase$ 105, 127. 133 se lectin g multip le control s w ith 54
Val 7-l testin g for. keyboard hand lers 275 , 277 - 278
, ,n, eni ng tes ti ng for . mou se eve nt s 206
Cehi u'>/Fahrenheit 147 - I-l8 CTRL+BREAK. brea kin g execution 230
degree'>lrac.Ji ans 192 C'TRL+PAGE 1)0\VN. I mmed i ate window 238
lo\\ ercase/uppercase 105 . 127, 133 C urrency data type
,tanc..lard approac h for 148 defi ned 80. 83 - 84
lé.\t/ numbe rs 74 - 75 11 0 1 support ed by DLLs 382
ti me fo rm al ~ 270. 271. 272 random -acccss fi les 333
,\) rJ1 nate ': , tcI11 Current di recto r)
creating custom sca le 171 - 174 providing user se lec ti on 297
c.Jefined 17 1 See a/so Fi lel nfo dialog box: L aun ch Pad
ncgati ,·e num be rs and frac ti ons 172 appl ica ti on
re \e ttin g to defaul t 175 C urrent drive
Scale mcthod 174 providing user se lec tion 296. 297
,e lec ti ng sta nd ard sea le 174- 175 See o/so Fil el nfo dialog box: L aunc h Pad
,e tting 17 1- 175 app l ica ti on
, Hl rJinates. drawing 152. 153 Cu 1Tcnt statement 232, 413
'P: L"Olll 11Janc..l Cu rrentX propert y
crea ti ng fo r app l ications 265 - 266 fo rm or picture box 152
pro, 1J in g DDE capabi l iti es for appl ica ti ons Pri lller objec t 158
1(17 .1 68 ,pccifying pri ntin g locati on 152. 158
'11: u1m111and (Edi l rn enu ) TextHeight. Tex tWidth meth ods 153
cIe,I II11 g 1)1)[ linb with J56. 357 Currcnt''{ prnpert)
'il'lln i, 1/elfi.fárcopy comrna nd form or pi cture box 152
'I" Pen I l)ra" Mode sc ttin gJ 186 Pri nte r object 15 8
'P: hle h1nd ion proccdure \ pecifying printin g loca ti on 152. 158
h1 nar1 1cr\Íon 3S 1 - 352 Cu~tom co nt rol file~
c·llde. 1llr ra nd om -access fi les 334 - 335 c.Jcfined 377.413
u, ed In Reco rd Editor app li cat i on 337 loading 378
1 p1I11g Cut anc.J paste co mm ands
c· ,Kk e.\a rnpl c\ from Hclp 29 - 3 1 crcating 265 - 267
c11 11tru l, 52 sc lcct ing te xt fo r 26..i
t"1lc,. hinary 15 1 352 C ut co mm and (Ed il menu ) Seorch /-/elp /á r C ut
l I lc,. rand orn -acccss 334 - 335 command
graphi cs fro rn obJCCl to objec t 163 CV D keyword 396
graphic~ to/frorn Cl ip boa rd 162. 267 CVDMBF keyword 396
lL' \l to/from Clipboa rd 265 - 267 CV I ke ywo rd 396
'il't1r,-/1 / l e/¡1.for copy codc: co py co ntro ls CVS kcyword 396
" illllL"lion 19 1 CVSMBF ke) word 396
1 •uI11 cr. dcfincd 92
l)rawi ng lcontinued) Editin g Sea rch H elp.foredit code ; ed il cap ti on: edit
ellip~es 190 - 19 1 men u bar; undo
ForeColorpropert y 177. 18 1. 184 E llipses, drawing 190 - 191
fundamenta l co ncepts 175 - 18 1 Else clause
lin e~ 182 - 188 use of 88, 250
point s 181. 187 See also lf.. .Then ... Else statement
po lygo ns 183 Elself clau se
rectang les 384 - 385 use of 88, 249 - 250
spoked pattern 183 See also Jf...Then ... E lse statement
Search Help .fordraw E lself...T ypeOf statement 249 - 250
DrawM ode propert y Enab led property
defi ned 177 Boolean sett i ngs 107
se ttin gs 186 - 187 chec king statu s of control 108
DrawStyle property defined 4 14
defin ed 177 defaul t se ttin g 58
~elli ng~ 185 enabl in g/disabling co ntrol s 107
Dra wWidt h propert y menus 11 3
defin ed 177 tex tboxes 147
specifying width of line 18-+ Timer control s 269
Dri ve Iist box con trol End command (Run menu) 42, 73. 229
Change eve nt 299 End I f statement, 87. 244
defi ned 4 14 END key, use in Immedi ate wi ndow 23 8
Dri\ e property 296. 297 End -of- line See Newline character
Fi leln fo dialog box 305 - 31 -+ End statemen t 226
Launch Pad app li ca tion ?.98 - 304 End Sub 67
mouse eve nt s rccog nized 196 En dDoc method 159
properties. event~. and methods ( li~t ) Search He/p ENTER key
/111· dri\e li~t bo\ ASC II number 127
Toolbox locat ion 48 keyboard handlers and 275
Vi,irilc propcrt> .1 l-+ use in lmmediate window 238
workin g with 2%. 297 EOF function
Drwe property. dri\·e li st box ?.96, 297 file access 316. 326
Drop-do wn li st box Input$ statement and 398
crea cin g 135 Eq ual sign (=)
C\ ents 139 ass ignment statements 8 1
DropDo\,·n eve nt. cornho box 139 Co nst statement 258
Dro ppin g opera tor 88, 98
defined ?.07 Eqv operator 88, 98
See o/so Drag -and -clrop operations ERDEV keyword 396
D~ namic ;irrays 255 - 25 6. 397 ERDE Y $ ke yword 396
D\ namic Data Exchange (DD E) See DDE (dynamic Err function
data exc hange ) defi ned 28 1, 283
Dy namic -link l ibra ry (DL L ) See DLL (uynam ic-link de layed error-handling examp le 29?. ?.93
li braryl routinc s use wi th Error 287
Error codcs
DDE error numbers 373
retri ev i ng wit h Err 28 1, 283 , 292 - 293
1·.d it co nt ro l See Tc.xl box contro l Seo rch He/p .for trappabl e errors
Ld it field See Tcxt hox control Error Err stateme nt
Ld it menu co mm and s defin ed 283
See specific cn111111mul nmn e 1 w hen to use 288
Seorch He/p jin· Edil mcnu co rnmancls
\J
'\ía min g o
DDE appli cati on names 355 Object See Objects
DDE ite m names 355, 358, 365 Obj ect box 68, 69, 4 18
DD E lin ks 365 Obj ectname, defin ed 4 1
DDE state ments 372 Obj ects
DD E topic names 355, 358, 359, 360 - 36 1 defin ed 4, 6,4 18
event procedures 7, 41 , 67 - 68 naming 41 , 63, 67, 68
me nus 110 Search Help Jo r obj ects
obj ects 41, 63,67, 68 Oct$ fu nction 11 4, 13 1
va ri abl es 82 Octal numbers (base 8)
\:ega ti on (-) operator 98 defi ned 80
\:es ted 244, 41 8 Nu mber System application 113 - 11 5, 130 - 131
>i ew Form command (File menu) 37, 2 17 Office icons (Icon Lib rary) 406 - 407
'-Jcw Modul e command (File menu ) Sea rch Help for ON C OM keyword 396
Ne w Module command On Erro r GoT o statement
.' kw Procedure command (Code menu ) 94 adapting from other Basic code 398
'-lcw Projec t command (File menu ) Search Help for enabling erro r trap 282
:--Jew Proj ect command O n En-or Resume Next state ment 293 - 294
' • 1; "l' ,:- h:1r;1c 1cr O:\ KrY 1'c'_'\\1,1d .~%
co nvening fi les wi th nonstandard cha.rac te rs ON L OCAL ERROR GOTO 398
330 - 33 1 ON PLA Y keyword 396
load ing text in text boxes conta ining 124 O STRI NG keyword 396
no ne in rando m-access files 33 1 O TIMER keyword 396
u e in Tex t Edi tor application 326, 328 O pen Project co mmand (Fi le menu)
'-lew Page meth od 159 use of 43
., cx t Procedure command (Code menu ) Search Help Search Help fo r Open P roj ect com mand
fo r Nex t Procedure command O pen stateme nt
Nex 1 statemenl 244 binary-access fil es 350
:-S:o p (Draw Mode setting) 186 F il eOpener F un cti on procedu re 3 18 - 320
'formal pro perty, fil e list box 3 14 modes 3 17, 3 18
'-101 Copy Pen (Dra wMode sett ing) 186 random-access fi les 334
'-lot equal (<>J operator 87, 98 sequential fi les 320
\:01 o pera tor 88, 98 syntax 3 18
.'\íow fun ction 157 Ope ning fi les
. u 11 charac te r 382 bi nary-access files 350
'-Ju ll pointers 385-386 Fil eln fo di a log box, example 305 - 3 14
'\i umber See Numbers F i leO pener Functi on procedure 3 18 - 320
\; umbcr sig n (#) Open state ment, overview 3 17, 3 18
Doub le type-clec laratio n character 83 ra ndo m-access fi les 334
fonna ttin g num bers 75 , 156 Record Ed itor applicati on 34 1- 342
Reco rd Editor applicati on ( can tinu ed) Rock ' n' Ro l! application
Form_ Load event procedure 339 -340 displaying Gro upCho ice for m 223 - 224
global modul e 338 exiting 226
HScroller_Change event procedure 349 - 35 0 hiding forms 224 - 225
inte rface 336 properties, genera l-purpose fo m1 s 2 17 -2 19
NextRecord_Click event procedure 344 specifying icon 22 1
OpenFi le_Click even t procedure 34 l -342 startup form 220-22 1
PreviousRecord_Click eve nt procedure 344 Rounding
retrieving records by nu mber 348 - 350 Currency data type 80, 84
ShowRecord Sub proced ure 340 - 34 1 floating-point numbers 84
Rec tangle, drawing 384 - 385 integer di vision 99
Re Dim statement RTrim$ function 251
compared with Dim 256 /RUN 17
creating dynami c arrays 256, 397 RU N keyword 397
Refres h method 275 Run me nu commands
Relationa l operators See specific cammand names
li st of 87, 98 Search Help far Run menu commands
use of 87- 88 Run mode, defined 229
Remove File command (File me nu ) Run time, defined 37,229,4 19
use of 44 Run-time appli cation
Sea rch HelpfarRemove Fi le command creating 76
Re rnoveltem method, list boxes and combo boxes 136 requirements for 76
Re naming files Search Help far executab le file
tips 44 Run-time error
Save Fi le As cornmand 44, 45 defined 22 8, 420
Sea rch Help far Save Fil e As command codes
Re naming proj ec t DDE erro r numbers 373
Save Projec t As co rnm and 45 list of error codes Search Help fa r trappab le
Sea rch Helpfar Save Projec t As cornma nd errors
"·¡, l:1cc u11111":111d 1 C ,de •pc1111' , ,.11ff l1 //,./1, li>r ··•·t ,·;" :,.
pattern rnatchin g: Replace command 292 - 293
REQUEST (Exce l stateme nt ) 372 messages
Reserved word retrieving with Error$ 28 1
defined 82. 4 19 li st of error messages Search Help far
Vi sual Basic language keywo rds Search Help far trappable errors
language See alsa debuggin g
Res izing fo rms Sea rch Help far run-ti me error
BorderStyle property 2 18,2 19 Run-time fi le (VBRUN 100.DLL) 76
Height and Wid th properties 64, 168 Runnin g program See Exec uting code
Tex t Ed itor app li cati o n 329
Restan co mmand (Code menu) Search He/p far
Res tart command s
RESTORE keyword 397 SADD keyword 397
Re sume line 283, 285, 286 Sample appli cations See Applications, sampl e
Resume Next statement "Sample Application s," tutoría! 20
ex iting error-hand ling routine 283 -286 Save File As command (Fil e menu)
use with un ant icipated e rrors 286 use of 44. 45
Res ume state ment 282 , 283 -286 Search Help far Save Fil e As command
Rcturn state ment 398 Save Fi le comrnand (Fi le menu )
RGB fun cti on use of 45 , 73
DoColor exampl e 143 Sea rch Help far Save File command
sctting colors 179
Set ext Stateme nt comm and (Run menu) Shortcut keys ( con tinu ed)
use of 235 SHIFT+F8 (Procedure Step command. Run menu)
Search Help for Set Nex t Statement command 234
Se t Startup Form command (Run menu ) Visual Basic shortcut keys Search Help for
use of 220 shortcuts
Sea,:ch Help for Set Startup Form command Show method
SetData method 267 loading and displaying fo rms 222 - 224
SetFocus method 340 syntax 2 16
SETMEM keyword 397 Sin 191
Se tText method S ingle data type
copy ing text to Clipboard 265 - 266 defined 83
syntax 265 highest value 84
Se tting Single Step command (R un me nu )
default settings 38, 58, 414 use of 233
defined 8,38, 420 Search Help for Single Step co mmand
Settings box 39, 59, 420 Single stepping
Sctup program defined 233,420
bac king up disks 15 using 233 - 234
getting Help 16 Single-precision numbers, in random-access files 333
need for 13 Sizing handle 53, 420
quitting 16 Sizing objects
re installing Visual Basic 16 BorderStyle property 218, 2 19
running Setup 15 - 16 Hei ght, Width, and Autosize properti es 168
SETUP.EXE using Properties bar 64
desc ri bed 13 usi ng sizing handles 53
See a/so Setup program Search Help for size
Shc ll app li cation, Proj ect Pl anner 106 - 107 S lash
She ll function (/) di vision symbo l 75 , 99
co mmand buttons and 105 - 107 (\) integer di vision 99
•n° n 11 en, 1n:inr1, ·"~d 1 ! '-' Sl.EEP kC)\lüld 39 ~
~ta rting appli cati ons using DDE 369 SmallChange property, scroll bar 14 1
syntax 105 Salid line, DrawStyle setting 185
See a /so Launch Pad app licati on Sort See Sorted property
Sl11ji arg ument Sorted property, list boxes and combo boxes l 35
key board handl ers and 276, 277 - 278 SOUND keyword 397
mouse events and 196, 202 - 206 Source (drag-and-drop operati ons) 209 , 420
placement of constants 278 Source argument, DragDrop eve nt 209
S HIFT key, testing for Space character 333
key events 277 - 278 Spaces
mouse events 206 LTrim$ 115 , 13 1
\ IIIFT+ F8 (Procedure Step command) 234 padding ·trailing spaces, random-access files 333
Shonc ut keys RTrim$ 25 1
creating for users 120 - 12 1 Spec ial charac ters, sending w ith SendKeys 376
CTRL+ BR EAK 230 Square root, ca lculating 11 2
de fined 420 Start command (Run menu)
FI key (Help) 24, 25 use of 73 , 229
F5 key (S tart comm and, Run menu) 42 Search Help for Start comm and
FX key (S ingle Step command , Run menu ) 233 Start ing Visual Basic 17, 36
F9 key (Togg le Breakpoint command, Run menu) Startup form or modu le
23 1 creat ing 220 - 22 1, 392
lmmediate window key s 238 - 23 9 us ing when writin g idl e loops 273
Sea rch Help for startup form
X y
X arg um elll Y argume nt
DragDrop event 209 DragD rop event 209
mouse events and 196 , 197 mouse events and 196, 197
Xor operato r 88. 98 Yield control
Xo r Pe n (Draw Mode setting) 186 in DDE con versatio n 374 - 375
writing idle loops 273-275
z
Zero, fo rm atting numbers 75 , 156