Seminar 1

Visual Basic -
Syntax and Program Debugging
© M. Firebaugh
Topics:
History and Background
- BASIC was invented by John Kemeny and Thomas Kurtz of Dartmouth College
- BASIC --> Beginners All-purpose Symbolic Instruction Code
- First BASIC program ran at 2 am on May 4, 1964
- In 1984 Kemeny and Kurtz wrote TrueBasic
- Our contribution was the article, "Comparative Evaluations of BASIC Systems" in Creative Computing (Firebaugh, Fossum, Sorensen, & Stone)

John Kemeny (1926-1992)
Microsoft Enters the BASIC Landscape
- Paul Allen convinced Bill Gates to write BASIC for the M.I.T.S. Altair
- This was a 4K BASIC
- Microsoft was founded and ported BASIC to the Apple, Atari, & Commodore
- Next they wrote BASICA for IBM-DOS and GW-BASIC for MS-DOS
- The success of MS BASIC interpreter led to the QuickBasic compiler
- Finally, MS married QuickBasic + an OOP GUI --> Visual Basic
- We are now at Visual Basic 6.0
Getting into Visual Basic
Our approach is to distinguish two characteristics of the language:
- Visual --> The GUI (Forms, Controls, Text boxes, Buttons, Tool boxes,...)
- Basic --> The syntax of BASIC code (That make the controls "play")
We start with BASIC and just enough "Visual" to write code and make it play. We return to GUI in Seminar 2. Remember, programming is an experimental science. We learn by doing.
1. Double click the Vb6 Icon on your desktop 
2. Double click the StandardEXE icon in the New Project Window

3. Double click the Form1 window in Project 1

4. Enter your BASIC code in the resulting Form1(Code) window

5. Run the program by clicking the Start button in the Tool Bar

Nomenclature
Naming convention (nomenclature) is an important aspect of any language. It involves:
- Reserved words (lexicon of the language, e.g., Private, Sub, For, End)
- Rules for naming constants, variables, and subprocedures
- Data Type Declarations and Recommendations on Type prefixes
- Rules for suffix definitions
- Comment lines and general code layout rules
Rules for naming constants, variables, and subprocedures
Syntax:
- They must begin with a letter.
- They can't contain embedded periods or type-declaration characters (special characters that specify a data type).
- They can be no longer than 255 characters. The names of controls, forms, classes, and modules must not exceed 40 characters.
- They can't be the same as restricted keywords (e.g., If, Abs, or OR).
Data Typing - Constants and Variables
Constants
The syntax for declaring a constant is:
[Public|Private]Const constantname [As type] = expression
Examples:
Const conPi = 3.14159265358979
Public Const conMaxPlanets As Integer = 9
Variables
To use a variable we must specify 3 quantities:
Syntax for Defining Variable Name and Type
Visual Basic offers two levels of "Typing"
- Implicit Declaration ("Weak typing")
- Explicit Declaration ("Strong typing")
Implicit Declaration
Implicit declaration occurs when variable is first used. For example:
Example 1.1
Private Sub Form_Load()
CorpName = "UNICO"
Num = 1
MsgBox CorpName & " is " & Num
End Sub
|
 |
See:
- BASIC knows what type to make CorpName and Num through usage
- Assignment of value is done using the "=".
- Output is achieved easily through use of the intrinsic function MsgBox
- Strings are concatenated using the "&" symbol
Explicit Declaration
Explicit declaration set in menu chain [Tools-->Options-->Editor-->Require variable Declaration]
Example 1.2
Option Explicit
Private Sub Form_Load()
Dim CorpName As String
Dim Num As Integer
CorpName = "UNICO"
Num = 1
MsgBox CorpName & " is " & Numb
End Sub |
 |
See:
- The variables CorpName and Num are declared appropriately
- Mis-typed variable name, Numb, is flagged by compiler
- The Option Explicit is the default condition on startup
Recommendation:
- Always use Explicit Typing to minimize errors in variable reference
While not required, it is recommended that variable names be prefixed by their data types.
Data type
|
Prefix
|
Example
|
| Boolean |
bln
|
blnFound
|
| Byte |
byt
|
bytRasterData
|
| Collection object |
col
|
colWidgets
|
| Currency |
cur
|
curRevenue
|
| Date (time) |
dtm
|
dtmStart
|
| Double |
dbl
|
dblTolerance
|
| Error |
err
|
errOrderNum
|
| Integer |
int
|
intQuantity
|
| Long |
lng
|
lngDistance
|
| Object |
obj
|
objCurrent
|
| Single |
sng
|
sngAverage
|
| String |
str
|
strFName
|
| User-defined type |
udt
|
udtEmployee
|
| Variant |
vnt
|
vntgCheckSum
|
Rules for Suffix Definition of Objects
Visual Basic Objects support suffix notation of the form:
ObjectName.Suffix
where
- Suffix --> Property of the object (i.e., an attribute)
- Suffix --> Method of the object (i.e., a subprocedure)
Standard Objects include:
CheckBox
|
ComboBox
|
CommandButton
|
MDIForm
|
Data
|
DirListBox
|
DriveListBox
|
FileListBox
|
Grid
|
Frame
|
HScrollBar
|
Image
|
Label
|
Line
|
ListBox
|
Menu
|
OptionButton
|
OLE
|
PictureBox
|
Shape
|
TextBox
|
Timer
|
VScrollBar
|
Form
|
An Example showing both Properties and Methods
Example 1.3
Option Explicit
Private Sub Form_Load()
Form1.Show
Form1.BackColor = &HDD00DD
Form1.Print Form1.BackColor
End Sub |
 |
See:
- The method Show causes Form1 to appear immediately after the Load event
- The property BackColor is assigned a hexadecimalvalue "DD00DD" (magenta)
- The method Print causes the decimal equivalent of hex DD00DD to appear in Form1.
General Code Layout Rules
Embedded Comments:
The comment symbol is the single quote ('). This symbol tells Visual Basic to ignore the words that follow it. For example:
' This is a comment beginning at the left edge of the
' screen.
Text1.Text = "Hi!" ' Place friendly greeting in text
' box.
Multiple-Line Statements
The following code is broken into three lines with line-continuation characters <space> + <Underscore> ( _):
Data1.RecordSource = _
"SELECT * FROM Titles, Publishers" _
& "WHERE Publishers.PubId = Titles.PubID" _
& "AND Publishers.State = 'CA'"
Multiple-Statement Lines
You can place two or more statements on a line if you use a colon (:) to separate them:
Text1.Text = "Hello" : Red = 255 : Text1.BackColor = _
Red
This is generally NOT recommended on readability arguments.
Visual Basic supports three Number Systems
Decimal
|
Octal
|
Hexadecimal
|
|
9
|
&O11 |
&H9
|
|
15
|
&O17 |
&HF
|
|
16
|
&O20 |
&H10
|
|
20
|
&O24 |
&H14
|
|
255
|
&O377 |
&HFF
|
Lifetime and Scope
In order to understand Lifetime and Scope of variables, it is necessary to understand Program Structure
Visual Basic code is stored in modules. Modules come in three kinds:
- form [the most common kind, with file name extension .FRM]
- standard [used for modules shared by other modules, with extension .BAS]
- class [used for user-defined objects, with extension .CLS]
Within each module are two sections:
The two main structures for building procedures:
- Sub (the syntax for SubProcedures)
- Function (the syntax for Functions)
The name of a procedure should be of mixed case and as long as necessary to describe its purpose. Function names should begin with verbs indicating their action. E.g.,
InitArray
CloseDialog
Sub Procedures
The syntax for a Sub Procedure is:
[Private|Public][Static]Sub procedurename(arguments)
statements
End Sub
Sub Procedures are Public by default (i.e., can be called from anywhere in an application). Normally, variables are local to the object in which they are defined.
Function Procedures
The syntax for a Function Procedure is:
[Private|Public][Static]Function procedurename(arguments)[As type]
statements
End Function
Function Procedures differ from Sub Procedures in three significant ways:
- Generally, you call a function by using the function name in the RHS of an expression [returnvalue = function()]
- Function procedures have data types, just as variables do.
- You return a value by assigning it to the procedurename itself.
Example:
Example 1.4
Option Explicit
Private Sub Form_Load()
Dim X As Single, Y As Single
X = 3
Y = 4
Form1.Show
Form1.Print X, Y, Hypot(X, Y)
End Sub
Function Hypot(A As Single, B As Single) As Single
Hypot = Sqr(A ^ 2 + B ^ 2)
End Function |
 |
See:
- Types of both function and arguments must be defined.
- Function name must be assigned within function.
- Function may be called with dummy arguments.
Scope specifies the spatial extent of a variable;
Lifetime specifies the time extent.
Rules for specifying scope and lifetime:
- Declaring a variable in the Declarations section of a form, standard, or class module, rather than within a procedure, makes the variable available to all the procedures in the module.
- Declaring a variable using the Public keyword makes it available throughout your application, i.e. to all modules contained in the application
- Declaring a local variable using the Static keyword preserves its value even when a procedure ends.
As an example of scope of global variables, consider the example:
Example 1.5
Module1 Code:
' Program to demonstrate GLOBAL VARIABLES
Option Explicit
Public gX As Single
Public gI As Integer
Public gName As String
Sub Main()
gX = 1999
gI = 13
gName = "July "
Scope1
End Sub
Form1 Code:
Option Explicit
Private Sub Scope1()
Form1.Show
Form1.Print gName & gI & ", " & gX
End Sub
|  |
See:
- Variables gX,gI,gName declared as global in the declaration section
- Their values are assigned in the subprocedure Main
- Their values are printed in a different subprocedure, Scope1, of Form1
- The declaration of Public makes these variables known to all modules and forms of the application, i.e. they are global variables
- If any of these variables are re-declared as Private, a "Variable not defined" error occurs.
Another rule of Scope - Local declaration wins. Consider
Example 1.6
' Program to demonstrate LOCAL CONTROL
Option Explicit
Public testVar As Integer
Sub Main()
testVar = 1999
MsgBox "In Main, testVar = " & testVar
Sub2
End Sub
Sub Sub2()
Dim testVar
MsgBox "In Sub2, Call 1 gives testVar = " & testVar
testVar = 2001
MsgBox "In Sub2, Call 2 gives testVar = " & testVar
End Sub |


|
See:
- The variable testVar is defined globally in the declaration section of the module
- It is also declared locally in the subprocedure Sub2
- Clearly, from the output, the local declaration wins.
Static Variables and LIFETIME
Example 1.7
' Program to demonstrate LIFETIME
' Using STATIC Variable
Option Explicit
Sub Main()
MsgBox "RunningTotal = " & RunningTotal(5)
MsgBox "RunningTotal = " & RunningTotal(5)
MsgBox "RunningTotal = " & RunningTotal(5)
MsgBox "RunningTotal = " & RunningTotal(5)
End Sub
Function RunningTotal(Num As Integer) As Integer
Static ApplesSold
ApplesSold = ApplesSold + Num
RunningTotal = ApplesSold
End Function
|



|
See:
- The Static ApplesSold declaration preserves the value of the variable between function calls.
- Declaring Dim ApplesSold would result in RunningTotal always returning Num
- We can apply static to all variables in a function using the static function definition:
Static Function RunningTotal(num)
Suggested Naming Conventions
One-letter prefixes help specify scope of variables.
Scope
|
Prefix
|
Example
|
Global |
g
|
GstrUserName
|
Module-level |
m
|
MblnCalcInProgress
|
Local to Procedure |
None |
dblVelocity
|
Control Structures
Edsger W. Dijkstra, of the University of Texas, has proven that the three control structures necessary and sufficient for programming are:
- Sequence
- Decision
- Iteration
We have already shown, in Examples 1.1-1.7, Sequence, i.e., one command after another.
Decision Structures in Visual Basic
There are three:
- If...Then
- If...Then...Else
- Select Case
If...Then
The syntax is:
If condition Then statement
or
If condition Then
statements
End If
The condition is typically a Boolean expression which can have values of True or False, but it can also be any expression that evaluates to a number. If the number = 0, the condition is False; if non-0 the condition is True.
Example 1.8
Option Explicit
Private Sub Form_Load()
Dim HoursWorked
HoursWorked = InputBox("Enter hours worked: ")
If HoursWorked > 40 Then
MsgBox "Overtime Pay Due!"
End If
End Sub
|

|
See:
- If the number of hours worked is greather than 40, the "Overtime Pay Due" message appears.
- If the number of hours worked is less than or equal 40, nothing happens.
- This is a "One-branch" If.
If...Then...Else
The syntax is:
If condition Then
[statementblock for True]
Else
[statementblock for False]
End If
Example 1.9
Option Explicit
Const RegularRate As Currency = 15.5
Const OvertimeRate As Currency = 23.25
Private Sub Form_Load()
Dim HoursWorked
Dim Pay As Currency
HoursWorked = InputBox("Enter hours worked: ")
If HoursWorked > 40 Then
Pay = 40 * RegularRate + (HoursWorked - 40) *
OvertimeRate
MsgBox "For " & HoursWorked & " hours,
Pay (with overtime) = $" & Pay
Else
Pay = HoursWorked * RegularRate
MsgBox "For " & HoursWorked & " hours,
Pay = $" & Pay
End If
End Sub
|

|
See:
- This is a "two-branch" If
- Sometimes called a balanced or symmetrical decision structure
- The True and False conditions are treated on an equal basis
If...Then...ElseIf
The syntax is:
If condition1 Then
[statementblock-1]
[ElseIf condition2 Then
[statementblock-2]]
...
[Else
[statementblock-n]
End If
Example 1.10
Option Explicit
Private Sub Form_Load()
Dim Score As Integer
Dim Grade As String
Score = InputBox("Enter student score ")
If Score >= 0 And Score < 50 Then
Grade = "F"
ElseIf Score >= 50 And Score < 65 Then
Grade = "D"
ElseIf Score >= 65 And Score < 80 Then
Grade = "C"
ElseIf Score >= 80 And Score < 90 Then
Grade = "B"
ElseIf Score >= 90 And Score <= 100 Then
Grade = "A"
Else
MsgBox "Illegal score. Please re-run."
Form_Load
End If
MsgBox "For a score of " & Score & ",
Course Grade = " & Grade
End Sub
|

|
See:
- This is an "n-way" or "multi-path" decision structure.
- Conditions 1...n-1 are tested until one is found True, say condition k.
- Then Basic executes the statement-k block and exits the If...Then...ElseIf statement.
- Note the use of the Else block to detect data out of range.
- Note the use of recursion (a routine calling itself) to try again for data in legal range.
- This decision structure tests up to (n-1) distinct conditions.
Select Case
The Select Case decision structure is a special case of the If...Then...ElseIf structure in which only one condition, testexpression, is computed.
The syntax for Select Case is:
Select Case testexpression
[Case expressionlist1
[statementblock-1]]
[Case expressionlist2
[statementblock-2]]
...
[Case Else
[statementblock-n]
End Select
As an example, consider:
Example 1.11
Option Explicit
Private Sub Form_Load()
Dim Month As String
Month = InputBox("What month is it? ")
Select Case Month
Case "January", "March", "May", "July",
"August", "October", "December"
MsgBox Month & " has 31 days."
Case "September", "April", "June", "November"
MsgBox Month & " has 30 days."
Case "February"
MsgBox Month & " has 28 days,
except for leap year when it has 29!"
Case Else
MsgBox "Illegal month name. Please try again."
Form_Load
End Select
End Sub
|

|
See:
- Select Case computes one test expression against which it checks several lists.
- Efficiency considerations suggest the testing order shown above.
- When agreement is found (i.e., testexpression = an element of expressionlist-k), statementblock-k is executed and the Select Case statement exited.
- The Case Else element may be used to check for valid input and recur if necessary.
Iteration
The Iteration (Loop) structures supported by Visual Basic include:
- Do...Loop
- For...Next
- For Each...Next
Syntax of the Do...Loop
Do While condition
statements
Loop
Consider the following simple example to average an arbitrary number of numbers:
Example 1.12
Option Explicit
Private Sub Form_Load()
Dim Number, Total, Average As Single
Dim N As Integer
Total = 0
N = 0
Number = InputBox("Input positive number
to average:")
Do While Number > 0
Total = Total + Number
N = N + 1
Number = InputBox("Input positive number
to average:")
Loop
Average = Total / N
MsgBox "The average of " & N &
" numbers = " & Average
End Sub
|

|
See:
- It is essential to initialize variables N and Total.
- The Do...Loop is a "top-tested" iterative structure.
- The number of iterations is determined at run-time by the user.
- The termination of iterations is by a negative number "sentinel".
Variations of the Do...Loop
Bottom-tested, "while true" loop syntax
Do
statements
Loop While condition
Top-tested, "while false" loop syntax
Do Until condition
statements
Loop
Bottom-tested, "while false" loop syntax
Do
statements
Loop Until condition
Note:
- Top-tested loops may iterate between 0 and N times (N arbitrary).
- Bottom-tested loops may iterate between 1 and N times (N arbitrary).
- Since N is arbitrary, all 4 of these are called "indefinite loops".
- Finally, the programmer must garantee that condition changes to terminate the loop.
The Historical While...Wend Loop
Syntax:
While condition
statements
Wend
Recommendation: Use Do..While rather then While..Wend which is included for compatibility with older BASICs.
Syntax of the For...Next Loop
For counter = start To end [Step increment]
statements
Next [counter]
Rules:
- The arguments counter, start, end, and increment are all numeric.
- To execute the For loop, Visual Basic
1. Sets counter equal to start.
2. Tests to see if counter is greater than end. If so, exit loop.
3. Executes the statements.
4. Increments counter by 1 (or by increment if specified)
5. Repeats steps 2 to 4.
Example 1.13
Option Explicit
Private Sub Form_Load()
Dim I As Integer
Form2.Show
Print "This system supports " &
Screen.FontCount & " Fonts."
Print "They are:" & vbCrLf
For I = 0 To Screen.FontCount
Print Screen.Fonts(I)
Next
End Sub
|

|
See:
- The method Screen.FontCount returns the number of system fonts as an integer
- The For loop uses this integer as the (definite) end point of the loop
- When the programmer knows the number of iteration, the definite loop is preferred.
Syntax of For Each...Next Loop
This loop is similar to the For...Next loop, but instead of iteration it performs a group of statements to each element in a collection of object or an array.
For Each element In group
statements
Next [element]
Example 1.14
Option Explicit
Private Sub cmdBackground_Click()
Dim nColor As Long
Dim FormControl As Control
dlgColors.ShowColor
nColor = dlgColors.Color
For Each FormControl In frmColors.Controls
If TypeOf FormControl Is TextBox And
chkTextBoxes.Value = 1
Then FormControl.BackColor = nColor
If TypeOf FormControl Is Frame And
chkFrames.Value = 1
Then FormControl.BackColor = nColor
If TypeOf FormControl Is Label And
chkLabels.Value = 1
Then FormControl.BackColor = nColor
If TypeOf FormControl Is CheckBox And
chkCheckBoxes.Value = 1
Then FormControl.BackColor = nColor
Next
Exit Sub
End Sub
Private Sub cmdForeground_Click()
Dim nColor As Long
Dim FormControl As Control
dlgColors.ShowColor
nColor = dlgColors.Color
For Each FormControl In frmColors.Controls
If TypeOf FormControl Is TextBox And
chkTextBoxes.Value = 1
Then FormControl.ForeColor = nColor
If TypeOf FormControl Is Frame And
chkFrames.Value = 1
Then FormControl.ForeColor = nColor
If TypeOf FormControl Is Label And
chkLabels.Value = 1
Then FormControl.ForeColor = nColor
If TypeOf FormControl Is CheckBox And
chkCheckBoxes.Value = 1
Then FormControl.ForeColor = nColor
Next
Exit Sub
End Sub
Private Sub cmdQuit_Click()
' Quit application by unloading the form
Unload frmColors
End Sub
|


|
See:
- This example uses 1 form, 2 frames, 3 textboxes, 4 checkboxes, and 3 command boxes: all VB controls to which we return in Seminar 2.
- The essential element of this program is the common dialog control, dlgColors, which allows us to bring up the color dialog box and select a color.
- Once nColor is selected, the For Each...Next loop takes over and checks all 16 controls for its type and whether the checkbox for this type is true.
- If the type agrees and the checkbox is checked, it sets the control property to nColor.
Program Debugging
Rapid and efficient application development requires powerful and transparent debugging tools. Visual Basic provides a useful set of such tools. However, a few simple rules of good program design will minimize the need for debugging tools. These include:
- Pick good mnemonics (e.g., NoBblsOil rather than N or NB).
- Use strong typing (e.g., Option Explicit)
- Use top-down design (e.g., break up large problems into small modules)
- Pass arguments to subprocedures by value rather than by reference
How do "pass by value" and "pass by reference" differ? Consider the example of pass by reference (the VB default):
Example 1.15
Option Explicit
' Pass argument BY REFERENCE (VB Default)
Sub Main()
Dim Salary As Currency
Salary = 50000
MsgBox "Your salary is now $" & Salary
IRS Salary
MsgBox "Your salary is now $" & Salary
End Sub
Sub IRS(Dollars As Currency)
Dollars = 0.6 * Dollars
End Sub
|

|
See:
- The Main program passes your salary to the IRS by reference (the VB default)
- The IRS performs an operation on it, reducing it by 40%
- The reduced amount is returned to Main and you're in big trouble!
Example 1.16
Option Explicit
' Pass argument BY VALUE
Sub Main()
Dim Salary As Currency
Salary = 50000
MsgBox "Your salary is now $" & Salary
IRS Salary
MsgBox "Your salary is now $" & Salary
End Sub
Sub IRS(ByVal Dollars As Currency)
Dollars = 0.6 * Dollars
End Sub
|

|
See:
- The Main program passes your salary to the IRS by value
- The IRS performs an operation on it, reducing it by 40%, but keeping it in the IRS
- The Main program never hears of the reduction, and you're in the clear!
Recommendation:
Clearly distinguish between INPUT parameters and OUTPUT parameters to subprocedures
- Pass INPUT parameters BY VALUE
- Pass OUTPUT parameters BY REFERENCE
- This protocol greatly reduces unwanted SIDE EFFECTS, a.k.a "bugs"
- It is also consistent with the trend towards OOP
O.K., but my program's still bombing. Now what do I do?
- Use the On Error command
- Use the Immediate Window
- Use the Watch Window
- Use Single Stepping through your code
- Use Breakpoints
On Error Command
The user can take the initiative to trap and interpret program errors:
Example 1.17
Sub Main()
Dim X As Single
On Error GoTo ErrorHandler
X = Log(-1)
Exit Sub
ErrorHandler:
MsgBox Str(Err.Number) & ": "
& Err.Description & " Error"
End Sub
|
 |
See:
- When error occurs, programmer maintains control.
- The program doesn't just "bomb" as usually occurs in error conditions.
- Can use this control to print error message, value of variables, and so on.
The Immediate Window 
The "Immediate Window" is an interactive, line-at-a-time programming scratch pad to test out elements of your program. You open it with <CTRL>+ G
Example 1.18
|
|
See:
- Note: X had no value (from Example 1.17) because of lifetime.
- However, printing the error line trips the system error we detected in Ex. 1.17.
- With the Immediate Window you can test each element of your program.
- Immediate Window supports only individual lines. Multiple statements must be tested by stringing them together with (:).
The Watch Window 
The Watch Window displays the contents of any variable, property or expression you wish to monitor. In addition, you can halt the program upon a given condition.
Example 1.19
|
|
See:
- Under [Debug] we opened the Watch Window.
- We then selected and dragged both variables, I and X, to the Watch Window
- Then we selected the Edit Watch in [Debug] and set the expression I = 10
- Finally, we selected "Break When Value Is True" in Edit Watch.
- Running the program produced the results shown.
Stepping Through Code 
The ultimate debug procedure is to single-step the program, examining the value of variables and expressions as each command is executed. Visual Basic provides two modes: Step Into (using F8) and Step Over (using <SHFT>+F8). Step Into follows program execution into called subprocedures; Step Over doesn't.
Setting Break Points 
In programs which are large, complex, or contain large loops, Break Points are essential for efficient debugging. Break points are easily inserted by position the cursor and clicking the Toggle Breakpoint icon.
Example 1.20
|
|
See:
- Breakpoints may be inserted anywhere in the program.
- You can hop quickly from one breakpoint to the next with the run icon.
- You can move slowly between breakpoints using Single Step.
- All debug tools are most effective when used together, i.e., using the Watch and Immediate Windows to examine variables at breakpoints.
References:
Wright, Peter, Beginning Visual Basic 6, WROX PressLtd., Birmingham, UK (1998)
Wang, Wallace, Visual Basic 4 for Windows for Dummies, IDG Books, Foster City, CA (1995)
Connell, John, Beginning Visual Basic 6 Database Programming, WROX PressLtd., Birmingham, UK (1998)
Stephens, Rod, Visual Basic Graphics Programming, John Wiley & Sons, Inc., New York (1997)
Firebaugh, Morris, Computer Graphics - Tools for Visualization, Wm. C. Brown Publishers, Dubuque, IA (1993)
Microsoft, MSDN (Microsoft Developers Network) Help Files