programming visual basic 6

Download Programming Visual Basic 6

If you can't read please download the document

Upload: lydieu

Post on 08-Dec-2016

433 views

Category:

Documents


92 download

TRANSCRIPT

EBook/605580.ICO

EBook/autorun.exe

EBook/AUTORUN.INF[autorun]open=AutoRun.exeicon=AutoRun.exe,0

EBook/bonline.ini[Admin]InstallType=Local

[Default]FullTitle=Programming Microsoft Visual Basic 6TitleForOS=Programming Microsoft Visual Basic 6LaunchFile=promsvb6.CHMRPC=38477SiteCode=cmpBookIcon=605580.ICO

EBook/DATA.TAG[TagInfo]Company=MicrosoftApplication=Microsoft Press Electronic BooksVersion=1.00.000Category=Development ToolMisc=

EBook/data1.cab

EBook/hhupd.exe

EBook/lang.dat

EBook/layout.bin

EBook/license.txtMICROSOFT LICENSE AGREEMENT

Microsoft Press Electronic Book

IMPORTANT-READ CAREFULLY: This Microsoft End-User License Agreement ("EULA") is a legal agreement between you (either an individual or an entity) and Microsoft Corporation for the Microsoft product identified above, which includes computer software and may include associated media, and "online" or electronic documentation ("SOFTWARE PRODUCT"). By installing, copying or otherwise using the SOFTWARE PRODUCT, you agree to be bound by the terms of this EULA. If you do not agree to the terms of this EULA, you are not authorized to install, copy or otherwise use the SOFTWARE PRODUCT; you may, however, return the SOFTWARE PRODUCT, along with all printed materials and other items that form a part of the Microsoft product that includes the SOFTWARE PRODUCT to the place you obtained them for a full refund.

MICROSOFT SOFTWARE LICENSE

The SOFTWARE PRODUCT is protected by United States copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. The SOFTWARE PRODUCT is licensed, not sold.1. GRANT OF LICENSE. This EULA grants you the following rights:

- Software Product. You may install and use one copy of the SOFTWARE PRODUCT, or any prior version for the same operating system, on a single computer. The primary user of the computer on which the SOFTWARE PRODUCT is installed may make a second copy for his or her exclusive use on a portable computer.

- Storage/Network Use. You may also store or install a copy of the SOFTWARE PRODUCT on a storage device, such as a network server, used only to install or run the SOFTWARE PRODUCT on your other computers over an internal network; however, you must acquire and dedicate a license for each separate computer on which the SOFTWARE PRODUCT is installed or run from the storage device. A license for the SOFTWARE PRODUCT may not be shared or used concurrently on different computers.

- License Pak. If you have acquired this EULA in a Microsoft License Pak, you may make the number of additional copies of the computer software portion of the SOFTWARE PRODUCT authorized on the printed copy of this EULA, and you may use each copy in the manner specified above. You are also entitled to make a corresponding number of secondary copies for portable computer use as specified above.

2. DESCRIPTION OF OTHER RIGHTS AND LIMITATIONS.

- Not For Resale Software. If the SOFTWARE PRODUCT is labeled "Not For Resale" or "NFR," then, notwithstanding other sections of this EULA, you may not resell, or otherwise transfer for value, the SOFTWARE PRODUCT.

- Limitations on Reverse Engineering, Decompilation, and Disassembly. You may not reverse engineer, decompile, or disassemble the SOFTWARE PRODUCT, except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation.

- Separation of Components. The SOFTWARE PRODUCT is licensed as a single product. Its component parts may not be separated for use on more than one computer.

- Rental. You may not rent, lease or lend the SOFTWARE PRODUCT.

- Support Services. Microsoft may provide you with support services related to the SOFTWARE PRODUCT ("Support Services"). Use of Support Services is governed by the Microsoft polices and programs described in the user manual, in "on line" documentation and/or other Microsoft-provided materials. Any supplemental software code provided to you as part of the Support Services shall be considered part of the SOFTWARE PRODUCT and subject to the terms and conditions of this EULA. With respect to technical information you provide to Microsoft as part of the Support Services, Microsoft may use such information for its business purposes, including for product support and development. Microsoft will not utilize such technical information in a form that personally identifies you.

- Software Transfer. You may permanently transfer all of your rights under this EULA, provided you retain no copies, you transfer all of the SOFTWARE PRODUCT (including all component parts, the media and printed materials, any upgrades, this EULA, and, if applicable, the Certificate of Authenticity), and the recipient agrees to the terms of this EULA.

- Termination. Without prejudice to any other rights, Microsoft may terminate this EULA if you fail to comply with the terms and conditions of this EULA. In such event, you must destroy all copies of the SOFTWARE PRODUCT and all of its component parts.

3. COPYRIGHT. All title and copyrights in and to the SOFTWARE PRODUCT (including but not limited to any images, photographs, animations, video, audio, music, text, and "applets" incorporated into the SOFTWARE PRODUCT), and any copies of the SOFTWARE PRODUCT are owned by Microsoft or its suppliers. The SOFTWARE PRODUCT is protected by copyright laws and international treaty provisions. Therefore, you must treat the SOFTWARE PRODUCT like any other copyrighted material except that you may install the SOFTWARE PRODUCT on a single computer provided you keep the original solely for backup or archival purposes. You may not copy the printed materials accompanying the SOFTWARE PRODUCT.

4. U.S. GOVERNMENT RESTRICTED RIGHTS. The SOFTWARE PRODUCT and documentation are provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and (2) of the Commercial Computer Software-Restricted Rights at 48 CFR 52.227-19, as applicable. Manufacturer is Microsoft Corporation/One Microsoft Way/Redmond, WA 98052-6399.

DISCLAIMER OF WARRANTY

NO WARRANTIES OR CONDITIONS. Microsoft expressly disclaims any warranty or condition for the SOFTWARE PRODUCT. THE SOFTWARE PRODUCT AND ANY RELATED DOCUMENTATION IS PROVIDED "AS IS" WITHOUT WARRANTY OR CONDITION OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OR MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NONINFRINGEMENT. THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE PRODUCT REMAINS WITH YOU.

LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL MICROSOFT OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE PRODUCT OR THE PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY CASE, MICROSOFT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS EULA SHALL BE LIMITED TO THE GREATER OF THE AMOUNT ACTUALLY PAID BY YOU FOR THE SOFTWARE PRODUCT OR US$5.00; PROVIDED HOWEVER, IF YOU HAVE ENTERED INTO A MICROSOFT SUPPORT SERVICES AGREEMENT, MICROSOFT'S ENTIRE LIABILITY REGARDING SUPPORT SERVICES SHALL BE GOVERNED BY THE TERMS OF THAT AGREEMENT. BECAUSE SOME STATES AND JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.

MISCELLANEOUS

If you acquired this product in the United States, this EULA is governed by the laws of the State of Washington.

If you acquired this product in Canada, this EULA is governed by the laws of the Province of Ontario, Canada. Each of the parties hereto irrevocably attorns to the jurisdiction of the courts of the Province of Ontario and further agrees to commence any litigation which may arise hereunder in the courts located in the Judicial District of York, Province of Ontario.

If this product was acquired outside the United States or Canada, then local law may apply.

Should you have any questions concerning this EULA, or if you desire to contact Microsoft for any reason, please contact the Microsoft subsidiary serving your country, or write: Microsoft Sales Information Center/One Microsoft Way/Redmond, WA 98052-6399.

EBook/os.dat[Info]Name=PLATFORMVersion=1.00.000

[0x0009]OS Independent=0x0000000000000000Windows 3.1 & 3.11=0x0000000000000001Windows 95=0x0000000000000010Windows NT 3.51 (Intel)=0x0000000000001000Windows NT 3.51 (Alpha)=0x0000000000002000Windows NT 3.51 (MIPS)=0x0000000000004000Windows NT 4.0 (Intel)=0x0000000000010000Windows NT 4.0 (Alpha)=0x0000000000020000Windows NT 4.0 (MIPS)=0x0000000000040000

EBook/Promsvb6.chm

[Previous] [Next]

About This Electronic Book

This electronic book was originally createdand still may be purchasedas a print book. For simplicity, the electronic version of this book has been modified as little as possible from its original form. For instance, there may be occasional references to sample files that come with the book. These files are available with the print version, but are not provided in this electronic edition.

Expanding Graphics

Many of the graphics shown in this book are quite large. To improve the readability of the book, reduced versions of these graphics are shown in the text. To see a full-size version, click on the reduced graphic.

[Previous] [Next]

Acknowledgments

Several people have helped me make this book, and it's such a joy to have an opportunity to publicly thank them all.

I'd like to especially mention four of my best friends, who dedicated some of their evenings and nights to reviewing the manuscript while I was writing it. Marco Losavio is a great Visual Basic programmer and was precious help in refining all the chapters about VBA, classes, and controls. Luigi Intonti has that special intuition that makes a developer a great developer and used it to help me enrich the book with some tricky techniques and tips. Giuseppe Dimauro, simply the finest C++ programmer I have ever met on this side of the Atlantic Ocean, revealed to me many intriguing details about Windows architecture. Finally, the sections about database and Internet programming wouldn't have been complete and accurate without the support of Francesco Albano, who has amazed me by always having the correct answers to all my questions about Jet, SQL Server, and Windows DNA architecture. Marco, Luigi, Giuseppe, and Francesco are well-known Italian technical writers, and I hope you'll read some of their works in English on my www.vb2themax.com Web site.

The book also contains many traces of my conversations with two other renowned Italian authors. Giovanni Librando has shared with me his knowledge of ADO and COM, while Dino Esposito has given me much good advice and made many suggestions. Also, I'm very grateful to Matt Curland, who on several occasions helped me understand what happens behind the Visual Basic scenes.

When writing a technical book, acquiring knowledge is only half the story. The other half consists in putting this knowledge in a form that other people can easily understand, especially when you're writing in a language that isn't your own mother tongue. In recent years, many people have devoted time teaching me how to write better English. They include the editors at the Visual Basic Programmer's Journal magazine, especially Lee Th and Patrick Meader. I also want to thank editor-in-chief Jeff Hadfield for permission to mention a couple of interesting tips that originally appeared in the magazine's Tech Tips supplement, and of course, publisher Jim Fawcette for the opportunity to write for VBPJ in the first place.

I was so excited to write this book with Microsoft Press, and I was even happier when I finally met the people I had worked with for these nine months. Kathleen Atkins, Marzena Makuta, and Sally Stickney are among the best editors an author can hope to work with. In spite of all the text they had to revert from italics to roman, and vice versa, they often found the time to explain to me all the subtle dos and don'ts of the editing black art. And big thanks to Eric Stroo, the one who started it all and gave me the chance to write the book that I always wanted to write.

Finally, I am grateful to Dave Sanborn, Keith Jarrett, Pat Metheny, and Jan Garbarek, a few of the many great musicians who provided the soundtrack for this book. Their music kept me company for many nights and helped even more than the one thousand cups of espresso coffee I drank during these months.

I still haven't mentioned the two people who have helped me more than anyone else. It's not a coincidence that they are also the ones I love most.

Thank you, Andrea, for always strolling in my room and insisting on playing on my knees with those weird widgets called mouse and keyboard. In the end, I had to give up my Windows NT Server system for your experiments with Paint and WordArt, but in return you continuously reminded me of how exciting being the dad of a lively two-year-old baby is.

Thank you, Adriana, for convincing me to write this book and for helping me be in the right humor and find the concentration to be at my best to write it. Living together is more and more like a fascinating, never-ending journey. What else can I say? You're simply the best wife I could dream of.

This book is dedicated to you both.

[Previous] [Next]

Francesco Balena

Francesco began to study programming when it was customary to write code on punched cards. Since then, he has closely followed the evolution of hardware and software, at least when he wasn't busy playing alto sax with his jazz combo.

In recent years, he has written four books and over 150 articles for programming magazines. He is a contributing editor of Visual Basic Programming Journal, coauthor of Platinum Edition Using VB5 (QUE), and founder and editor-in-chief of Visual Basic Journal, VBPJ's Italian licensee. He works as a trainer and consultant, speaks at several conferences for developersincluding Microsoft DevDays, American and European editions of VBITS, and Italian VB Forum workshopsand also teaches on-line seminars via the Internet. (For more information, go to his http://www.vb2themax.com Web site.)

When not traveling, Francesco lives in Bari, Italy, with his wife, Adriana, and his son, Andrea.

[Next]

Copyright 1999by Francesco Balena

[Previous] [Next]

PUBLISHED BY

Microsoft Press

A Division of Microsoft Corporation

One Microsoft Way

Redmond, Washington 98052-6399

Copyright 1999 by Francesco Balena

All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission of the publisher.

Library of Congress Cataloging-in-Publication Data

Balena, Francesco, 1960--

Programming Microsoft Visual Basic 6.0 / Francesco Balena.

p. cm.

Includes index.

ISBN 0-7356-0558-0

1. Microsoft Visual Basic. 2. Basic (Computer program language)

I. Title.

QA76.73.B3B345 1999

005.26'8--dc21 99-20381

CIP

Printed and bound in the United States of America.

1 2 3 4 5 6 7 8 9QMQM4 3 2 1 0 9

Distributed in Canada by Penguin Books Canada Limited.

A CIP catalogue record for this book is available from the British Library.

Microsoft Press books are available through booksellers and distributors worldwide. For further information about international editions, contact your local Microsoft Corporation office or contact Microsoft Press International directly at fax (425) 936-7329. Visit our Web site at mspress.microsoft.com.

Active Desktop, ActiveX, the BackOffice logo, FrontPage, IntelliSense, Microsoft, Microsoft Press, MS-DOS, Visual Basic, and Windows are either registered trademarks or trademarks ofMicrosoft Corporation in the United States and/or other countries. Other product and company names mentioned herein may be the trademarks of their respective owners.

The example companies, organizations, products, people, and events depicted herein are fictitious. No association with any real company, organization, product, person, or event is intended or should be inferred.

Acquisitions Editor:Eric Stroo

Project Editor: Kathleen Atkins

Manuscript Editors: Kathleen Atkins, Sally Stickney

Technical Editor: Marzena Makuta

[Previous] [Next]

Chapter 1

First Steps with Microsoft Visual Basic 6

This chapter introduces you to the Visual Basic environment and guides you through the creation of your first Visual Basic program. It also presents a number of important concepts that are crucial to Visual Basic programming, such as the event-driven programming model. If you aren't new to Visual Basic, you can probably skip over this chapter without any problem. Interspersed in the main text, however, you might find a few interesting tips for making the best use of the environment as well as a couple of introductions to features of Visual Basic that are new in version 6, so I suggest that you give this chapter a quick look, regardless of your Visual Basic experience.

[Previous] [Next]

The Integrated Development Environment

Much of the popularity of Visual Basic comes from its Integrated Development Environment, or IDE for short. In theory, you can edit your Visual Basic programs using any editor, including the aged Notepad, but I never met a programmer insane enough to do that. In fact, the IDE gives you everything you need to create great applications, to write code for them, to test and fine-tune them, and, finally, to produce executable files. These files are independent of the environment and therefore can be delivered to customers for execution on their machines, even if they haven't installed Visual Basic.

Running the IDE

You can choose from several ways to launch the Visual Basic IDE, as is true for any Windows executable:

You can run the Visual Basic 6 environment from the Start Menu; the exact path to the menu command depends on whether you have installed Visual Basic as part of the Microsoft Visual Studio suite.

You can create a shortcut to the IDE on your desktop and run it by simply double-clicking on it.

When Visual Basic is installed, it registers the .vbp, .frm, .bas, and a few other extensions with the operating system. Therefore, you can run the environment by double-clicking on any Visual Basic file.

If you have installed Microsoft Active Desktop, you can create a shortcut to the Visual Basic IDE on the system taskbar. This is probably the fastest way to run the IDE: it's similar to a desktop shortcut, but you don't have to minimize other windows to uncover it.

Don't underestimate the convenience of running the Visual Basic IDE in the fastest way possible. When you develop COM components or add-ins, you might need to follow the commonplace practice of opening multiple instances of the environment at the same time. You might need to repeat this operation several times during your working day.

Selecting the Project Type

The first time you run the Visual Basic IDE, you're asked to select the type of project you want to create, as you can see in Figure 1-1. In this chapter, as well as in many chapters in the first part of this book, we're going to create Standard EXE projects only, so you can click on the Open buttonor just press the Enter keyto start working with a regular project that, once compiled, will deliver a stand-alone EXE application. You can also decide to tick the "Don't show this dialog in future" check box if you want to avoid this operation the next time you launch the IDE.

Figure 1-1. The New Project dialog box that appears when you launch the Visual Basic 6 environment.

IDE Windows

If you have worked with Visual Basic 5, the Visual Basic 6 IDE will look very familiar to you, as you can see in Figure 1-2. In fact, the only indication that you're not interacting with Visual Basic 5 is a couple of new top-level menusQuery and Diagramand two new icons on the standard toolbar. When you begin to explore the IDE's menus, you might find a few other commands (in the Edit, View, Project, and Tools menus) that were missing in Visual Basic 5. But overall changes are minimal, and if you're familiar with the Visual Basic 5 environment you can start working with Visual Basic 6 right away.

On the other hand, if you have worked only with versions of Visual Basic earlier than 5, you're going to be surprised by the many changes in the working environment. For one thing, the IDE is now an MDI (Multiple Document Interface) application, and you can reduce it and its dependent window with a single operation. You can restore the SDI (Single Document Interface) working mode, if you prefer, by choosing Options from the Tools menu, clicking the Advanced tab, and ticking the SDI Development Environment check box.

Figure 1-2. The Visual Basic 6 environment with most windows opened.

Finally, if this is your first exposure to Visual Basic, you'll surely be confused by the many menu commands, toolbars, and windows that the IDE hosts. Let's quickly review the purpose of each item. You can display any of the windows using an appropriate command in the View menu. Many of them can also be opened using a keyboard shortcut, as described in the following paragraphs, or by clicking on an icon in the main toolbar.

The Project window gives you an overview of all the modules that are contained in your application. You can display such modules grouped by their types or in alphabetical order by clicking on the rightmost icon on the Project window's toolbar. You can then view the code in each module or the object associated with each module (for example, a form) by clicking the first or the second icon, respectively. You can quickly display the Project window or put it in front of other windows by pressing the Ctrl+R key combination or by clicking on the Project Explorer icon on the standard toolbar.

You use the Form Designer window to design your application's user interface. Any application can contain multiple forms, and you can open a number of form designers at the same time. Moreover, both Visual Basic 5 and 6 support additional designers, such as the UserControl and UserDocument designers.

The Toolbox window includes a set of objects that you can place on a form or on another designer. Visual Basic comes with a fixed set of controlsthe so-called intrinsic controlsbut you can add other Microsoft ActiveX controls to this window. To avoid filling this window with too many controls, you can create multiple tabs on it: just right-click on the window, select the Add Tab command, and at a prompt assign a name to the new tab. Then you can place additional ActiveX controls on this new tab or drag one or more controls from the General tab. Similarly, you can delete or rename any tab by right-clicking on it and selecting the Delete Tab or Rename Tab commands, respectively. You can't delete or rename the General tab, though.

You use the Code window to write code that determines the behavior of your forms and other objects in your application. You can keep a number of code windows visible at one time, each one displaying the code related to a form or, more generally, to a module in your application. You can't open two code windows for the same module; however, you can split a code window into two distinct and independent portions by dragging the small gray rectangle located immediately above the vertical scrollbar.

TIPYou can quickly show the code window associated with a form or another designer by pressing the F7 function key while the focus is on the designer. Similarly, if you have opened the code window related to a designer, press the Shift-F7 key combination to display the associated designer.

The Properties window lists all the properties of the object that's currently selected and gives you the opportunity to modify them. For instance, you can change the foreground and background colors of the form or the control that's currently selected. You can list properties in alphabetical order or group them in categories, and you can find a short description of the currently selected property near the bottom of this window. When you select an object, its properties are automatically displayed in the Properties window. If the window isn't visible, you can quickly display it by pressing the F4 key or by clicking on the Toolbox icon on the toolbar.

The Color Palette window is handy for quickly assigning a color to an object, such as the control that's currently selected on a form designer. You can select the foreground color of an object by left-clicking on the desired color, and if you click on an empty item in the bottom row of cells you can also define a custom color. Finally, you can select the background color of an object if you click on the larger square located near the upper left corner of the Color Palette window.

The Form Layout window shows how a given form will be displayed when the program runs. You can drag a form to the place on the screen where you want it to appear during execution, and you can also compare the relative sizes and positions of two or more forms. By right-clicking on this window, you can show its resolution guides, which enable you to check how your forms display at screen resolutions different from the current one.

The Immediate window lets you enter a Visual Basic command or expression and see its result using the Print command (which can also be shortened to ?). In break modethat is, when you have temporarily suspended a running programyou can use these commands to display the current value of a variable or an expression. You can also write diagnostic messages from your application's code to this window using the Debug.Print statement. Because the Immediate window isn't visible when the application is compiled and executed outside the environment, such diagnostic statements aren't included in the executable file. You can quickly open the Immediate window by pressing the Ctrl+G key combination.

TIP No menu command or toolbar icon lets you delete the current contents of the Immediate window. The quickest way to do it is by pressing the Ctrl+A key combination to select the Immediate window's entire contents, after which you press the Delete key to delete it or simply begin typing to replace the contents with whatever you want to type in instead.

The Object Browser is one of the most important tools available to the Visual Basic developer. It lets you explore external libraries so that you can learn about the objects they expose and their properties, methods, and events. The Object Browser also helps you quickly locate and jump to any procedure in any module of your application. You can open the Object Browser by pressing the F2 key or by clicking its icon on the standard toolbar.

The Locals window is active only when a program is executing. It lists the values of all the variables that are local to a module or to a procedure. If the variable is an object itself (a form or a control, for example) a plus (+) sign appears to the left of the variable name, which means that you can expand it and look at its properties.

The Watches window has a dual purpose: it lets you continuously monitor the value of a variable or an expression in your programincluding a global variable, which is outside the capabilities of the Locals windowand it also gives you the ability to stop the execution of a program when a given expression becomes True or whenever it changes its value. You can add one or more watch expressions using the Add Watch command from the Debug menu, or you can select the Add Watch command from the pop-up menu that appears when you right-click the Watches window itself.

The Call Stack window (not visible in Figure 1-2) appears only when you break the execution of a running program and press Ctrl+L. It shows all the procedures that are waiting for the current procedure to complete. It's a useful debugging tool in that it lets you understand the execution path that led to the current situation. Note that this is a modal window, so you must close it to resume regular execution.

The Data View window is new to Visual Basic. (See Figure 1-3 below.) In a nutshell, the Data View window offers an integrated tool to administer your databases and to explore their structures and the attributes of their tables and fields. The Data View window is particularly versatile when connecting to a Microsoft SQL Server or Oracle database because you can also add and delete its tables, views, and fields and edit stored procedures. Regardless of the database you're using, you can often drag tables and fields from the Data View window onto other windows in the IDE. You display this window using the Data View command from the View menu or by clicking on its icon on the standard toolbar.

Most of the windows I've just described can be docked: in other words, they can stick to the external frame of the main window of the IDE and are always on top of all other windows. By default, the majority of IDE windows are docked, although only the Toolbox, Project, Properties, and Form Layout windows are visible when the environment is launched. You can switch the Docked attribute on and off for a single window by right-clicking in it and then selecting the Dockable menu command. Alternatively, you can modify the Docked attribute individually for all the windows in the IDE by choosing Options from the Tools menu and then clicking the Docking tab. Just tick the check box associated with any window you want to be docked.

Figure 1-3. The Data View window lets you interactively create a new View object in an SQL Server database.

Menus

It's unnecessary to describe in detail the purpose of each menu command at this point in the book because most of the commands are related to advanced features of Visual Basic. But I think that an overview of all the top-level menus is useful, in that it gives you an idea of where to look for a given function when you need it.

The File menu includes the commands to load and save a Visual Basic project or a group of projects (Visual Basic 6 can open multiple projects in the environment), to save the current module, to print the entire project or selected portions of it, and to build the executable file.

The Edit menu lets you perform the typical editing commands, including Cut, Copy, Paste, Find, Replace, Undo, and Redo. It also includes commands that act on database tables, but they are active only when you're viewing the structure of a database or a database diagram. This menu also includes a bunch of commands related to Microsoft IntelliSense, a feature of the Visual Basic IDE that lets you automatically complete commands, list the syntax of functions and expected arguments, and so forth.

The View menu is the primary means of displaying any of the environment's windows described previously. It also includes some database-related commands that are enabled only if you have activated a tool for database maintenance.

The Project menu lets you add modules to the current project, including forms, standard (BAS) modules, class modules, UserControl modules, and so on. It also lets you add designer modules, which are the key to many new Visual Basic 6 features. The last three commands in this menu are particularly useful because they give you access to the References, the Components, and the Project Properties dialog boxes, respectively.

The Format menu is used to align and resize one or more controls on a form or on a designer of any type. You can also center a control on its form and increase or decrease the distance among a group of controls. When you're satisfied with the appearance of your form, you should select the Lock Controls option so that you can't accidentally move or resize the controls using the mouse.

The Debug menu contains the commands that you usually issue when you're testing an application within the IDE. You can execute your code step-by-step, display the value of a variable or an expression, and set one or more breakpoints in code. Breakpoints are special points in the code that, when reached during the program's execution, cause the Visual Basic environment to interrupt execution, thus entering break mode. You can also create conditional breakpoints, which are expressions that are monitored as each statement is executed. When the value of a conditional breakpoint changes or when the condition you specified becomes True, the program enters break mode and you can debug it easily.

The Run menu is probably the simplest of the group. It contains the commands to start the execution of the application being developed, to stop it and enter break mode, and to definitively end it.

The Query menu is new to the Visual Basic environment. It's available only in Visual Basic Enterprise and Professional Editions and only when you're interactively creating an SQL query using the Microsoft Query Builder utility, which you can see in Figure 1-3.

The Diagram menu, shown in Figure 1-4, is also new to Visual Basic. As with the Query menu, the Diagram menu is available only in the Enterprise and Professional Editions and only when you're interacting with SQL Server or Oracle databases to create or edit a database diagram.

Figure 1-4. The Diagram menu becomes active only when you're building a query or editing an SQL Server View object.

The Tools menu contains several miscellaneous commands, the most important of which is the Options command. This command allows you to access a dialog box that lets you customize the IDE.

The Add-In menu lists a collection of commands related to external modules that integrate into the environment. Visual Basic 6 itself comes with a number of such external add-ins, and you can also write your own.

The Window menu is the typical menu that you find in most MDI applications; it lets you arrange and tile your windows.

The Help menu is also standard for Microsoft Windows applications. Visual Basic 6 doesn't use standard HLP files any longer, and its help subsystem requires that you install Microsoft Developer Network (MSDN) to access its documentation.

Toolbars

Visual Basic comes with a standard toolbar that includes many common commands, such as those for loading and saving the project, running the program, and opening the most frequently used windows. Three more toolbars, Debug, Edit, and Form Editor, are visible only after you right-click on the standard toolbar and select one toolbar at a time from the submenu that appears. You can also make these toolbars visible by selecting the Toolbars option from the View menu.

All the toolbars can be docked in the upper portion of the main IDE window, or they can freely float in the environment, as you can see in Figure 1-5. You can quickly dock a floating toolbar by double-clicking on its title bar, and you can make a docked toolbar float by double-clicking on its left-most vertical stripes. If you want to know what a particular toolbar icon represents, place the mouse cursor over it and a yellow ToolTip showing a short explanation will appear after about a second.

Figure 1-5. Visual Basic 6 comes with four toolbars, which can float or be docked.

The Debug toolbar hosts most of the commands that are found in the Debug menu. The Edit toolbar is useful when you're editing code and setting breakpoints and bookmarks. The Form Editor toolbar includes most of the commands in the Format menu and is useful only when you're arranging controls on a form's surface.

Making these additional toolbars visible or not is largely a matter of personal taste. I usually prefer not to waste valuable desktop space with toolbars other than the standard one. If you work with a higher screen resolution, this might not be an issue for you.

TIPThe Edit toolbar is unusual because it contains two commands that aren't available through menu commandsthe Comment Block and Uncomment Block commands, which are useful when you're testing an application. (See Figure 1-5 for an example of a routine that has been commented using the Comment Block command.) For this reason, you might want to make the Edit toolbar visible.

You can customize the appearance of all the Visual Basic toolbars and even create new ones, as you can see in Figure 1-6. The procedure for creating a new toolbar is simple:

Right-click on any toolbar, and select the Customize menu command; this brings up the Customize dialog box.

Click the New button, and type a name for the new custom toolbar (for example, Custom Toolbar). The name of the new toolbar appears in the list of toolbars, and its check box is ticked. The empty toolbar appears on the screen. You're now ready to add commands to it.

Click the Commands tab, and then click a menu name in the leftmost list box. Click on an item in the list box on the right, and drag it over the custom toolbar to the spot where you want to insert it.

Right-click on the icon you have just added, and select a command from the pop-up menu that appears. The commands in this menu let you replace the icon with a different one, associate it with a caption, make it the beginning of a group, and so on.

Repeat steps 3 and 4 for all the commands you want to add to the custom toolbar, and then click on the Close button to make your additions permanent.

Figure 1-6. Creating a custom toolbar.

Here are a few commands that you should consider for inclusion in a custom toolbar because they're frequently used but don't have any associated hot keys:

The References and Properties commands from the Project menu

The Comment Block and Uncomment Block commands from the Edit toolbar (not displayed on the menu)

All the Bookmark submenu commands from the Edit menu

The Options command from the Tools menu

The Toolbox

The Toolbox window is probably the first window you'll become familiar with because it lets you visually create the user interface for your applications. More specifically, the Toolbox contains the icons of all the intrinsic controlsthat is, all the controls that are included in the Visual Basic runtime.

If you have already programmed with a previous version of Visual Basic, you surely know the characteristics of all the controls that are present in the Toolbox. If you haven't, refer to Figure 1-7 while you read the following condensed descriptions.

Figure 1-7. The Visual Basic 6 Toolbox with all the intrinsic controls.

The Pointer isn't a control; click this icon when you want to select controls already on the form rather than create new ones.

The PictureBox control is used to display images in any of the following formats: BMP, DIB (bitmap), ICO (icon), CUR (cursor), WMF (metafile), EMF (enhanced metafile), GIF, and JPEG.

The Label control serves to display static text or text that shouldn't be edited by the user; it's often used to label other controls, such as TextBox controls.

The TextBox control is a field that contains a string of characters that can be edited by the user. It can be single-line (for entering simple values) or multiline (for memos and longer notes). This is probably the most widely used control of any Windows application and is also one of the richest controls in terms of properties and events.

The Frame control is typically used as a container for other controls. You rarely write code that reacts to events raised by this control.

The CommandButton control is present in almost every form, often in the guise of the OK and Cancel buttons. You usually write code in the Click event procedure of this control.

The CheckBox control is used when the user has to make a yes/no, true/false selection.

OptionButton controls are always used in groups, and you can select only one control in the group at a time. When the user selects a control in the group, all other controls in the group are automatically deselected. OptionButton controls are useful for offering to the user a number of mutually exclusive selections. If you want to create two or more groups of OptionButton controls on a form, you must place each group inside another container control (most often a Frame control). Otherwise, Visual Basic can't understand which control belongs to which group.

The ListBox control contains a number of items, and the user can select one or more of them (depending on the value of the control's MultiSelect property).

The ComboBox control is a combination of a TextBox and a ListBox control, with the difference that the list portion is visible only if the user clicks on the down arrow to the right of the edit area. ComboBox controls don't support multiple selections.

The HScrollBar and VScrollBar controls let you create stand-alone scroll bars. These controls are used infrequently because the majority of other controls display their own scroll bars if necessary. Stand-alone scroll bars are sometimes used as sliders, but in this case you'd better use other, more eye-catching controls, such as the Slider control, which is covered in Chapter 10.

The Timer control is peculiar in that it isn't visible at run time. Its only purpose is to regularly raise an event in its parent form. By writing code in the corresponding event procedure, you can perform a task in the backgroundfor instance, updating a clock or checking the status of a peripheral device.

The DriveListBox, DirListBox, and FileListBox controls are often used together to create file-oriented dialog boxes. DriveListBox is a ComboBox-like control filled automatically with the names of all the drives in the system. DirListBox is a variant of the ListBox control; it shows all the subdirectories of a given directory. FileListBox is another special ListBox control; this control fills automatically with names of the files in a specified directory. While these three controls offer a lot of functionality, in a sense they have been superseded by the Common Dialog control, which displays a more modern user interface (to be covered in Chapter 12). If you want to write applications that closely conform to the Windows 9x look, you should avoid using these controls.

The Shape and Line controls are mostly cosmetic controls that never raise any events and are used only to display lines, rectangles, circles, and ovals on forms or on other designers.

The Image control is similar to the PictureBox control, but it can't act as a container for other controls and has other limitations as well. Nevertheless, you should use an Image control in place of a PictureBox control whenever possible because Image controls consume fewer system resources.

The Data control is the key to data binding, a Visual Basic feature that lets you connect one or more controls on a form to fields in a database table. The Data control works with Jet databases even though you can also use attached tables to connect to data stored in databases stored in other formats. But it can't work with ActiveX Data Objects (ADO) sources and is therefore not suitable for exploiting the most interesting database-oriented Visual Basic 6 features.

The OLE control can host windows belonging to external programs, such as a spreadsheet window generated by Microsoft Excel. In other words, you can make a window provided by another program appear as if it belongs to your Visual Basic application.

From this short description, you can see that not all the intrinsic controls are equally important. Some controls, such as the TextBox, Label, and CommandButton controls, are used in virtually every Visual Basic application, while other controls, such as the DriveListBox, DirListBox, and FileListBox controls, have been replaced, in practice, by newer controls. Similarly, you shouldn't use the Data control in any application that uses the ADO data sources.

[Previous] [Next]

Your Very First Visual Basic Program

Visual Basic lets you build a complete and functional Windows application by dropping a bunch of controls on a form and writing some code that executes when something happens to those controls or to the form itself. For instance, you can write code that executes when a form loads or unloads or when the user resizes it. Likewise, you can write code that executes when the user clicks on a control or types while the control has the input focus.

This programming paradigm is also known as event-driven programming because your application is made up of several event procedures executed in an order that's dependent on what happens at run time. The order of execution can't, in general, be foreseen when the program is under construction. This programming model contrasts with the procedural approach, which was dominant in the old days.

This section offers a quick review of the event-driven model and uses a sample application as a context for introducing Visual Basic's intrinsic controls, with their properties, methods, and events. This sample application, a very simple one, queries the user for the lengths of the two sides of a rectangle, evaluates its perimeter and area, and displays the results to the user. Like all lengthy code examples and programs illustrated in this book, this application is included on the companion CD.

Adding Controls to a Form

We're ready to get practical. Launch the Visual Basic IDE, and select a Standard EXE project. You should have a blank form near the center of the work area. More accurately, you have a form designer, which you use to define the appearance of the main window of your application. You can also create other forms, if you need them, and you can create other objects as well, using different designers (the UserControl and UserDocument designers, for example). Other chapters of this book are devoted to such designers.

One of the greatest strengths of the Visual Basic language is that programmers can design an application and then test it without leaving the environment. But you should be aware that designing and testing a program are two completely different tasks. At design time, you create your forms and other visible objects, set their properties, and write code in their event procedures. Conversely, at run time you monitor the effects of your programming efforts: What you see on your screen is, more or less, what your end users will see. At run time, you can't invoke the form designer, and you have only a limited ability to modify the code you have written at design time. For instance, you can modify existing statements and add new ones, but you can't add new procedures, forms, or controls. On the other hand, at run time you can use some diagnostic tools that aren't available at design time because they would make no sense in that context (for example, the Locals, the Watches, and the Call Stack windows).

To create one or more controls on a form's surface, you select the control type that you want from the Toolbox window, click on the form, and drag the mouse cursor until the control has the size and shape you want. (Not all controls are resizable. Some, such as the Timer control, will allow you to drag but will return to their original size and shape when you release the mouse button.) Alternatively, you can place a control on the form's surface by double-clicking its icon in the Toolbox: this action creates a control in the center of the form. Regardless of the method you follow, you can then move and resize the control on the form using the mouse.

TIPIf you need to create multiple controls of the same type, you can follow this three-step procedure: First, click on the control's icon on the Toolbox window while you keep the Ctrl key pressed. Next, draw multiple controls by clicking the left button on the form's surface and then dragging the cursor. Finally, when you're finished creating controls, press the Escape key or click the Pointer icon in the upper left corner of the Toolbox.

To complete our Rectangle sample application, we need four TextBox controlstwo for entering the rectangle's width and height and two for showing the resulting perimeter and area, as shown in Figure 1-8. Even if they aren't strictly required from an operational point of view, we also need four Label controls for clarifying the purpose of each TextBox control. Finally we add a CommandButton control named Evaluate that starts the computation and shows the results.

Place these controls on the form, and then move and resize them as depicted in Figure 1-8. Don't worry too much if the controls aren't perfectly aligned because you can later move and resize them using the mouse or using the commands in the Format menu.

Figure 1-8 The Rectangle Demo form at design time, soon after the placement of its controls.

Setting Properties of Controls

Each control is characterized by a set of properties that define its behavior and appearance. For instance, Label controls expose a Caption property that corresponds to the character string displayed on the control itself, and a BorderStyle property that affects the appearance of a border around the label. The TextBox control's most important property is Text, which corresponds to the string of characters that appears within the control itself and that can be edited by the user.

In all cases, you can modify one or more properties of a control by selecting the control in the form designer and then pressing F4 to show the Properties window. You can scroll through the contents of the Properties window until the property you're interested in becomes visible. You can then select it and enter a new value.

Using this procedure, you can modify the Caption property of all four Label controls to &Width, &Height, &Perimeter, and &Area, respectively. You will note that the ampersand character doesn't appear on the control and that its effect is to underline the character that follows it. This operation actually creates a hot key and associates it with the control. When a control is associated with a hot key, the user can quickly move the focus to the control by pressing an Alt+x key combination, as you normally do within most Windows applications. Notice that only controls exposing a Caption property can be associated with a hot key. Such controls include the Label, Frame, CommandButton, OptionButton, and CheckBox.

TIPThere is one handy but undocumented technique for quickly selecting a given property of a control. You just have to select the control on the form and press the Ctrl+Shift+x key, where x is the first letter in the property's name. For instance, select a Label control, and then press Ctrl+Shift+C to display the Properties window and select the Caption property in one operation. Pressing the Ctrl+Shift+C key again moves the focus to the next property whose name begins with the C character, and so on in a cyclic fashion.

Notice that once you have selected the Caption property for the first Label control, it stays selected when you then click on other controls. You can take advantage of this mechanism to change the Caption property of the CommandButton control to &Evaluate and the Caption property of the Form itself to Rectangle Demo, without having to select the Caption item in the Properties window each time. Note that ampersand characters within a form's caption don't have any special meaning.

As an exercise, let's change the font attributes used for the controls, which you do through the Font property. While you can perform this action on a control-by-control basis, it's much easier to select the group of controls that you want to affect and then modify their properties in a single operation. To select multiple controls, you can click on each one of them while you press either the Shift or the Ctrl key, or you can drag an imaginary rectangle around them. (This technique is also called lassoing the controls.)

TIPA quick way to select all the controls on a form is to click anywhere on the form and press the Ctrl+A key combination. After selecting all controls, you can deselect a few of them by clicking on them while pressing the Shift or Ctrl key. Note that this shortcut doesn't select controls that are contained in other controls.

When you select a group of controls and then press the F4 key, the Properties window displays only the properties that are common to all the selected controls. The only properties that are exposed by any control are Left, Top, Width, and Height. If you select a group of controls that display a string of characters, such as the TextBox, Label, and CommandButton controls in our Rectangle example, the Font property is also available and can therefore be selected. When you double-click on the Font item in the Properties window, a Font dialog box appears. Let's select a Tahoma font and set its size to 11 points.

TIPIf you want to copy a number of properties from one control to one or more other controls, you can select the control you want to copy from, press Shift and select the other controls, press F4 to show the Properties window, and triple-click the name of the property you want to copy. Note that you must click the name of the property on the left, not the value cell on the right. The values of the properties on which you triple-click are copied from the source controls to all the other selected controls. This technique doesn't work with all the items in the Properties window.

Finally we must clear the Text property of each of the four TextBox controls so that the end user will find them empty when the program begins its execution. Oddly, when you select two or more TextBox controls, the Text property doesn't appear in the Properties window. Therefore, you must set the Text property to an empty string for each individual TextBox control on the form. To be honest, I don't know why this property is an exception to the rule stated earlier. The result of all these operations is shown in Figure 1-9.

Figure 1-9. The Rectangle Demo form at design time, after setting the controls' properties.

TIPWhen a control is created from the Toolbox, its Font property reflects the font of the parent form. For this reason, you can often avoid individual font settings by changing the form's Font property before placing any controls on the form itself.

Naming Controls

One property that every control has and that's very important to Visual Basic programmers is the Name property. This is the string of characters that identifies the control in code. This property can't be an empty string, and you can't have two or more controls on a form with the same name. The special nature of this property is indirectly confirmed by the fact that it appears as (Name) in the Properties window, where the initial parenthesis serves to move it to the beginning of the property list.

When you create a control, Visual Basic assigns it a default name. For example, the first TextBox control that you place on the form is named Text1, the second one is named Text2, and so forth. Similarly, the first Label control is named Label1, and the first CommandButton control is named Command1. This default naming scheme frees you from having to invent a new, unique name each time you create a control. Notice that the Caption property of Label and CommandButton controls, as well as the Text property of TextBox controls, initially reflect the control's Name property, but the two properties are independent of each other. In fact, you have just modified the Caption and Text properties of the controls in the Rectangle Demo form without affecting their Name properties.

Because the Name property identifies the control in code, it's a good habit to modify it so that it conveys the meaning of the control itself. This is as important as selecting meaningful names for your variables. In a sense, most controls on a form are special variables whose contents are entered directly by the user.

Microsoft suggests that you always use the same three-letter prefix for all the controls of a given class. The control classes and their recommended prefixes are shown in Table 1-1.

Table 1-1. Standard three-letter prefixes for forms and all intrinsic controls.

Control Class Prefix Control Class Prefix

CommandButton cmd Data dat

TextBox txt HScrollBar hsb

Label lbl VScrollBar vsb

PictureBox pic DriveListBox drv

OptionButton opt DirListBox dir

CheckBox chk FileListBox fil

ComboBox cbo Line lin

ListBox lst Shape shp

Timer tmr OLE ole

Frame fra Form frm

For instance, you should prefix the name of a TextBox control with txt, the name of a Label control with lbl, and the name of a CommandButton control with cmd. Forms should also follow this convention, and the name of a form should be prefixed with the frm string. This convention makes a lot of sense because it lets you deduce both the control's type and meaning from its name. This book sticks to this naming convention, especially for more complex examples when code readability is at stake.

In our example, we will rename the Text1 through Text4 controls as txtWidth, txtHeight, txtPerimeter, and txtArea respectively. The Command1 control will be renamed cmdEvaluate, and the four Label1 through Label4 controls will be renamed lblWidth, lblHeight, lblPerimeter, and lblArea, respectively. However, please note that Label controls are seldom referred to in code, so in most cases you can leave their names unmodified without affecting the code's readability.

Moving and Resizing Controls

You probably won't be able to place your controls on the form in the right position on your first attempt. Most likely, you will try several layouts until you are satisfied with the overall appearance of the form. Fortunately, the IDE offers you many ways to modify the position and size of your controls without much effort.

Select one or more controls, and move them as a single entity using the mouse.

Move one or more controls with arrow keys while you press the Ctrl key. The steps along the x- and y-axes are determined by the Grid Units settings. You can view and modify these settings using the General tab of the Options dialog box from the Tools menu.

Resize the selected control(s) by using the arrow keys while you press the Shift key. You can also resize a control by dragging one of the blue handles surrounding it when it is selected. Like the move operation, the resize step depends on the Grid Units settings.

Center a control or a group of controls on the form, either horizontally or vertically, using the Center In Form submenu of the Format menu.

Align a group of controls with respect to another control using the commands in the Align submenu of the Format menu. The control used as a reference in the aligning process is the one that was selected last (that is, the one with blue handles around it).

Resize a group of controls by selecting them and invoking a command in the Make Same Size submenu of the Format menu. All selected controls will be resized to reflect the size of the control that was selected last.

You can align or resize a group of controls by selecting them, pressing F4 to display the Properties window, and then manually modifying the Left, Top, Width, or Height properties. This procedure is useful when you know the absolute position or size of the controls.

TIPA ComboBox control is peculiar in that its height is determined by the system and depends on its Font property. Therefore, if you have ComboBox and single-line TextBox controls on the same form, you should use either one of the last two techniques that I just described to resize the TextBox controls to reflect the height of the ComboBox control(s) placed on the form. This will give your form a consistent look.

Setting the Tab Order

Windows standards dictate that the user can press the Tab key to visit all the fields in a window in the logical order. Such a sequence is known as the Tab order sequence. In Visual Basic, you set the correct Tab order sequence by assigning a proper value to the TabIndex property for all the controls that can receive the input focus, starting with 0 for the control that should receive the input focus when the form appears and assigning increasing values for all the others. In our Rectangle sample application, this means assigning 0 to the txtWidth control's TabIndex property, 1 to the txtHeight control's TabIndex property, and so on.

But wait, there's more to know about the Tab order setting. Even if Label controls never get the focus themselves, they expose a TabIndex property. Why?

As I mentioned previously, TextBox controlsor more to the point, controls that don't expose a Caption propertycan't be directly associated with a hot key. This means that you can't use an Alt+x key combination to activate them. In our Rectangle example, we overcome this limitation by placing Label controls above each individual TextBox control. Unfortunately, placing a Label control near another control doesn't automatically provide it with hot key capabilities. To have a Label control lend its hot key to another control on the form, you must assign the Label's TabIndex property a value that is 1 less than the value of the other control's TabIndex property.

In our Rectangle sample application, this means assigning the TabIndex property as follows: 0 to lblWidth, 1 to txtWidth, 2 to lblHeight, 3 to txtHeight, 4 to cmdEvaluate, 5 to lblPerimeter, 6 to txtPerimeter, 7 to lblArea, and 8 to txtArea.

It's immediately apparent that when you have forms with tens or even hundreds of controls, correctly setting the TabIndex property for each one of them is a nuisance. For this reason, a number of third-party commercial or shareware vendors have developed special add-ins that permit you to solve this task in a visual manner, for example by clicking on each control, or in a semiautomatic manner by analyzing the relative position of all controls on the form. While these add-ins are real lifesavers, here's a trick well known among Visual Basic programmers that solves the problem with relatively little effort:

Select the last control in your planned Tab order.

Press the Ctrl+Shift+T key combination to activate the Properties window. For most controls, this combination selects the TabIndex properties; for others, you might need to press it more than once.

Press the 0 key, thus assigning a 0 to the TabIndex property of the selected control.

Click on the next to last control in the Tab order, and press the 0 key again; this assigns a 0 to the TabIndex property of the current control and 1 to the TabIndex property of the last control. This occurs because Visual Basic prevents you from using the same TabIndex value for two or more controls on the same form.

Repeat step 4, working backward in the Tab order sequence and pressing the 0 key after selecting each control. When you reach the first control in the sequence, the TabIndex property for all the controls on the form will be set correctly.

TIPVisual Basic 5 and 6 also come with an add-in that permits you to arrange the TabIndex property for all the controls on the current form. This add-in is provided in source code format, in the TabOrder.vbp project located in the Samples\CompTool\AddIns subdirectory. To use this add-in, you must compile and install it manually. This tool lets you save a lot of time when arranging the Tab order for forms with many controls.

Now that we have completed our project, we'll save it. Choose Save Project from the File menu, or click the floppy disk icon. Visual Basic will ask you for the name of the form file, and again for the name of the project file; type Rectangle for both. You'll see that you now have two new files, Rectangle.frm and Rectangle.vbp.

Adding Code

Up to this point, you have created and refined the user interface of your program and created an application that in principle can be run. (Press F5 and run it to convince yourself that it indeed works.) But you don't have a useful application yet. To turn your pretty but useless program into your first working application, you need to add some code. More precisely, you have to add some code in the Click event of the cmdEvaluate control. This event fires when the user clicks on the Evaluate button or presses its associated hot key (the Alt+E key combination, in this case).

To write code within the Click event, you just select the cmdEvaluate control and then press the F7 key, or right-click on it and then invoke the View Code command from the pop-up menu. Or you simply double-click on the control using the left mouse button. In all cases, the code editor window appears, with the flashing cursor located between the following two lines of code:

Private Sub cmdEvaluate_Click()

End Sub

Visual Basic has prepared the template of the Click event procedure for you, and you have to add one or more lines of code between the Sub and End Sub statements. In this simple program, you need to extract the values stored in the txtWidth and txtHeight controls, use them to compute the rectangle's perimeter and area, and assign the results to the txtPerimeter and txtArea controls respectively:

Private Sub cmdEvaluate_Click() ' Declare two floating point variables. Dim reWidth As Double, reHeight As Double ' Extract values from input TextBox controls. reWidth = CDbl(txtWidth.Text) reHeight = CDbl(txtHeight.Text) ' Evaluate results and assign to output text boxes. txtPerimeter.Text = CStr((reWidth + reHeight) * 2) txtArea.Text = CStr(reWidth * reHeight)End Sub

TIPMany developers, especially those with prior experience in the QuickBasic language, are accustomed to extracting numeric values from character strings using the Val function. The CDbl or CSng conversion functions are better choices in most cases, however, because they're locale-aware and correctly interpret the number in those countries where the decimal separator is the comma instead of the period. Even more important, the CDbl or CSng functions conveniently skip over separator characters and currency symbols (as in $1,234), whereas the Val function doesn't.

Note that you should always use the Dim statement to declare the variables you are going to use so that you can specify for them the most suitable data type. If you don't do that, Visual Basic will default them to the Variant data type. While this would be OK for this sample program, for most occasions you can make better and faster applications if you use variables of a more specific type. Moreover, you should add an Option Explicit statement at the very beginning of the code module so that Visual Basic will automatically trap any attempt to use a variable that isn't declared anywhere in the program code. By this single action, you'll avoid a lot of problems later in the development phase.

Running and Debugging the Program

You're finally ready to run this sample program. You can start its execution in several ways: By invoking the Start command from the Run menu, by clicking the corresponding icon on the toolbar, or by pressing the F5 key. In all cases, you'll see the form designer disappear and be replaced (but not necessarily in the same position on the screen) by the real form. You can enter any value in the leftmost TextBox controls and then click on the Evaluate button (or press the Alt+E key combination) to see the calculated perimeter and area in the rightmost controls. When you're finished, end the program by closing its main (and only) form.

CAUTIONYou can also stop any Visual Basic program running in the environment by invoking the End command from the Run menu, but in general this isn't a good approach because it prevents a few form-related eventsnamely the QueryUnload and the Unload eventsfrom firing. In some cases, these event procedures contain the so-called clean-up code, for example, statements that close a database or delete a temporary file. If you abruptly stop the execution of a program, you're actually preventing the execution of this code. As a general rule, use the End command only if strictly necessary.

This program is so simple that you hardly need to test and debug it. Of course, this wouldn't be true for any real-world application. Virtually all programs need to be tested and debugged, which is probably the most delicate (and often tedious) part of a programmer's job. Visual Basic can't save you from this nuisance, but at least it offers so many tools that you can often complete it very quickly.

To see some Visual Basic debugging tools in action, place a breakpoint on the first line of the Click event procedure while the program is in design mode. You can set a breakpoint by moving the text cursor to the appropriate line and then invoking the Toggle Breakpoint command from the Debug menu or pressing the F9 shortcut key. You can also set and delete breakpoints by left-clicking on the gray vertical strip that runs near the left border of the code editor window. In all cases, the line on which the breakpoint is set will be highlighted in red.

After setting the breakpoint at the beginning of the Click event procedure, press F5 to run the program once again, enter some values in the Width and Height fields, and then click on the Evaluate button. You'll see the Visual Basic environment enter break mode, and you are free to perform several actions that let you better understand what's actually going on:

Press F8 to execute the program one statement at a time. The Visual Basic instruction that's going to be executed nextthat is, the current statement is highlighted in yellow.

Show the value of an expression by highlighting it in the code window and then pressing F9 (or selecting the Quick Watch command from the Debug menu). You can also add the selected expression to the list of values displayed in the Watch window, as you can see in Figure 1-10.

An alternative way to show the value of a variable or a property is to move the mouse cursor over it in the code window; after a couple of seconds, a yellow data tip containing the corresponding value appears.

Evaluate any expression by clicking on the Immediate window and typing ? or Print followed by the expression. This is necessary when you need to evaluate the value of an expression that doesn't appear in the code window.

You can view the values of all the local variables (but not expressions) by selecting the Locals command from the View menu. This command is particularly useful when you need to monitor the value of many local variables and you don't want to set up a watching expression for each one.

You can affect the execution flow by placing the text cursor on the statement that you want to execute next and then selecting the Set Next Statement command from the Debug menu. Or you can press the Ctrl+F9 key combination. You need this technique to skip over a piece of code that you don't want to execute or to reexecute a given block of lines without restarting the program.

Figure 1-10. The Rectangle Demo program in break mode, with several debug tools activated.

Refining the Sample Program

Our first Visual Basic project, Rectangle.vbp, is just a sample program, but this is no excuse not to refine it and turn it into a complete and robust, albeit trivial, application.

The first type of refinement is very simple. Because the txtPerimeter and txtArea controls are used to show the results of the computation, it doesn't make sense to make their contents editable by the user. You can make them read-only fields by setting their Locked property to True. (A suggestion: select the two controls, press F4, and modify the property just once.) Some programmers prefer to use Label controls to display result values on a form, but using read-only TextBox controls has an advantage: The end user can copy their contents to the clipboard and paste those contents into another application.

A second refinement is geared toward increasing the application's consistency and usability. Let's suppose that your user uses the Rectangle program to determine the perimeter and area of a rectangle, takes note of the results, and then enters a new width or a new height (or both). Unfortunately, an instant before your user clicks on the Evaluate button the phone rings, engaging the user in a long conversation. When he or she hangs up, the form shows a plausible, though incorrect, result. How can you be sure that those values won't be mistaken for good ones? The solution is simple, indeed: as soon as the user modifies either the txtWidth or the txtHeight TextBox controls, the result fields must be cleared. In Visual Basic, you can accomplish this task by trapping each source control's Change event and writing a couple of statements in the corresponding event procedure. Since Change is the default event for TextBox controlsjust as the Click event is for CommandButtons controlsyou only have to double-click the txtWidth and txtHeight controls on the form designer to have Visual Basic create the template for the corresponding event procedures. This is the code that you have to add to the procedures:

Private Sub txtWidth_Change() txtPerimeter.Text = "" txtArea.Text = ""End Sub

Private Sub txtHeight_Change() txtPerimeter.Text = "" txtArea.Text = ""End Sub

Note that you don't have to retype the statements in the txtHeight's Change event procedure: just double-click the control to create the Sub ... End Sub template, and then copy and paste the code from the txtWidth_Click procedure. When you're finished, press F5 to run the program to check that it now behaves as expected.

The purpose of the next refinement that I am proposing is to increase the program's robustness. To see what I mean, run the Rectangle project and press the Evaluate button without entering width or height values: the program raises a Type Mismatch error when trying to extract a numeric value from the txtWidth control. If this were a real-world, compiled application, such an untrapped error would cause the application to end abruptly, which is, of course, unacceptable. All errors should be trapped and dealt with in a convenient way. For example, you should show the user where the problem is and how to fix it. The easiest way to achieve this is by setting up an error handler in the cmdEvaluate_Click procedure, as follows. (The lines you would add are in boldface.)

Private Sub cmdEvaluate_Click() ' Declare two floating point variables. Dim reWidth As Double, reHeight As Double On Error GoTo WrongValues

' Extract values from input textbox controls. reWidth = CDbl(txtWidth.Text) reHeight = CDbl(txtHeight.Text) Ensure that they are positive values. If reWidth = 0 Then lstRight.AddItem lstLeft.Text lstLeft.RemoveItem lstLeft.ListIndex End IfEnd Sub

Private Sub cmdMoveAll_Click() ' Move all items from left to right. Do While lstLeft.ListCount lstRight.AddItem lstLeft.List(0) lstLeft.RemoveItem 0 LoopEnd Sub

Private Sub cmdBack_Click() ' Move one item from right to left. If lstRight.ListIndex >= 0 Then lstLeft.AddItem lstRight.Text lstRight.RemoveItem lstRight.ListIndex End IfEnd Sub

Private Sub cmdBackAll_Click() ' Move all items from right to left. Do While lstRight.ListCount lstLeft.AddItem lstRight.List(0) lstRight.RemoveItem 0 LoopEnd Sub

Private Sub lstLeft_DblClick() ' Simulate a click on the Move button. cmdMove.Value = TrueEnd Sub

Private Sub lstRight_DblClick() ' Simulate a click on the Back button. cmdBack.Value = TrueEnd Sub

The Scroll event comes in handy when you need to synchronize a ListBox control with another control, often another list box; in such cases, you usually want to scroll the two controls together, so you need to know when either one is scrolled. The Scroll event is often used in conjunction with the TopIndex property, which sets or returns the index of the first visible item in the list area. Using the Scroll event together with the TopIndex property, you can achieve really interesting visual effects, such as the one displayed in Figure 3-9. The trick is that the leftmost ListBox control is partially covered by the other control. Its companion scroll bar is never seen by users, who are led to believe that they're acting on a single control. For the best effect, you need to write code that keeps the two controls always in sync, and you achieve that by trapping Click, MouseDown, MouseMove, and Scroll events. The following code synchronizes two lists, lstN and lstSquare:

Figure 3-9. You don't need a grid control to simulate a simple table; two partially overlapping ListBox controls will suffice.

Private Sub lstN_Click() ' Synchronize list boxes. lstSquare.TopIndex = lstN.TopIndex lstSquare.ListIndex = lstN.ListIndexEnd SubPrivate Sub lstSquare_Click() ' Synchronize list boxes. lstN.TopIndex = lstSquare.TopIndex lstN.ListIndex = lstSquare.ListIndexEnd Sub

Private Sub lstN_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) Call lstN_ClickEnd SubPrivate Sub lstSquare_MouseDown(Button As Integer, _ Shift As Integer, X As Single, Y As Single) Call lstSquare_ClickEnd Sub

Private Sub lstN_MouseMove(Button As Integer, Shift As Integer, _ X As Single, Y As Single) Call lstN_ClickEnd SubPrivate Sub lstSquare_MouseMove(Button As Integer, _ Shift As Integer, X As Single, Y As Single) Call lstSquare_ClickEnd Sub

Private Sub lstN_Scroll() lstSquare.TopIndex = lstN.TopIndexEnd SubPrivate Sub lstSquare_Scroll() lstN.TopIndex = lstSquare.TopIndexEnd Sub

The ItemData property

The information you place in a ListBox control is rarely independent from the rest of the application. For example, the customer's name that you see on screen is often related to a corresponding CustomerID number, a product name is associated with its description, and so on. The problem is that once you load a value into the ListBox control you somehow disrupt such relationships; the code in event procedures sees only ListIndex and List properties. How can you retrieve the CustomerID value that was originally associated with the name that the user has just clicked on? The answer to this question is provided by the ItemData property, which lets you associate a 32bit integer value with each item loaded in the ListBox control, as in the code below.

' Add an item to the end of the list.lstCust.AddItem CustomerName' Remember the matching CustomerID.lstCust.ItemData(lstCust.ListCount -1) = CustomerId

Note that you must pass an index to the ItemData property: Because the item you have just added is now the last one in the ListBox control, its index is ListCount-1. Unfortunately, this simple approach doesn't work with sorted ListBox controls, which can place new items anywhere in the list. In this case, you use the NewIndex property to find out where an item has been inserted:

' Add an item to the end of the list.lstCust.AddItem CustomerName' Remember the matching ID. (This also works with Sorted list boxes.)lstCust.ItemData(lstCust.NewIndex) = CustomerId

In real-world applications, associating a 32-bit integer value with an item in a ListBox control is often inadequate, and you usually need to store more complex information. In this case, you use the ItemData value as an index into another structure, for example, an array of strings or an array of records. Let's say you have a list of product names and descriptions:

Type ProductUDT Name As String Description As String Price As CurrencyEnd TypeDim Products() As ProductUDT, i As Long

Private Sub Form_Load() ' Load product list from database into Products. ' ... (code omitted) ' Load product names into a sorted ListBox. For i = LBound(Products) To UBound(Products) lstProducts.AddItem Products(i).Name ' Remember where this product comes from. lstProducts.ItemData(lstProducts.NewIndex) = i NextEnd Sub

Private Sub lstProducts_Click() ' Show the description and price of the item ' currently selected, using two companion labels. i = lstProducts.ItemData(lstProducts.ListIndex) lblDescription.Caption = Products(i).Description lblPrice.Caption = Products(i).PriceEnd Sub

Multiple-selection ListBox controls

The ListBox control is even more flexible than I've shown so far because it lets users select multiple items at the same time. To enable this feature, you assign the MultiSelect property the values 1-Simple or 2-Extended. In the former case, you can select and deselect individual items only by using the Spacebar or the mouse. In extended selection, you can also use the Shift key to select ranges of items. Most popular Windows programs use extended selection exclusively, so you shouldn't use the value 1-Simple unless you have a good reason to do so. The MultiSelect property can't be changed when the program is running, so this is a design-time decision.

Working with a multiple selection ListBox control isn't different from interacting with a regular ListBox in the sense that you still use the ListIndex, ListCount, List, and ItemData properties. In this case, the most important piece of information is held in the SelCount and Selected properties. The SelCount property simply returns the number of items that are currently selected. You usually test it within a Click event:

Private Sub lstProducts_Click() ' The OK button should be enabled only if the ' user has selected at least one product. cmdOK.Enabled = (lstProducts.SelCount > 0)End Sub

You retrieve the items that are currently selected using the Selected property. For example, this routine prints all selected items:

' Print a list of selected products.Dim i As LongFor i = 0 To lstProducts.ListCount -1 If lstProducts.Selected(i) Then Print lstProducts.List(i)Next

The Select property can be written to, which is sometimes necessary to clear the current selection:

For i = 0 To lstProducts.ListCount -1 lstProducts.Selected(i) = FalseNext

Visual Basic 5 introduced a new variant of multiple selection ListBox controls, which let users select items by flagging a check box, as you see in Figure 3-10. To enable this capability, you set the ListBox control's Style property to 1-Checkbox at design time. (You can't change it at run time.) ListBox controls with check boxes are always multiselect, and the actual value of the MultiSelect property is ignored. These ListBox controls let the user select and deselect one item at a time, so it's often convenient to provide the user with two buttonsSelect All and Clear All (and sometimes Invert Selection too).

Figure 3-10. Two variants for multiple selection ListBox controls.

Apart from their appearance, there's nothing special about ListBox controls set as Style = 1-Checkbox, in that you can set and query the selected state of items through the Selected property. However, selecting and deselecting multiple items through code doesn't happen as quickly as you might believe. For example, this is the code for handling the Click event of the Select All button:

Private Sub cmdSelectAll_Click() Dim i As Long, saveIndex As Long, saveTop As Long ' Save current state. saveIndex = List2.ListIndex saveTop = List2.TopIndex ' Make the list box invisible to avoid flickering. List2.Visible = False ' Change the select state for all items. For i = 0 To List2.ListCount - 1 List2.Selected(i) = True Next ' Restore original state, and make the list box visible again. List2.TopIndex = saveTop List2.ListIndex = saveIndex List2.Visible = TrueEnd Sub

The code for the Clear All and Invert All buttons is similar, except for the statement inside the ForNext loop. This approach is necessary because writing to the Selected property also affects the ListIndex property and causes a lot of flickering. Saving the current state in two temporary variables solves the former problem, while making the control temporarily invisible solves the latter.

Interestingly, making the control invisible doesn't actually hide it, not immediately at least. If you operate on a control and want to avoid flickering or other disturbing visual effects, make it invisible, do your stuff, and then make it visible again before the procedure ends. If the procedure doesn't include any DoEvents or Refresh statement, the screen isn't updated and the user will never notice that the control has been made temporarily invisible. To see how the code would work without resorting to this technique, add a DoEvents or a Refresh statement to the preceding code, immediately before the ForNext loop.

ListBox controls with Style = 1-Checkbox offer an additional event, ItemCheck, that fires when the user selects or deselects the check box. You can use this event to refuse to select or deselect a given item:

Private Sub List2_ItemCheck(Item As Integer) ' Refuse to deselect the first item. If Item = 0 And List2.Selected(0) = False Then List2.Selected(0) = True MsgBox "You can't deselect the first item", vbExclamation End IfEnd Sub

ComboBox Controls

ComboBox controls are very similar to ListBox controls, so much of what I have explained so far applies to them as well. More precisely, you can create ComboBox controls that automatically sort their items using the Sorted property, you can add items at design time using the List item in the Properties window, and you can set a ComboBox control's IntegralHeight property as your user interface dictates. Most run-time methods are common to both kinds of controls too, including AddItem, RemoveItem, and Clear, as are the ListCount, ListIndex, List, ItemData, TopIndex, and NewIndex properties and the Click, DblClick, and Scroll events. ComboBox controls don't support multiple columns and multiple selections, so you don't have to deal with the Column, MultiSelect, Select, and SelCount properties and the ItemCheck event.

The ComboBox control is a sort of mixture between a ListBox and a TextBox control in that it also includes several properties and events that are more typical of the latter, such as the SelStart, SelLength, SelText, and Locked properties and the KeyDown, KeyPress, and KeyUp events. I've already explained many things that you can do with these properties and won't repeat myself here. Suffice it to say that you can apply to ComboBox controls most of the techniques that are valid for TextBox controls, including automatic formatting and deformatting of data in GotFocus and LostFocus event procedures and validation in Validate event procedures.

The most characteristic ComboBox control property is Style, which lets you pick one among the three styles available, as you can see in Figure 3-11. When you set Style = 0-DropDown Combo, what you get is the classic combo; you can enter a value in the edit area or select one from the drop-down list. The setting Style = 1-Simple Combo is similar, but the list area is always visible so that in this case you really have a compounded TextBox plus ListBox control. By default, Visual Basic creates a control that's only tall enough to show the edit area, and you must resize it to make the list portion visible. Finally, Style = 2-Dropdown List suppresses the edit area and gives you only a drop-down list to choose from.

Figure 3-11. Three different styles for ComboBox controls. The drop-down list variant doesn't allow direct editing of the contents.

When you have a ComboBox control with Style = 0-Dropdown Combo or 2-Dropdown List, you can learn when the user is opening the list portion by trapping the DropDown event. For example, you can fill the list area just one instant before the user sees it (a sort of just-in-time data loading):

Private