第 8章 过程过程是用来执行一个特定任务的一段程序代码。
VB应用程序(又称工程或项目)由若干过程组成,这些过程保存在文件中,每个文件的内容通常称为一个模块。
在程序设计过程中,将一些常用的功能编写成过程,可供多个不同的事件过程多次调用,从而可以减少重复编写代码的工作量,实现代码重用,使程序简练,便于调试和维护 。 在 VB6.0中,用户自定义过程分为:以,Sub” 保留字开始的子过程,以,Function”
保留字开始的函数过程,以,Property” 保留字开始的属性过程,以,Event” 保留字开始的事件过程 。
本章主要介绍用户自定义的子过程和函数过程 。
退出
8.1 子过程
8.2 函数过程
8.3 参数传递
8.4 过程与变量的作用域
8.5 鼠标事件和键盘事件
8.1 子过程子过程是用特定格式组织起来的一组代码,通常用来完成一个特定的功能,可以被其它过程作为一个整体来调用。
8.1.1 子过程的定义定义子过程有以下两种方法 。
1.利用“工具”菜单下的“添加过程”命令定义
2.利用代码窗口直接定义在窗体或标准模块的代码窗口把插入点放在所有现有过程之外,键入 Sub子过程名即可 。 定义一般形式如下:
[Static][Public|Private]Sub 子 过 程 名
[( 参数列表 ) ]
[局部变量或常数定义 ]
[语句序列 ]
[Exit Sub]
[语句序列 ]
End Sub
下面是一个子过程的例子:
Sub sum( x%,y%,s%)
s = x + y
End Sub
8.1.2 过程的调用要执行一个过程,必须调用该过程 。
子过程的调用有两种方式,一种是利用 Call语句加以调用,另一种是把过程名作为一个语句来直接调用 。
1.用 Call语句调用 Sub过程格式,Call 过程名 [( 参数列表 ) ]
例如,Call sum( a,b,c)
2.把过程名作为一个语句来使用格式,过程名 [参数列表 ]
与第一种调用方法相比,这种调用方式省略了关键字 Call,去掉了,参数列表,的括号 。
例如,sum a,b,c
【 例 8.2】 编一个求 n!的子过程,然后调用它计算
7! +11! -10! 。
程序如下:
Sub jch( n%,p&)
Dim i%
p = 1
For i = 1 To n
p = p * i
Next i
End Sub
Private Sub Form_Click()
Dim a&,b&,c&,d&
Call jch( 7,a)
Call jch( 11,b)
Call jch( 10,c)
d = a + b- c
Print "7!+11!-10!="; d
End Sub
8.2 函数过程函数过程是自定义过程的另一种形式 。 VB提供了许多内部函数,如 Sin( ),Sqr( ) 等,在编写程序时,只需写出函数名和相应的参数,就可得到函数值 。
另外,VB还允许用户自己定义函数过程 。 同内部函数一样,函数过程也有一个返回值 。
8.2.1 函数的定义函数过程的定义方法也有以下两种 。
1.利用“工具”菜单下的“添加过程”命令定义
2.利用代码窗口直接定义在窗体或标准模块的代码窗口把插入点放在所有现有过程之外,键入 Function函数名即可。定义形式如下:
[Static][Public|Private] Function 函数名( [参数列表 ]) [As类型 ]
[局部变量或常数定义 ]
[语句序列 ]
[Exit Function]
[语句序列 ]
函数名 =表达式
End Function
8.2.2 函数的调用调用函数过程可以由函数名带回一个值给调用程序,被调用的函数必须作为表达式或表达式中的一部分,再与其它的语法成分一起配合使用 。 因此,与子过程的调用方式不同,函数不能作为单独的语句加以调用 。
最简单的情况就是在赋值语句中调用函数过程,
其形式为:
变量名 =函数过程名 ( [参数列表 ])
【 例 8.3】 用函数过程实现对例 8-2的求解。
程序如下:
Function jch&( n%)
Dim i%
jch = 1
For i = 1 To n
jch = jch * i
Next i
End Function
Private Sub Form_Click()
Dim d&
d = jch( 7) + jch( 11)- jch
( 10)
Print "7!+11!- 10!="; d
End Sub
8.3 参数传递在调用过程时,一般主调过程与被调过程之间有数据传递,即将主调过程的实参传递给被调过程的形参,完成实参与形参的结合,然后执行被调过程体 。
在 VB中,实参与形参的结合有两种方法:传址和传值 。
传址是默认的方法 。 两种结合方法的区分标志是
,ByVal”,形参前加,ByVal” 关键字时是传值,否则为传址 。 本章前面的举例,例 8.4是传值,其余均为传址 。
8.3.1 传值传值的参数传递过程是:当调用一个过程时,系统将实参的值复制给形参,之后实参与形参便断开了联系。被调过程对形参的操作是在形参自己的存储单元中进行,当过程调用结束时,这些形参所占用的存储单元也同时被释放。因此在过程中对形参的任何操作都不会影响到实参。
8.3.2 传址传址的参数传递过程是:当调用一个过程时,它将实参的地址传递给形参 。 因此在被调过程体中对形参的任何操作都变成了对相应实参的操作,因此实参的值就会随形参的改变而改变 。 当参数是字符串或数组时,使用传址传递直接将实参的地址传递给过程,
会使程序的效率提高 。
8.3.3 数组参数的传递数组可以作为过程的参数 。 过程定义时,形参列表中的数组用数组名后的一对空的圆括号表示 。 在过程调用时,实际参数表中的数组可以只用数组名表示,
省略圆括号 。
当用数组作为过程的参数时,进行的不是,值,
的传递,而是,址,的传递 。
【 例 8.7】 用数组作参数,求一维数组中的所有负元素之和 。
程序如下:
Function sum%( b%( ))
Dim i%
For i = LBound( b) To UBound
( b)
If b( i) < 0 Then
sum = sum + b( i)
End If
Next i
End Function
Private Sub Form_Click()
Dim a%( 10),s%,i%
For i = 1 To 10
a( i) = Int( Rnd * 100) - 50
Print a( i);
Next i
Print
s = sum( a())
Print "数组中的负元素之和为,"; s
End Sub
8.4 过程与变量的作用域应用程序中的过程,变量是有作用域的 。 所谓作用域,就是过程,变量可以在哪些地方被使用 。 作用域的大小和过程,变量所处的位置及定义方式有关 。
8.4.1 过程的作用域这里只讨论窗体和标准模块文件 。
过程的作用域分为:窗体 /模块级和全局级 。
8.4.2 变量的作用域变量的作用域决定了哪些子过程和函数过程可访问该变量 。 变量的作用域分为局部变量,窗体 /模块级变量和全局变量 。 表 8-2中列出了 3种变量作用范围及使用规则 。
【 例 8.10】 通过本例学习不同作用域变量的使用 。
在 Form1窗体代码窗口输入如下程序:
Private a% '窗体 /
模块级变量
Private Sub Form_Click( )
Dim c%,s% '局部变量
c = 20
s = a + Form2.b + c '引用各级变量
Print "s="; s
End Sub
Private Sub Form_Load()
a = 10 '给窗体 /
模块级变量赋值
Form2.Show
End Sub
添加 Form2窗体,在它的代码窗口输入如下代码:
Public b% '定义全局变量
Private Sub Form_Load()
b = 30 '给全局变量赋值
End Sub
运行程序,单击 Form1窗体,结果如下:
s=60
在本例中,我们在 Form1窗体的 Click事件过程中引用了 Form2窗体中定义的全局级变量 b,由此可以看出在代码窗口“通用声明”段中用 Public定义的变量确实是在整个应用程序中起作用的。
如果将 Form1代码窗口中的 Form_Click事件过程做如下变动:
Private Sub Form_Click()
Dim c%,s%,b% '局部变量
c = 20
b = 40
s = a + b + c
Print "s="; s
End Sub
运行结果变为:
s=70
结果发生了变化。原因是在 VB中,当同一应用程序中定义了不同级别的同名变量时,系统优先访问作用域小的变量。上例改动后,系统优先访问了局部变量 b,因此结果当然也相应地改变了。如果想优先访问全局变量,则应在全局变量前加上窗体 /模块名。
8.4.3 静态变量由表 8-2中可知,局部变量除了用 Dim语句声明外,
还可用 Static语句将变量声明为静态变量,它在程序运行过程中可保留变量的值。也就是说,每次调用过程后,用 Static说明的变量会保留运行后的结果;而在过程内用 Dim说明的变量,每次调用过程结束,都会将这些局部变量释放掉。
形式如下:
Static 变量名 [As类型 ]
Static Function 函数名( [参数列表 ])
[As 类型 ]
Static Sub 过程名 [(参数列表) ]
若在函数名、过程名前加 Static,则表示该函数、
过程内的局部变量都是静态变量。
【 例 8.11】 调用函数实现变量自动增 1的功能。
程序如下:
Private Static Function s%()
Dim sum%
sum = sum + 1
s = sum
End Function
Private Sub Form_Click()
Dim i%
For i = 1 To 5
Print "第 " & i & "次结果为 " & s
()
Next i
End Sub
8.5 鼠标事件和键盘事件鼠标对于 Windows应用程序设计来说几乎是必需的,
尤其是在图形图像处理的程序设计中,显得更为重要 。
而鼠标应用的基础是鼠标事件 。 下面我们就来简单介绍一下窗体鼠标事件及其应用 。
8.5.1 鼠标事件除了单击 ( Click) 和双击 ( DblClick) 外,基本的鼠标事件还有 3个,MouseDown、
MouseUp和 MouseMove。 工具箱中的大多数控件都能响应这 3个事件 。
MouseDown:鼠标的任一键被按下时触发该事件。
MouseUp:鼠标的任一键被释放时触发该事件。
MouseMove:鼠标被移动时触发该事件。
以 Form 对象为例,它们的语法格式为:
Private Sub Form_MouseDown( Button As Integer,
Shift As Integer,X As Single,Y As Single)
Private Sub Form_MouseMove( Button As Integer,
Shift As Integer,X As Single,Y As Single)
Private Sub Form_MouseUp( Button As Integer,
Shift As Integer,X As Single,Y As Single)
【 例 8.12】 显示鼠标指针的当前位置 。
程序如下:
Private Sub Form_MouseMove
( Button As Integer,_
Shift As Integer,X As
Single,Y As Single)
Text1.Text = X
Text2.Text = Y
End Sub
运行结果如图 8-6所示 。
8.5.2 键盘事件
VB中的对象识别键盘事件,包括 KeyPress,KeyUp
和 KeyDown事件 。 用户按下并且释放一个 ANSI键时就会触发 KeyPress事件;用户按下一个键时触发 KeyDown事件,释放引发 KeyUp事件 。 在引发键盘事件的同时,用户所按的键盘码作为实参传递给相应的事件过程,供程序判断识别用户的操作 。
KeyPress只响应按下标准 ASCII字符表中对应的键时的事件,如 [Enter]QVFP,[Tab]键,[Backspace]键等以及标准键盘中的字母,标点,数字键等 。 而
KeyDown和 KeyUP则提供了最低级的键盘响应 。
它们的格式如下:
Sub Object_KeyPress( [Index As Integer,]
KeyAscii As Integer)
Sub Object_KeyDown( [Index As Integer,]
KeyCode As Integer,Shift As Integer)
Sub Object_KeyUp( [Index As Integer,]
KeyCode As Integer,Shift As Integer)
【 例 8-14】 在窗体上放一文本框,编写一事件过程,保证在该文本框内只能输入字母,且无论大小写,
都要转换成大写字母显示 。
程序如下:
Private Sub Text1_KeyPress
( KeyAscii As Integer)
Dim str$
If KeyAscii < 65 Or KeyAscii >
122 Then
Beep
KeyAscii = 0
ElseIf KeyAscii >= 65 And
KeyAscii <= 90
Then
Text1 = Text1 + Chr( KeyAscii)
Else
str = UCase( Chr( KeyAscii))
KeyAscii = 0
Text1 = Text1 + str
End If
End Sub
VB应用程序(又称工程或项目)由若干过程组成,这些过程保存在文件中,每个文件的内容通常称为一个模块。
在程序设计过程中,将一些常用的功能编写成过程,可供多个不同的事件过程多次调用,从而可以减少重复编写代码的工作量,实现代码重用,使程序简练,便于调试和维护 。 在 VB6.0中,用户自定义过程分为:以,Sub” 保留字开始的子过程,以,Function”
保留字开始的函数过程,以,Property” 保留字开始的属性过程,以,Event” 保留字开始的事件过程 。
本章主要介绍用户自定义的子过程和函数过程 。
退出
8.1 子过程
8.2 函数过程
8.3 参数传递
8.4 过程与变量的作用域
8.5 鼠标事件和键盘事件
8.1 子过程子过程是用特定格式组织起来的一组代码,通常用来完成一个特定的功能,可以被其它过程作为一个整体来调用。
8.1.1 子过程的定义定义子过程有以下两种方法 。
1.利用“工具”菜单下的“添加过程”命令定义
2.利用代码窗口直接定义在窗体或标准模块的代码窗口把插入点放在所有现有过程之外,键入 Sub子过程名即可 。 定义一般形式如下:
[Static][Public|Private]Sub 子 过 程 名
[( 参数列表 ) ]
[局部变量或常数定义 ]
[语句序列 ]
[Exit Sub]
[语句序列 ]
End Sub
下面是一个子过程的例子:
Sub sum( x%,y%,s%)
s = x + y
End Sub
8.1.2 过程的调用要执行一个过程,必须调用该过程 。
子过程的调用有两种方式,一种是利用 Call语句加以调用,另一种是把过程名作为一个语句来直接调用 。
1.用 Call语句调用 Sub过程格式,Call 过程名 [( 参数列表 ) ]
例如,Call sum( a,b,c)
2.把过程名作为一个语句来使用格式,过程名 [参数列表 ]
与第一种调用方法相比,这种调用方式省略了关键字 Call,去掉了,参数列表,的括号 。
例如,sum a,b,c
【 例 8.2】 编一个求 n!的子过程,然后调用它计算
7! +11! -10! 。
程序如下:
Sub jch( n%,p&)
Dim i%
p = 1
For i = 1 To n
p = p * i
Next i
End Sub
Private Sub Form_Click()
Dim a&,b&,c&,d&
Call jch( 7,a)
Call jch( 11,b)
Call jch( 10,c)
d = a + b- c
Print "7!+11!-10!="; d
End Sub
8.2 函数过程函数过程是自定义过程的另一种形式 。 VB提供了许多内部函数,如 Sin( ),Sqr( ) 等,在编写程序时,只需写出函数名和相应的参数,就可得到函数值 。
另外,VB还允许用户自己定义函数过程 。 同内部函数一样,函数过程也有一个返回值 。
8.2.1 函数的定义函数过程的定义方法也有以下两种 。
1.利用“工具”菜单下的“添加过程”命令定义
2.利用代码窗口直接定义在窗体或标准模块的代码窗口把插入点放在所有现有过程之外,键入 Function函数名即可。定义形式如下:
[Static][Public|Private] Function 函数名( [参数列表 ]) [As类型 ]
[局部变量或常数定义 ]
[语句序列 ]
[Exit Function]
[语句序列 ]
函数名 =表达式
End Function
8.2.2 函数的调用调用函数过程可以由函数名带回一个值给调用程序,被调用的函数必须作为表达式或表达式中的一部分,再与其它的语法成分一起配合使用 。 因此,与子过程的调用方式不同,函数不能作为单独的语句加以调用 。
最简单的情况就是在赋值语句中调用函数过程,
其形式为:
变量名 =函数过程名 ( [参数列表 ])
【 例 8.3】 用函数过程实现对例 8-2的求解。
程序如下:
Function jch&( n%)
Dim i%
jch = 1
For i = 1 To n
jch = jch * i
Next i
End Function
Private Sub Form_Click()
Dim d&
d = jch( 7) + jch( 11)- jch
( 10)
Print "7!+11!- 10!="; d
End Sub
8.3 参数传递在调用过程时,一般主调过程与被调过程之间有数据传递,即将主调过程的实参传递给被调过程的形参,完成实参与形参的结合,然后执行被调过程体 。
在 VB中,实参与形参的结合有两种方法:传址和传值 。
传址是默认的方法 。 两种结合方法的区分标志是
,ByVal”,形参前加,ByVal” 关键字时是传值,否则为传址 。 本章前面的举例,例 8.4是传值,其余均为传址 。
8.3.1 传值传值的参数传递过程是:当调用一个过程时,系统将实参的值复制给形参,之后实参与形参便断开了联系。被调过程对形参的操作是在形参自己的存储单元中进行,当过程调用结束时,这些形参所占用的存储单元也同时被释放。因此在过程中对形参的任何操作都不会影响到实参。
8.3.2 传址传址的参数传递过程是:当调用一个过程时,它将实参的地址传递给形参 。 因此在被调过程体中对形参的任何操作都变成了对相应实参的操作,因此实参的值就会随形参的改变而改变 。 当参数是字符串或数组时,使用传址传递直接将实参的地址传递给过程,
会使程序的效率提高 。
8.3.3 数组参数的传递数组可以作为过程的参数 。 过程定义时,形参列表中的数组用数组名后的一对空的圆括号表示 。 在过程调用时,实际参数表中的数组可以只用数组名表示,
省略圆括号 。
当用数组作为过程的参数时,进行的不是,值,
的传递,而是,址,的传递 。
【 例 8.7】 用数组作参数,求一维数组中的所有负元素之和 。
程序如下:
Function sum%( b%( ))
Dim i%
For i = LBound( b) To UBound
( b)
If b( i) < 0 Then
sum = sum + b( i)
End If
Next i
End Function
Private Sub Form_Click()
Dim a%( 10),s%,i%
For i = 1 To 10
a( i) = Int( Rnd * 100) - 50
Print a( i);
Next i
s = sum( a())
Print "数组中的负元素之和为,"; s
End Sub
8.4 过程与变量的作用域应用程序中的过程,变量是有作用域的 。 所谓作用域,就是过程,变量可以在哪些地方被使用 。 作用域的大小和过程,变量所处的位置及定义方式有关 。
8.4.1 过程的作用域这里只讨论窗体和标准模块文件 。
过程的作用域分为:窗体 /模块级和全局级 。
8.4.2 变量的作用域变量的作用域决定了哪些子过程和函数过程可访问该变量 。 变量的作用域分为局部变量,窗体 /模块级变量和全局变量 。 表 8-2中列出了 3种变量作用范围及使用规则 。
【 例 8.10】 通过本例学习不同作用域变量的使用 。
在 Form1窗体代码窗口输入如下程序:
Private a% '窗体 /
模块级变量
Private Sub Form_Click( )
Dim c%,s% '局部变量
c = 20
s = a + Form2.b + c '引用各级变量
Print "s="; s
End Sub
Private Sub Form_Load()
a = 10 '给窗体 /
模块级变量赋值
Form2.Show
End Sub
添加 Form2窗体,在它的代码窗口输入如下代码:
Public b% '定义全局变量
Private Sub Form_Load()
b = 30 '给全局变量赋值
End Sub
运行程序,单击 Form1窗体,结果如下:
s=60
在本例中,我们在 Form1窗体的 Click事件过程中引用了 Form2窗体中定义的全局级变量 b,由此可以看出在代码窗口“通用声明”段中用 Public定义的变量确实是在整个应用程序中起作用的。
如果将 Form1代码窗口中的 Form_Click事件过程做如下变动:
Private Sub Form_Click()
Dim c%,s%,b% '局部变量
c = 20
b = 40
s = a + b + c
Print "s="; s
End Sub
运行结果变为:
s=70
结果发生了变化。原因是在 VB中,当同一应用程序中定义了不同级别的同名变量时,系统优先访问作用域小的变量。上例改动后,系统优先访问了局部变量 b,因此结果当然也相应地改变了。如果想优先访问全局变量,则应在全局变量前加上窗体 /模块名。
8.4.3 静态变量由表 8-2中可知,局部变量除了用 Dim语句声明外,
还可用 Static语句将变量声明为静态变量,它在程序运行过程中可保留变量的值。也就是说,每次调用过程后,用 Static说明的变量会保留运行后的结果;而在过程内用 Dim说明的变量,每次调用过程结束,都会将这些局部变量释放掉。
形式如下:
Static 变量名 [As类型 ]
Static Function 函数名( [参数列表 ])
[As 类型 ]
Static Sub 过程名 [(参数列表) ]
若在函数名、过程名前加 Static,则表示该函数、
过程内的局部变量都是静态变量。
【 例 8.11】 调用函数实现变量自动增 1的功能。
程序如下:
Private Static Function s%()
Dim sum%
sum = sum + 1
s = sum
End Function
Private Sub Form_Click()
Dim i%
For i = 1 To 5
Print "第 " & i & "次结果为 " & s
()
Next i
End Sub
8.5 鼠标事件和键盘事件鼠标对于 Windows应用程序设计来说几乎是必需的,
尤其是在图形图像处理的程序设计中,显得更为重要 。
而鼠标应用的基础是鼠标事件 。 下面我们就来简单介绍一下窗体鼠标事件及其应用 。
8.5.1 鼠标事件除了单击 ( Click) 和双击 ( DblClick) 外,基本的鼠标事件还有 3个,MouseDown、
MouseUp和 MouseMove。 工具箱中的大多数控件都能响应这 3个事件 。
MouseDown:鼠标的任一键被按下时触发该事件。
MouseUp:鼠标的任一键被释放时触发该事件。
MouseMove:鼠标被移动时触发该事件。
以 Form 对象为例,它们的语法格式为:
Private Sub Form_MouseDown( Button As Integer,
Shift As Integer,X As Single,Y As Single)
Private Sub Form_MouseMove( Button As Integer,
Shift As Integer,X As Single,Y As Single)
Private Sub Form_MouseUp( Button As Integer,
Shift As Integer,X As Single,Y As Single)
【 例 8.12】 显示鼠标指针的当前位置 。
程序如下:
Private Sub Form_MouseMove
( Button As Integer,_
Shift As Integer,X As
Single,Y As Single)
Text1.Text = X
Text2.Text = Y
End Sub
运行结果如图 8-6所示 。
8.5.2 键盘事件
VB中的对象识别键盘事件,包括 KeyPress,KeyUp
和 KeyDown事件 。 用户按下并且释放一个 ANSI键时就会触发 KeyPress事件;用户按下一个键时触发 KeyDown事件,释放引发 KeyUp事件 。 在引发键盘事件的同时,用户所按的键盘码作为实参传递给相应的事件过程,供程序判断识别用户的操作 。
KeyPress只响应按下标准 ASCII字符表中对应的键时的事件,如 [Enter]QVFP,[Tab]键,[Backspace]键等以及标准键盘中的字母,标点,数字键等 。 而
KeyDown和 KeyUP则提供了最低级的键盘响应 。
它们的格式如下:
Sub Object_KeyPress( [Index As Integer,]
KeyAscii As Integer)
Sub Object_KeyDown( [Index As Integer,]
KeyCode As Integer,Shift As Integer)
Sub Object_KeyUp( [Index As Integer,]
KeyCode As Integer,Shift As Integer)
【 例 8-14】 在窗体上放一文本框,编写一事件过程,保证在该文本框内只能输入字母,且无论大小写,
都要转换成大写字母显示 。
程序如下:
Private Sub Text1_KeyPress
( KeyAscii As Integer)
Dim str$
If KeyAscii < 65 Or KeyAscii >
122 Then
Beep
KeyAscii = 0
ElseIf KeyAscii >= 65 And
KeyAscii <= 90
Then
Text1 = Text1 + Chr( KeyAscii)
Else
str = UCase( Chr( KeyAscii))
KeyAscii = 0
Text1 = Text1 + str
End If
End Sub