- •Using Your Sybex Electronic Book
- •Acknowledgments
- •Contents at a Glance
- •Introduction
- •Who Should Read This Book?
- •How About the Advanced Topics?
- •The Structure of the Book
- •How to Reach the Author
- •The Integrated Development Environment
- •The Start Page
- •Project Types
- •Your First VB Application
- •Making the Application More Robust
- •Making the Application More User-Friendly
- •The IDE Components
- •The IDE Menu
- •The Toolbox Window
- •The Solution Explorer
- •The Properties Window
- •The Output Window
- •The Command Window
- •The Task List Window
- •Environment Options
- •A Few Common Properties
- •A Few Common Events
- •A Few Common Methods
- •Building a Console Application
- •Summary
- •Building a Loan Calculator
- •How the Loan Application Works
- •Designing the User Interface
- •Programming the Loan Application
- •Validating the Data
- •Building a Math Calculator
- •Designing the User Interface
- •Programming the MathCalculator App
- •Adding More Features
- •Exception Handling
- •Taking the LoanCalculator to the Web
- •Working with Multiple Forms
- •Working with Multiple Projects
- •Executable Files
- •Distributing an Application
- •VB.NET at Work: Creating a Windows Installer
- •Finishing the Windows Installer
- •Running the Windows Installer
- •Verifying the Installation
- •Summary
- •Variables
- •Declaring Variables
- •Types of Variables
- •Converting Variable Types
- •User-Defined Data Types
- •Examining Variable Types
- •Why Declare Variables?
- •A Variable’s Scope
- •The Lifetime of a Variable
- •Constants
- •Arrays
- •Declaring Arrays
- •Initializing Arrays
- •Array Limits
- •Multidimensional Arrays
- •Dynamic Arrays
- •Arrays of Arrays
- •Variables as Objects
- •So, What’s an Object?
- •Formatting Numbers
- •Formatting Dates
- •Flow-Control Statements
- •Test Structures
- •Loop Structures
- •Nested Control Structures
- •The Exit Statement
- •Summary
- •Modular Coding
- •Subroutines
- •Functions
- •Arguments
- •Argument-Passing Mechanisms
- •Event-Handler Arguments
- •Passing an Unknown Number of Arguments
- •Named Arguments
- •More Types of Function Return Values
- •Overloading Functions
- •Summary
- •The Appearance of Forms
- •Properties of the Form Control
- •Placing Controls on Forms
- •Setting the TabOrder
- •VB.NET at Work: The Contacts Project
- •Anchoring and Docking
- •Loading and Showing Forms
- •The Startup Form
- •Controlling One Form from within Another
- •Forms vs. Dialog Boxes
- •VB.NET at Work: The MultipleForms Project
- •Designing Menus
- •The Menu Editor
- •Manipulating Menus at Runtime
- •Building Dynamic Forms at Runtime
- •The Form.Controls Collection
- •VB.NET at Work: The DynamicForm Project
- •Creating Event Handlers at Runtime
- •Summary
- •The TextBox Control
- •Basic Properties
- •Text-Manipulation Properties
- •Text-Selection Properties
- •Text-Selection Methods
- •Undoing Edits
- •VB.NET at Work: The TextPad Project
- •Capturing Keystrokes
- •The ListBox, CheckedListBox, and ComboBox Controls
- •Basic Properties
- •The Items Collection
- •VB.NET at Work: The ListDemo Project
- •Searching
- •The ComboBox Control
- •The ScrollBar and TrackBar Controls
- •The ScrollBar Control
- •The TrackBar Control
- •Summary
- •The Common Dialog Controls
- •Using the Common Dialog Controls
- •The Color Dialog Box
- •The Font Dialog Box
- •The Open and Save As Dialog Boxes
- •The Print Dialog Box
- •The RichTextBox Control
- •The RTF Language
- •Methods
- •Advanced Editing Features
- •Cutting and Pasting
- •Searching in a RichTextBox Control
- •Formatting URLs
- •VB.NET at Work: The RTFPad Project
- •Summary
- •What Is a Class?
- •Building the Minimal Class
- •Adding Code to the Minimal Class
- •Property Procedures
- •Customizing Default Members
- •Custom Enumerations
- •Using the SimpleClass in Other Projects
- •Firing Events
- •Shared Properties
- •Parsing a Filename String
- •Reusing the StringTools Class
- •Encapsulation and Abstraction
- •Inheritance
- •Inheriting Existing Classes
- •Polymorphism
- •The Shape Class
- •Object Constructors and Destructors
- •Instance and Shared Methods
- •Who Can Inherit What?
- •Parent Class Keywords
- •Derived Class Keyword
- •Parent Class Member Keywords
- •Derived Class Member Keyword
- •MyBase and MyClass
- •Summary
- •On Designing Windows Controls
- •Enhancing Existing Controls
- •Building the FocusedTextBox Control
- •Building Compound Controls
- •VB.NET at Work: The ColorEdit Control
- •VB.NET at Work: The Label3D Control
- •Raising Events
- •Using the Custom Control in Other Projects
- •VB.NET at Work: The Alarm Control
- •Designing Irregularly Shaped Controls
- •Designing Owner-Drawn Menus
- •Designing Owner-Drawn ListBox Controls
- •Using ActiveX Controls
- •Summary
- •Programming Word
- •Objects That Represent Text
- •The Documents Collection and the Document Object
- •Spell-Checking Documents
- •Programming Excel
- •The Worksheets Collection and the Worksheet Object
- •The Range Object
- •Using Excel as a Math Parser
- •Programming Outlook
- •Retrieving Information
- •Recursive Scanning of the Contacts Folder
- •Summary
- •Advanced Array Topics
- •Sorting Arrays
- •Searching Arrays
- •Other Array Operations
- •Array Limitations
- •The ArrayList Collection
- •Creating an ArrayList
- •Adding and Removing Items
- •The HashTable Collection
- •VB.NET at Work: The WordFrequencies Project
- •The SortedList Class
- •The IEnumerator and IComparer Interfaces
- •Enumerating Collections
- •Custom Sorting
- •Custom Sorting of a SortedList
- •The Serialization Class
- •Serializing Individual Objects
- •Serializing a Collection
- •Deserializing Objects
- •Summary
- •Handling Strings and Characters
- •The Char Class
- •The String Class
- •The StringBuilder Class
- •VB.NET at Work: The StringReversal Project
- •VB.NET at Work: The CountWords Project
- •Handling Dates
- •The DateTime Class
- •The TimeSpan Class
- •VB.NET at Work: Timing Operations
- •Summary
- •Accessing Folders and Files
- •The Directory Class
- •The File Class
- •The DirectoryInfo Class
- •The FileInfo Class
- •The Path Class
- •VB.NET at Work: The CustomExplorer Project
- •Accessing Files
- •The FileStream Object
- •The StreamWriter Object
- •The StreamReader Object
- •Sending Data to a File
- •The BinaryWriter Object
- •The BinaryReader Object
- •VB.NET at Work: The RecordSave Project
- •The FileSystemWatcher Component
- •Properties
- •Events
- •VB.NET at Work: The FileSystemWatcher Project
- •Summary
- •Displaying Images
- •The Image Object
- •Exchanging Images through the Clipboard
- •Drawing with GDI+
- •The Basic Drawing Objects
- •Drawing Shapes
- •Drawing Methods
- •Gradients
- •Coordinate Transformations
- •Specifying Transformations
- •VB.NET at Work: Plotting Functions
- •Bitmaps
- •Specifying Colors
- •Defining Colors
- •Processing Bitmaps
- •Summary
- •The Printing Objects
- •PrintDocument
- •PrintDialog
- •PageSetupDialog
- •PrintPreviewDialog
- •PrintPreviewControl
- •Printer and Page Properties
- •Page Geometry
- •Printing Examples
- •Printing Tabular Data
- •Printing Plain Text
- •Printing Bitmaps
- •Using the PrintPreviewControl
- •Summary
- •Examining the Advanced Controls
- •How Tree Structures Work
- •The ImageList Control
- •The TreeView Control
- •Adding New Items at Design Time
- •Adding New Items at Runtime
- •Assigning Images to Nodes
- •Scanning the TreeView Control
- •The ListView Control
- •The Columns Collection
- •The ListItem Object
- •The Items Collection
- •The SubItems Collection
- •Summary
- •Types of Errors
- •Design-Time Errors
- •Runtime Errors
- •Logic Errors
- •Exceptions and Structured Exception Handling
- •Studying an Exception
- •Getting a Handle on this Exception
- •Finally (!)
- •Customizing Exception Handling
- •Throwing Your Own Exceptions
- •Debugging
- •Breakpoints
- •Stepping Through
- •The Local and Watch Windows
- •Summary
- •Basic Concepts
- •Recursion in Real Life
- •A Simple Example
- •Recursion by Mistake
- •Scanning Folders Recursively
- •Describing a Recursive Procedure
- •Translating the Description to Code
- •The Stack Mechanism
- •Stack Defined
- •Recursive Programming and the Stack
- •Passing Arguments through the Stack
- •Special Issues in Recursive Programming
- •Knowing When to Use Recursive Programming
- •Summary
- •MDI Applications: The Basics
- •Building an MDI Application
- •Built-In Capabilities of MDI Applications
- •Accessing Child Forms
- •Ending an MDI Application
- •A Scrollable PictureBox
- •Summary
- •What Is a Database?
- •Relational Databases
- •Exploring the Northwind Database
- •Exploring the Pubs Database
- •Understanding Relations
- •The Server Explorer
- •Working with Tables
- •Relationships, Indices, and Constraints
- •Structured Query Language
- •Executing SQL Statements
- •Selection Queries
- •Calculated Fields
- •SQL Joins
- •Action Queries
- •The Query Builder
- •The Query Builder Interface
- •SQL at Work: Calculating Sums
- •SQL at Work: Counting Rows
- •Limiting the Selection
- •Parameterized Queries
- •Calculated Columns
- •Specifying Left, Right, and Inner Joins
- •Stored Procedures
- •Summary
- •How About XML?
- •Creating a DataSet
- •The DataGrid Control
- •Data Binding
- •VB.NET at Work: The ViewEditCustomers Project
- •Binding Complex Controls
- •Programming the DataAdapter Object
- •The Command Objects
- •The Command and DataReader Objects
- •VB.NET at Work: The DataReader Project
- •VB.NET at Work: The StoredProcedure Project
- •Summary
- •The Structure of a DataSet
- •Navigating the Tables of a DataSet
- •Updating DataSets
- •The DataForm Wizard
- •Handling Identity Fields
- •Transactions
- •Performing Update Operations
- •Updating Tables Manually
- •Building and Using Custom DataSets
- •Summary
- •An HTML Primer
- •HTML Code Elements
- •Server-Client Interaction
- •The Structure of HTML Documents
- •URLs and Hyperlinks
- •The Basic HTML Tags
- •Inserting Graphics
- •Tables
- •Forms and Controls
- •Processing Requests on the Server
- •Building a Web Application
- •Interacting with a Web Application
- •Maintaining State
- •The Web Controls
- •The ASP.NET Objects
- •The Page Object
- •The Response Object
- •The Request Object
- •The Server Object
- •Using Cookies
- •Handling Multiple Forms in Web Applications
- •Summary
- •The Data-Bound Web Controls
- •Simple Data Binding
- •Binding to DataSets
- •Is It a Grid, or a Table?
- •Getting Orders on the Web
- •The Forms of the ProductSearch Application
- •Paging Large DataSets
- •Customizing the Appearance of the DataGrid Control
- •Programming the Select Button
- •Summary
- •How to Serve the Web
- •Building a Web Service
- •Consuming the Web Service
- •Maintaining State in Web Services
- •A Data-Driven Web Service
- •Consuming the Products Web Service in VB
- •Summary
THE STACK MECHANISM 829
application so that every time it runs into a ZIP file, it calls the MVFiles.bat program with the appropriate arguments and lets it process the ZIP file.
The Stack Mechanism
Now that you have seen examples of recursive programming and have a better understanding of this powerful technique, let’s look at the mechanism that makes recursion possible. I mentioned earlier that each time a procedure (function or subroutine) calls another, its status must be stored in memory so that it can later resume execution. The status of an interrupted procedure includes the location of the line where it was interrupted and the values of the local variables the moment it was interrupted. This information is enough for a procedure to resume operation and never be aware that it was interrupted.
Stack Defined
The area of memory in which the procedure’s status is stored is called the stack. The stack is a protected area of the system’s memory that’s handled exclusively by the operating system. The stack memory is regular memory, but the operating system handles it differently from the way it handles the rest of memory. For one thing, programs can’t grab any byte from the stack. The items in this memory are stacked on top of one another, and only the topmost item can be extracted.
Each time a program places a value on the stack, the new item is placed at the top of the stack. When a program reads a value from the stack, it can read only the item on top, which is the item that was placed on the stack last. This type of memory organization is called last in, first out, or LIFO. The item that is placed on the stack last is the first one to be read. This is exactly the mechanism used to pass arguments between procedures.
Recursive Programming and the Stack
If you aren’t familiar with the role of the stack in the computer’s operation, the following discussion will probably help you understand the mechanics of recursion a little better. The stack is one of the oldest models used in programming, and it’s still as useful and as popular as ever. In fact, it’s an important part of the operating system. Microprocessors provide special commands for manipulating the stack. Fortunately, you don’t have to worry about the stack, since it’s handled exclusively by the operating system and your favorite programming language. The description of the stack you’ll find in this section is a bit simplified. The goal is to explain how recursive procedures work without getting too technical.
Suppose the recursive procedure is a subroutine and it accepts no arguments, similar to the ScanFolder() subroutine. When the ScanFolder() subroutine calls itself, it must first store its status on the stack so that it can later resume. One component of the subroutine’s status is the line that was executing when the program was interrupted. The ScanFolder() subroutine calls itself from within a loop. When it resumes, it should be able to continue with the remaining loops and not start all over again. The loop’s counter, i, is part of the subroutine’s status, and it must also be stored on the stack along with all the information that makes up the function’s status.
The ScanFolder() subroutine’s status is stored on top of the stack, and the same subroutine starts executing again with a fresh set of local variables (a new loop counter, for example). When this copy
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
830 Chapter 18 RECURSIVE PROGRAMMING
of the ScanFolder() subroutine calls itself again, its status is stored on the stack on top of the status of the previously interrupted subroutine. As more instances of the same subroutine are called, the status of each is stored on top of the previously interrupted subroutine’s status. Eventually, the active ScanFolder() subroutine terminates, and the most recently interrupted one takes over. Its status is on the top of the stack. The operating system removes the values of its local variables from the stack so that the subroutine can resume execution.
What’s left on the top of the stack now is the status of the subroutine that must resume execution when the active subroutine terminates. When these values are removed from the stack, the status of another interrupted function surfaces on the stack. This simple mechanism allows procedures to interrupt each other and keep track of each other’s status without any complicated operations. Each procedure finds its status on the stack, as if no other information was ever placed on top of it.
Passing Arguments through the Stack
The same mechanism is used to pass arguments from one procedure to another. Suppose your program calls the function Payment(Amount, Interest), which expects to read two arguments (the loan amount and an interest rate) and return the monthly payment. As you know so well by now, you must supply the arguments in this order: first the amount, then the interest. The calling program leaves its status and the two arguments on the stack in the same order: first its status (the values of its local variables), then the value of the Amount argument, and finally, the value of the Interest argument. When the Payment() function takes over, it retrieves the two arguments from the top of the stack: first the value of the last argument, then the value of the first argument. After the removal of these two values from the stack, the status of the calling procedure is at the top of the stack. When the Payment() function finishes, it leaves its result on the top of the stack and relinquishes control to the calling procedure.
The calling procedure removes the value from the top of the stack (the result of the Payment() function) and uses it for its own purposes. It then removes the values of the local variables (its status) so that it can resume execution. As you can see, the LIFO structure is ideal for exchanging data between procedures.
Suppose the Payment() function calls another function. Again, the arguments of the new function are placed on the stack where the new function will find them. When the other function returns, it leaves its result on the top of the stack where the Payment() function will find it and remove it from the stack. It also finds its status information on the stack. No matter how many functions are called in such a nested manner, the information required is always at the top of the stack.
The only requirement when passing arguments through the stack is that they are placed there in the order they are needed. The procedure being called has no other means to decipher which value corresponds to which argument. That’s why these arguments are also known as positional arguments.
VB functions support named arguments as well, and you can pass arguments to them in any order, as long as you provide both the name and the value of the argument. If the Payment() function has a default interest rate, you can call it as follows: Payment(Amount:=29000). Even these procedures use the stack mechanism to pass the named arguments, but the mechanics are a bit more complicated. The basic idea is the same: The information is always placed on top of the stack, and when it’s read, it’s removed from the stack. In this way, each procedure is guaranteed to find the information it leaves on the stack the moment it needs it.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
