370 likes | 493 Views
第 8 章 过程. 过程是用来执行一个特定任务的一段程序代码。 VB 应用程序(又称工程或项目)由若干过程组成,这些过程保存在文件中,每个文件的内容通常称为一个模块。 在程序设计过程中,将一些常用的功能编写成过程,可供多个不同的事件过程多次调用,从而可以减少重复编写代码的工作量,实现代码重用,使程序简练、便于调试和维护。在 VB6.0 中,用户自定义过程分为:以“ Sub” 保留字开始的子过程、以“ Function” 保留字开始的函数过程、以“ Property” 保留字开始的属性过程、以“ Event” 保留字开始的事件过程。 本章主要介绍用户自定义的子过程和函数过程。.
E N D
第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!。 【例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】用数组作参数,求一维数组中的所有负元素之和。 【例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】通过本例学习不同作用域变量的使用。【例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窗体的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,则表示该函数、过程内的局部变量都是静态变量。若在函数名、过程名前加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】在窗体上放一文本框,编写一事件过程,保证在该文本框内只能输入字母,且无论大小写,都要转换成大写字母显示。 【例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