-
由于 Microsoft Windows 的图形特性,图形和其它操作的显示速度在很大程度上决定了应用程序的感觉速度。窗体出现及画图的速度越快,应用程序就会显得越快。以下的几种技术可用来提高应用程序的显示速度:
将容器的 ClipControls 属性设置为 False。
恰当地使用 AutoRedraw。
使用 Image 控件替代 PictureBox 控件。
设置属性时隐藏控件以避免多次重画。
使用 Line 替代 PSet。
将容器的 ClipControls 属性设置为 False
除非正在使用图形方法(Line,Pset,Circle 和 Print),否则将窗体、框架及 PictureBox 控件的 ClipControls 设置为 False(如果代码包含了在其它控件之后绘图的图形方法,则这可能导致不可预测的结果)。当 ClipControls 设置为 False 时,在重画控件本身之前,Visual Basic 不会用背景覆盖控件。这在窗体包含大量控件时,会大大提高显示速度。
详细信息 请参阅“使用文本和图形”中的“使用 AutoRedraw 和 ClipControls 使图形分层”。
恰当地使用 AutoRedraw
当窗体或控件的 AutoRedraw 设置为 True 时,Visual Basic 会利用位图重画该窗体或控件。这种方法虽然提高了简单情况的重画速度(例如,在删除覆盖在窗体或控件上的窗口后,窗体或控件重新显示),但会降低图形方法的速度。此时,Visual Basic 就会在 AutoRedraw 位图上进行图形方法操作,再把整个位图复制到屏幕上。这个过程也占用了相当数量的内存。
如果应用程序产生的图形复杂但是不常改变,AutoRedraw 设置为 True 较为合适。如果图形需要经常改变,则 AutoRedraw 设置为 False 的效果更好,并且在 Paint 事件中进行窗体或控件的图形方法操作。
详细信息 请参阅“使用文本和图形”中的“使用 AutoRedraw 和 ClipControls 使图形分层”。
用 Image 控件替代 PictureBox 控件
优化能够提高应用程序的速度,并减小其大小,所以要尽量应用优化技术。如果仅简单显示图片,并只对单击事件和鼠标操作作出响应,应使用 Image 控件替代 PictureBox。除非需要图片框提供的特殊功能时,如图形方法、包含其它控件的能力或动态数据交换 (DDE),否则不要使用图片框。
设置属性时隐藏控件以避免多次重画
重画的代价是昂贵的。重画的操作越少,应用程序就显得越快。减少重画次数的一种方法,就是操作控件时使其不可见。例如,假设在窗体的 Resize 事件中调整数个列表框的大小:
Sub Form_Resize ()
Dim i As Integer, sHeight As Integer
sHeight = ScaleHeight / 4
For i = 0 To 3
lstDisplay(i).Move 0, i * sHeight, _
ScaleWidth, sHeight
Next
End Sub
该示例产生四次独立的重画,每个列表框一次。把所有的列表框放在图片框中,并在移动或调整列表框大小之前隐藏图片框,就会减少重画的次数。当再次使图片框可见时,所有的列表框一次画出:
Sub Form_Resize ()
Dim i As Integer, sHeight As Integer
picContainer.Visible = False
picContainer.Move 0, 0, ScaleWidth, ScaleHeight
sHeight = ScaleHeight / 4
For i = 0 To 3
lstDisplay(i).Move 0, i * sHeight, _
ScaleWidth, sHeight
Next
picContainer.Visible = True
End Sub
值得注意的是,该示例中使用了 Move 方法替代设置 Top 和 Left 属性。Move 方法只需一次操作就设置了这两个属性,所以节省了多余的重画。
使用 Line 替代 PSet
使用 Line 比使用一系列的 PSet 方法快。避免使用 Pset 方法,把一些点组成一条线由 Line 方法一次画出。一般来说,简单、不常改变的图形元素采用形状和直线控件来处理比较合适;而复杂的或经常改变的图形则最好采用图形方法处理。
-
优化显示速度
由于 Microsoft Windows 的图形特性,图形和其它操作的显示速度在很大程度上决定了应用程序的感觉速度。窗体出现及画图的速度越快,应用程序就会显得越快。以下的几种技术可用来提高应用程序的显示速度:
将容器的 ClipControls 属性设置为 False。
恰当地使用 AutoRedraw。
使用 Image 控件替代 PictureBox 控件。
设置属性时隐藏控件以避免多次重画。
使用 Line 替代 PSet。
将容器的 ClipControls 属性设置为 False
除非正在使用图形方法(Line,Pset,Circle 和 Print),否则将窗体、框架及 PictureBox 控件的 ClipControls 设置为 False(如果代码包含了在其它控件之后绘图的图形方法,则这可能导致不可预测的结果)。当 ClipControls 设置为 False 时,在重画控件本身之前,Visual Basic 不会用背景覆盖控件。这在窗体包含大量控件时,会大大提高显示速度。
详细信息 请参阅“使用文本和图形”中的“使用 AutoRedraw 和 ClipControls 使图形分层”。
恰当地使用 AutoRedraw
当窗体或控件的 AutoRedraw 设置为 True 时,Visual Basic 会利用位图重画该窗体或控件。这种方法虽然提高了简单情况的重画速度(例如,在删除覆盖在窗体或控件上的窗口后,窗体或控件重新显示),但会降低图形方法的速度。此时,Visual Basic 就会在 AutoRedraw 位图上进行图形方法操作,再把整个位图复制到屏幕上。这个过程也占用了相当数量的内存。
如果应用程序产生的图形复杂但是不常改变,AutoRedraw 设置为 True 较为合适。如果图形需要经常改变,则 AutoRedraw 设置为 False 的效果更好,并且在 Paint 事件中进行窗体或控件的图形方法操作。
详细信息 请参阅“使用文本和图形”中的“使用 AutoRedraw 和 ClipControls 使图形分层”。
用 Image 控件替代 PictureBox 控件
优化能够提高应用程序的速度,并减小其大小,所以要尽量应用优化技术。如果仅简单显示图片,并只对单击事件和鼠标操作作出响应,应使用 Image 控件替代 PictureBox。除非需要图片框提供的特殊功能时,如图形方法、包含其它控件的能力或动态数据交换 (DDE),否则不要使用图片框。
设置属性时隐藏控件以避免多次重画
重画的代价是昂贵的。重画的操作越少,应用程序就显得越快。减少重画次数的一种方法,就是操作控件时使其不可见。例如,假设在窗体的 Resize 事件中调整数个列表框的大小:
Sub Form_Resize ()
Dim i As Integer, sHeight As Integer
sHeight = ScaleHeight / 4
For i = 0 To 3
lstDisplay(i).Move 0, i * sHeight, _
ScaleWidth, sHeight
Next
End Sub
该示例产生四次独立的重画,每个列表框一次。把所有的列表框放在图片框中,并在移动或调整列表框大小之前隐藏图片框,就会减少重画的次数。当再次使图片框可见时,所有的列表框一次画出:
Sub Form_Resize ()
Dim i As Integer, sHeight As Integer
picContainer.Visible = False
picContainer.Move 0, 0, ScaleWidth, ScaleHeight
sHeight = ScaleHeight / 4
For i = 0 To 3
lstDisplay(i).Move 0, i * sHeight, _
ScaleWidth, sHeight
Next
picContainer.Visible = True
End Sub
值得注意的是,该示例中使用了 Move 方法替代设置 Top 和 Left 属性。Move 方法只需一次操作就设置了这两个属性,所以节省了多余的重画。
使用 Line 替代 PSet
使用 Line 比使用一系列的 PSet 方法快。避免使用 Pset 方法,把一些点组成一条线由 Line 方法一次画出。一般来说,简单、不常改变的图形元素采用形状和直线控件来处理比较合适;而复杂的或经常改变的图形则最好采用图形方法处理。
-
优化代码
除非应用程序是用来产生分形图形的,否则应用程序看上去并不受限于代码的实际处理速度。其它典型的因素,如显示速度、网络延迟或磁盘操作,才是应用程序速度的限制因素。比如,导致窗体加载慢的原因,是窗体上控件和图形的个数太多,而不是由于 Form_Load 事件中的代码太慢。尽管如此,代码本身的速度也可以成为限制应用程序速度的瓶颈,特别是经常调用到的例程。这种情况下,可采用以下的几种技术来优化应用程序的真实速度。
避免使用 Variant 变量。
使用 Long integer 变量和整数运算。
将常用的属性缓存在变量中。
使用内嵌过程替代过程调用。
尽可能使用常数。
用 ByVal 传递参数,而不用 ByRef。
使用类型确定的可选参数。
利用集合的优点。
即使您并不想优化代码的速度,这也有助于了解这些技术及其基本原则。而且,一旦养成选择高效率算法作为代码的习惯,就可以从总体上大大改善应用程序的速度。
避免使用 Variant 变量
Variant 变量是 Visual Basic 中的缺省变量。这对于初学者以及处理速度不成问题的应用程序来说,是非常方便的。然而,如果想优化应用程序的实际速度,就要避免使用 Variant 变量。因为,运行时 Variant 将转化为其它适当的数据类型,那么直接采用其它简单的数据类型,就会避免不必要的操作而加快应用程序的速度。
避免使用 Variant 变量的一种好办法是使用 Option Explicit 语句,此时所有的变量都必须声明。要使用“Option Explicit”,就要在“工具”菜单中启动“选项”对话框,选择“编辑器”选项卡,选定“要求变量声明”复选框。
在声明多个变量时要小心:如果没有用 As type 子句,它们实际上被声明为 Variant 变量。在下面的例子中,X 和 Y 是 Variant 变量:
Dim X, Y, Z As Long
重写上面的语句,则三个变量为 Long 变量:
Dim X As Long, Y As Long, Z As Long
详细信息 关于 Visual Basic 数据类型的详细信息,请参阅“编程基础”中的“数据类型”。
使用 Long 整型变量和整数运算
算术运算中要避免使用 Currency、Single 和 Double 变量;并尽量使用 Long 整型变量,尤其在循环体中。因为 Long 整数是 32 位 CPU 的本机数据类型,所以其操作非常快;如果无法使用 Long 变量,就要尽量使用 Integer 或 Byte 数据类型。很多时候,即使在要求使用浮点数的情况下,也可以使用 Long 整数。例如,在窗体和图形控件的 ScaleMode 属性设置为缇或象素时,就可以在控件和图形方法中使用 Long 整型变量表示大小和位置。
进行除法运算时,如果不需要小数部分,就可以使用整数除法运算符 (/)。由于浮点运算需要转移到协处理器上进行,而整数运算并不需要,所以整数运算总是比浮点运算快。如果确实需要做小数运算,则 Double 数据类型比 Currency 数据类型快。
下表把各种数值数据类型按运算速度顺序列出。
数值数据类型 速度
Long 最快
Integer .
Byte .
Single .
Double .
Currency 最慢
将常用的属性缓存在变量中
变量的访问和设置速度比属性快。如果经常用到某一属性的值(如在循环体中),可以在循环体外把该属性值赋给某一变量,以后用该变量替代该属性,这样就能够提高代码的速度。一般来说,变量的处理速度比同类型的属性处理速度快 10 到 20 倍。
除非知道属性已经改变,否则在过程中就无需再次读取该属性值。可以把属性值赋予某一变量,然后在以后的代码中使用该变量。例如,象这样的代码就非常慢:
For i = 0 To 10
picIcon(i).Left = picPallete.Left
Next I
下面改写的代码就要快得多:
picLeft = picPallete.Left
For i = 0 To 10
picIcon(i).Left = picLeft
Next I
同样地,像这样的代码 . . .
Do Until EOF(F)
Line Input #F, nextLine
Text1.Text = Text1.Text + nextLine
Loop
. . . 比下面的代码慢得多:
Do Until EOF(F)
Line Input #F, nextLine
bufferVar = bufferVar + nextLine
Loop
Text1.Text = bufferVar
然而,下面的代码完成了相同的功能,而且还要快:
Text1.Text = Input(F, LOF(F))
如上述,几种方法都实现了同样的任务;同时,最好的算法也是最优的。
同样的技术可用于处理函数的返回值。缓存函数的返回值,避免经常调用运行时的动态链接库 (DLL),Msvbvm60.dll。
使用内嵌过程替代过程调用
采用过程调用使代码更具有模块化的风格,但模块调用总是增加额外的操作和处理时间。如果循环体中多次调用某一过程,就可以直接把该过程写到循环体中去,以消除过程调用时的额外负担。但另一方面,直接把某一过程写到好几个循环体中时,重复的代码无疑要增加应用程序的大小;同时,在更改程序时,有可能忘记更改这些重复的代码,这就增加了出错的机会。
尽可能使用常数
使用常数可以加快应用程序的运行,增强代码的可读性,而且易于维护。如果代码中的字符串或数字是不变的,则可把它们声明为常数。常数在编译时只处理一次,将适当的值写进 -
优化
优化具有科学和艺术两重含义。从科学角度看,优化意指具体的优化技术;而从艺术角度看,优化指的是确定在什么地方、什么时候需要优化。由此,优化可定义为“通过选择和设计数据结构、算法以及指令序列,来提高程序效率(更小、更快)的过程”。
有关优化的一个普遍存在的误解是,认为只是在应用程序开发周期的最后阶段才进行优化。而实际上,为了创建真正优化的应用程序,就必须在开发时实行优化。一般来说,优化的过程为:仔细选择算法,并在速度、大小等诸多限制因素间进行权衡,初步估计应用程序各个部分的速度和大小,再在以后的开发过程中检验上述假设。
优化的第一步是确定优化目标。优化可以从以下几个方面进行:
真实速度(应用程序实际计算或操作的速度)。
显示速度(应用程序屏幕显示的速度)。
感觉速度(应用程序运行时给人的感觉速度,它往往和显示速度有关,但并不总是和真实速度相关)。
占用内存的大小。
图形大小(这直接影响占用内存的大小,而且工作在 Microsoft Windows 中时往往会产生其它影响)。
一般来说,不可能在几个方面同时得到优化。一个经过大小优化的应用程序往往会降低其速度;相应的,经过速度优化的应用程序则会增加其大小。由此可见,实现不同目标的优化技术往往是相抵触的。
值得注意的是,优化并不总是完全有益的。加快或降低应用程序的速度,可能导致维护或调试方面的困难;还有些优化技术与结构化的程序设计相矛盾,这在将来扩充应用程序的功能或把它嵌入其它程序时会产生麻烦。
在确定应用程序优化策略时,有三方面的问题值得考虑:优化什么、在何处优化及何时结束优化。
优化什么:理解实际问题
如果没有明确的优化目标,就会因为方向错误而浪费大量的时间。优化的目标是为了满足用户的需求。例如,速度对于计算销售税的应用程序来说就至关重要,而对于可以从 Internet 上下载的应用程序,则其大小倍受关注。所以,正确理解优化所要解决的问题所在,是确定优化策略的关键。
即使已经确定了某一优化目标,仍需在开发过程中全面考虑优化。在编写代码时,一步一步地浏览代码,仔细思考其实际发生的情况,则会帮助了解很多东西。例如,设置属性会产生许多事件,而恰好这些事件过程中有大量的代码,则无谓的设置属性语句会导致程序执行时的巨大延迟。有时优化即便是针对大小的,仍然可以在不增加大小的前提下实现速度的优化。
在何处优化:事半功倍
绝大部分的开发者不可能对应用程序的所有地方都进行优化。增加时间等于增加开发成本,所以有必要进行“优化预算”。哪些地方能够花一些时间换取最大的投资回报呢?显然,那些速度慢、代码冗长的地方最需要优化,把精力花在这样的地方就会有事半功倍的效果。
例如,速度是主要目标,则循环体往往是开始优化的好地方。一旦循环体内的操作得到加快,则该优化会被放大,倍数是循环体执行的次数。对于有大量重复的循环,减少循环体内的一个字符串操作,结果就会有很大的不同。同样的规律也可以应用于经常调用的子程序。
何时结束优化:效果的衡量
有时一些东西并不值得优化。例如,为了十几个项目的排序而编写一个精致的快速排序程序是没有意义的。一种排序的方法是把项目加到排序列表框中,再把它们按排好的顺序读出来。如果项目的数量巨大,则该方法效率极低;但对于少量的项目,该方法与其它方法的效率一样,而且代码出奇地简单(只是有点难解)。
在一些情况下,优化纯属浪费。如果应用程序的运行受到驱动器或网络速度的限制,则对代码的任何优化都无助于速度的提高。此时,就应设法减少因延迟而造成对用户的影响:如利用进度栏提示当前应用程序的运行状况,或利用高速缓存减小延迟,或放弃控制,这样用户在等待时可以运行其它的应用程序,等等。
详细信息 请参阅“响应鼠标和键盘事件”中的“中断后台处理”。
-
坐标系统概述
本章描述的每一个图形操作(包括调整大小、移动和绘图),都要使用绘图区或容器的坐标系统。虽然用坐标系统能达到成功的图形效果,然而,如何用坐标系统定义窗体和控件在应用程序中的位置,也是很重要的。
坐标系统是一个二维网格,可定义屏幕上、窗体中或其它容器中(如:图片框或 Printer 对象)的位置。使用窗体中的坐标,可定义网格上的位置:
(x, y)
x 值是沿 x 轴点的位置,最左端是缺省位置 0。y 值是沿 y 轴点的位置,最上端是缺省位置 0。该坐标系统的图示在图 12.3 中。
图 12.3 窗体的坐标系统
以下规则用于 Visual Basic 坐标系统:
当移动控件或调整控件的大小时,使用控件容器的坐标系统。如果直接在窗体上绘制对象时,窗体就是容器。如果在框架或图片框里绘制控件时,框架或控件是容器。
所有的图形和 Print 方法,使用容器的坐标系统。例如,那些在图片框里绘制控件的语句,使用的是控件的坐标系统。
一些用来调整窗体大小或移动窗体的语句,用缇来表示窗体的位置和大小。
当创建用来调整窗体大小或移动窗体的代码时,应先检查 Screen 对象的 Height 属性和 Width 属性,以确保窗体在屏幕上大小合适。
屏幕的左上角总是(0,0)。任何容器的缺省坐标系统,都是由容器的左上角(0,0)坐标开始。
沿这些坐标轴定义位置的测量单位,统称为刻度。在 Visual Basic 中,坐标系统的每个轴都有自己的刻度。
坐标轴的方向、起点和坐标系统的刻度,都是可以改变的,但是,对现在来说,使用的是缺省系统。本章后面的“改变对象的坐标系统”中将讨论如何改动。
缇的解释
所有 Visual Basic 的移动、调整大小和图形绘制语句,根据缺省规定,使用缇为单位。缇是打印机的一磅的 1/20(1,440 缇等于一英寸;567 缇等于一厘米)。这些测量值指示对象打印后的大小。屏幕上的物理实际距离根据监视器的大小变化。“改变对象的坐标系统”中描述了如何选择缇以外的单位。
-
检测 SHIFT、CTRL及 ALT 键的状态 - [VB学习]
2004-04-03
检测 SHIFT、CTRL及 ALT 键的状态
鼠标和键盘事件用 shift 参数判断是否按下了 SHIFT、CTRL 和 ALT 键,以及以什么样的组合(如果存在)按下这些键。如果按 SHIFT 键,则 shift 为 1;如果按 CTRL 键,则 shift 为 2;如果按 ALT 键,则 shift 为 4。应使用这些键值的总和来判断这些组合。例如,同时按下 SHIFT 和 ALT 键时 shift 等于 5 (1 + 4)。
如图 11.5 所示,shift 中的三个最不明显位对应 SHIFT、CTRL 和 ALT 键的状态。
图 11.5 位如何表示 SHIFT、CTRL 和 ALT 键的状态
根据 SHIFT、CTRL 和 ALT 键的状态可在 shift 中设置任一位或设置所有位。下表列出这些值和常数:
二进制值 十进制值 常数 意义
001 1 vbShiftMask 按 SHIFT 键。
010 2 vbCtrlMask 按 CTRL 键。
100 4 vbAltMask 按 ALT 键。
011 3 vbShiftMask + vbCtrlMask 按 SHIFT 键和 CTRL 键。
101 5 vbShiftMask + vbAltMask 按 SHIFT 键和 ALT 键。
110 6 vbCtrlMask + vbAltMask 按 CTRL 键和 ALT 键。
111 7 vbCtrlMask + vbAltMask + vbShiftMask 按 SHIFT、CTRL 和 ALT 键。
象对鼠标事件的 button 参数那样,可将 If匱hen匛lse 语句或 And 操作符与 Select Case 语句组合使用以判断是否按下 SHIFT、CTRL 和 ALT 键以及以什么样的组合(若存在)按下这些键。
打开一个新工程并将变量 ShiftTest 添加到窗体的声明部分:
Dim ShiftTest as Integer
将下列代码添加到窗体的 MouseDown 事件中:
Private Sub Form_MouseDown(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
ShiftTest = Shift And 7
Select Case ShiftTest
Case 1 ’ 或 vbShiftMask
Print "You pressed the SHIFT key."
Case 2 ’或 vbCtrlMask
Print "You pressed the CTRL key."
Case 4 ’或 vbAltMask
Print "You pressed the ALT key."
Case 3
Print "You pressed both SHIFT and CTRL."
Case 5
Print "You pressed both SHIFT and ALT."
Case 6
Print "You pressed both CTRL and ALT."
Case 7
Print "You pressed SHIFT, CTRL, and ALT."
End Select
End Sub
-
将工程编译成本机代码 - [VB学习]
2004-04-03
将工程编译成本机代码
如果拥有 Visual Basic 的专业版或企业版,既可以将代码编译成标准的 Visual Basic 伪代码格式,也可以编译成本机代码格式。本机代码编译提供了伪代码编译所没有的关于优化和调试的几个选项。
P-code 或伪代码,是介于 Basic 程序中的高级指令和计算机处理器执行的低级本机代码之间的一种中间步骤。在运行时刻,Visual Basic 将每一句伪代码转换成本机代码。如果将程序直接编译成本机代码,则取消了伪代码这一中间步骤。
可以使用象在 Visual C++ 中提供的调试环境之类的标准的本机代码调试工具来调试编译后的本机代码。也可以使用例如在 Visual C++ 的语言中提供的优化和调试本机代码的选项。例如,可以根据代码运行速度和大小优化代码。
注意 所有用 Visual Basic 创建的工程都使用运行时 DLL (MSVBVM60.DLL) 服务。在 DLL 所提供的服务当中有您应用程序的启动和关闭代码、窗体和内部控件的功能,以及像 Format 和 CLng 的运行时函数。
用“本机代码”选项来编译工程意味着您写的代码将完整地编译为处理器芯片的本地指令,而不是编译为p-code。这将大大加速循环和数学计算,并可以加速对 MSVBVM60.DLL提供的服务程序的调用。然而,这并不能减少对 DLL 的需要。
要将工程编译成本机代码,请按照以下步骤执行:
在“工程”窗口,选择希望编译的工程。
从“工程”菜单选择“工程属性”。
在“工程属性”对话框,单击“编译”选项卡。
图 8.6 在“工程属性”对话框中的“编译”选项卡
选择“编译为本机代码”。
Visual Basic 提供几个选项用于定制和优化可执行文件。例如,当希望创建以代码大小为优化目标的编译代码时,可选择“小代码优化”选项。
如使用附加的高级优化选项,单击“高级优化”按钮。
选择所希望的选项,然后单击“确定”。
从“文件”菜单选择“制作 Exe”或者“生成工程组”。
下表描述本机代码优化选项。
选项 描述
禁止别名引用(高级优化) 通知编译器应用程序不使用别名引用。选择本选项将允许编译器实施优化,如将变量存储在寄存器中并且实现循环优化。
创建 Symbolic Debug Info 产生 .pdb 文件和 .exe 或 .dll 文件,其中包含允许用 Microsoft Visual C++ 5.0 或其它兼容调试器进行调试的信息。
支持 Pentium Pro(tm) 优化代码,使其支持在 Pentium Pro(tm) 处理器上运行。
不优化 取消所有的优化。
快速代码优化 通知编译器侧重于运行速度而非代码大小进行优化,使 .exe 和 .dll 文件的速度达到最快。
小代码优化 通知编译器侧重于代码大小而非运行速度进行优化,使 .exe 和 .dll 文件的大小达到最小。
取消数组边界检查(高级优化) 禁用 Visual Basic 的数组边界检查。
取消浮点数错误检查(高级优化) 禁用 Visual Basic 的浮点数错误检查。
取消整数溢出检查(高级优化) 禁用 Visual Basic 的整数溢出检查。
取消 Pentium(tm) FDIV 安全性检查(高级优化) 禁用对 Pentium(tm) 处理器浮点数除法的安全检查。
详细信息 关于本机代码选项的详细信息,请参阅“本机代码编译器开关”。
-
可用性设计
任何应用程序的可用性基本上由用户决定。界面设计是需多次反复的过程;在为应用程序设计界面时,第一步就设计出非常完美的界面的情况非常少见。用户参与设计过程越早,化的气力越少,创建的界面越好、越可用。
什么是好的界面
设计用户界面时,开始时最好是先看看 Microsoft 或其他公司的一些卖得很好的应用程序。毕竟,界面很差的应用程序不会卖得很好。将会发现许多通用的东西,比如:工具栏、状态条、工具提示、上下文菜单以及标记对话框。Visual Basic 具有把所有这些东西添加到应用程序中的能力,这并不偶然。
也可以凭借自己使用软件的经验。想一想曾经使用过的一些应用程序,哪些可以工作、哪些不可以、以及如何修改它。但要记住个人的喜好不等于用户的喜好,必需把自己的意见与用户的意见一致起来。
还要注意到大多数成功的应用程序都提供选择来适应不同的用户的偏爱。例如,Microsoft Windows“资源管理器”允许用户通过菜单、键盘命令或者拖放来复制文件。提供选项会扩大应用程序的吸引力,至少应该使所有的功能都能被鼠标和键盘所访问。
Windows 界面准则
Windows 操作系统的主要的优点就是为所有的应用程序提供了公用的界面。知道如何使用基于 Windows 的应用程序的用户,很容易学会使用其他应用程序。而与已创建的界面准则相差太远的应用程序不易让人明了。
菜单就是这方面很好的例子—大多数基于 Windows 的应用程序都遵循这样的标准:“文件”菜单在最左边,然后是“编辑”、“工具”等可选的菜单,最右边是“帮助”菜单。如果说 Documents 会比 File 更好,或者“帮助”菜单要放在最前,这就值得讨论一下了。没有任何事情阻止您这样做,但这样做会引起用户的混淆,降低应用程序的可用性。每当在应用程序与其他程序之间切换时,用户都不得不停下来想一想。
子菜单的位置也很重要。用户本期望在“编辑”菜单下找到“复制”、“剪切”与“粘贴”等子菜单,若将它们移到“文件”菜单下会引起用户的混乱。不要偏离已经创建的准则太远,除非有很好的理由这样做。
可用性的检测
测试界面可用性的最好方法是在整个设计过程中请用户参与。不论是正在设计大型的压缩包应用程序,还是小型的有限使用的应用程序,设计的过程应当完全相同。使用已创建的设计准则,界面设计应从纸上开始。
下一步是创建一个或者多个原型,在 Visual Basic 中设计窗体。还需要增加足够的代码来启动原型:显示窗体、用示例数据填充列表框等等。然后准备可用性测试。
可用性测试可以是个不拘形式的过程:与用户一道审查设计;也可以是在已创建的可用性实验室中进行的正式的过程。这两种方法目的是一样的:从用户那儿了解哪儿设计得很好,哪儿还需要改进的第一手材料。放开,让用户与应用程序在一起,然后观察它们;这种方式比询问用户更为有效。当用户试图完成一系列任务时让他们表达其思考过程:“要想打开新文档,所以要在‘文件’菜单中找一找。”记下哪些地方的界面设计没有反应他们的思考过程。与不同类型的用户一起测试,如果发现用户完成某个特定的任务有困难,该任务可能需要多加关照。
下一步,复查一下记录,考虑如何修改该界面使它更加可用。修改界面并再测试。一旦对应用程序可用性满意,就准备开始编码。在开发的过程中也需要不时地测试来确保对原型的设想是正确的。
功能的可发现性
可用性测试的关键的概念是可发现性。如果用户不能发现如何使用某个功能(或者甚至不知道有此功能存在),则此功能很少有人去使用。例如,Windows 3.1 的大多数用户都从来不知道 ALT 和 TAB 的组合键可以用于在打开的应用程序之间切换。界面中没有任何地方可提供线索来帮助用户发现这一功能。
为了测试功能的可发现性,不解释如何做就要求用户完成一个任务(例如,使用“窗体模板”创建新文档)。如果他们不能完成这个任务,或者尝试了好多次,则此功能的可发现性还需要改进。
-
界面设计的基础
不必成为创建用户界面的艺术家-大多数用户界面设计的原则,与任意一门基础艺术课中所讲授的基础设计的原则相同。构图、颜色等的基本的设计原则,就象它们应用在纸张或油画上一样,也能很好地在一台计算机的屏幕上应用。
虽然 Visual Basic 能通过简单地将控件拖动并放置到窗体上而使得创建用户界面非常容易,但是,在设计之前稍微计划一下就能使应用程序的可用性有很大的改观。可能须先在纸上画出窗体开始设计,决定需要哪些控件,不同元素的相对重要性,以及控件之间的关系。
构图:应用程序的观感与感觉
窗体的构图或布局不仅影响它的美感,而且也极大地影响应用程序的可用性。构图包括诸如控件的位置、元素的一致性、动感、空白空间的使用、以及设计的简单性等因素。
控件的位置
在大多数界面设计中,不是所有的元素都一样重要。仔细地设计是很有必要的,以确保越是重要的元素越要很快地显现给用户。重要的或者频繁访问的元素应当放在显著的位置上,而不太重要的元素就应当降级到不太显著的位置上。
在大多数语言中我们习惯于在一页之中从左到右、自上到下地阅读。对于计算机屏幕也如此,大多数用户的眼睛会首先注视屏幕的左上部位,所以最重要的元素应当放在屏幕的左上部位。例如,如果窗体上的信息与客户有关,则它的名字字段应当显示在它能最先被看到的地方。而按钮,如“确定”或“下一个”,应当放置在屏幕的右下部位;用户在未完成对窗体的操作之前,通常不会访问这些按钮。
把元素与控件分成组也很重要。尽量把信息按功能或关系进行逻辑地分组。因为他们的功能彼此相关,所以定位数据库的按钮应当被形象地分成一组,而不是分散在窗体的四处。对信息也是一样,名字字段与地址通常分在一组,因为它们联系紧密。在许多情况下,可以使用框架控件来帮助加强控件之间的联系。
界面元素的一致性
在用户界面设计中,一致性是一种优点。一致的外观与感觉可以在应用程序中创造一种和谐,任何东西看上去都那么协调。如果界面缺乏一致性,则很可能引起混淆,并使应用程序看起来非常混乱、没有条理、价值降低,甚至可能引起对应用程序可靠性的怀疑。
为了保持视觉上的一致性,在开始开发应用程序之前应先创建设计策略和类型约定。诸如控件的类型、控件的尺寸、分组的标准以及字体的选取等设计元素都应该在事先确定。可以创建设计样板来帮助进行设计。
在 Visual Basic 中有大量的控件可供使用,这可能引起有人想使用所有的控件。为了避免这种引诱,选取能很好地适合特定应用程序的控件子集。虽然列表框、组合框、网格以及树等控件都可用来表示信息列表,最好还是尽可能使用一种类型。
还有,尽量恰当地使用控件,虽然 TextBox 控件可以设置成只读并用来显示文本,但 Label 控件通常更适用于该目的。在为控件设置属性时请保持一致性,如果在一个地方为可编辑的文本使用白色背景,除非有很好的理由,否则不要在别的地方又使用灰色。
在应用程序中不同的窗体之间保持一致性对其可用性有非常重要的作用。如果在一个窗体上使用了灰色背景以及三维效果,而在另一个窗体上使用白色背景,则这两个窗体就显得毫不相干。选定一种类型并在整个应用程序保持一致,即使这意味着要重新设计某些功能。
动感:窗体与其功能匹配
动感是对象功能的可见线索。虽然对这个术语也许还不熟悉,但动感的实例四处可见。自行车上的把手,手放在它的上面,动感会将把手用手扣紧这件事显现出来。按下按钮、旋转旋钮和点亮电灯的开关等都能进行动感表示— 一看到它们就可以看出其用处。
用户界面也使用动感。例如,用在命令按钮上的三维立体效果使得他们看上去象是被按下去的。如果设计平面边框的命令按钮的话,就会失去这种动感,因而不能清楚地告诉用户它是一个命令按钮。在有些情况下,平面的按钮也许是适合的,比如游戏或者多媒体应用程序;只要在整个应用程序中保持一致就很好。
文本框也提供了一种动感,用户可以期望带有边框和白色背景的框,框中包含可编辑的文本。显示不带边框的文本框 (BorderStyle = 0) 也有可能,这使它看起来象一个标签,并且不能明显地提示用户它是可编辑的。
空白空间的使用
在用户界面中使用空白空间有助于突出元素和改善可用性。空白空间不必非得是白色的-它被认为是窗体控件之间以及控件四周的空白区域。一个窗体上有太多的控件会导致界面杂乱无章,使得寻找一个字段或者控件非常困难。在设计中需要插入空白空间来突出设计元素。
各控件之间一致的间隔以及垂直与水平方向元素的对齐也可以使设计更可用。就象杂志中的文本那样,安排得行列整齐、行距一致,整齐的界面也会使其容易阅读。
Visual Basic 提供了几个工具,使得控件的间距、排列和尺寸的调整非常容易。“排列”、“按相同大小制作”、“水平间距”、“垂直间距”和“在窗体中央”等命令都可以在“格式”菜单中找到。
保持界面的简明
界面设计最重要的原则也许就是简单化。对于应用程序而言,如果界面看上去很难,则可能程序本身也很难。稍稍深入考虑一下便 -
各种显示类型的设计
Microsoft Windows 是与设备无关的-基于窗口的应用程序可以在许多不同显示分辨率与颜色浓度的计算机中运行。同样,用 Visual Basic 编写的应用程序也会在不同类型的显示器上运行,在设计应用程序时需要考虑到这一点。
设计与分辨率无关的窗体
缺省情况下,当改变屏幕分辨率时,Microsoft Visual Basic 不会改变窗体与控件的尺寸。这就意味着在分辨率为 1024 X 768 的屏幕上设计的窗体,在分辨率为 640 X 480 的屏幕中运行时会伸出屏幕的边界之外。如果想创建不管使用什么样的屏幕分辨率都能有相同比例的窗体和控件,必须在最低的分辨率下设计窗体,或者将改变窗体的代码添加到程序中去。
避免尺寸问题的最简单的方法是在 640 X 480 的分辨率下设计窗体。如果更喜欢在高一些的分辨率下工作,仍需要考虑窗体在低一些的分辨率下将如何显示。实现这一点的方法是用“Form Layout”窗口预览窗体的大小和位置。您也可以使用“Resolution Guides”观察在低分辨率时屏幕的哪些部分是可见的。要切换到“Resolution Guides”,可以在“Form Layout”窗口单击鼠标右键,从弹出菜单上选择“Resolution Guides”菜单项。
在运行时,Visual Basic 根据设计时的位置来放置窗体。如果设计时在 1024 X 768 的分辨率上运行,并把窗体放到屏幕的右下角,则当它在比较低的分辨率下运行时该窗体可能看不见。为了避免这种情况的发生,在设计时可从“Form Layout”窗口的弹出菜单选择“Startup Position”菜单项来设置窗体的启动位置。同样,您也可以在运行时用下面的 Form Load 事件中的代码来设置窗体的位置:
Private Sub Form_Load()
Me.Move 0, 0
End Sub
若是设置窗体的 Left 与 Top 的属性都为 0 也能有同样的效果,但 Move 方法只要一步就能完成。
Visual Basic 使用与设备无关的度量单位,缇,是用来计算尺寸与位置。Screen 对象的两个属性 TwipsPerPixelX 与 TwipsPerPixelY 可以用来确定运行时的显示尺寸。应用这些属性,可以编写代码来调整窗体以及控件的尺寸与位置。
Private Sub SetControls()
Dim X As Integer
Dim Y As Integer
X = Screen.TwipsPerPixelX
Y = Screen.TwipsPerPixelY
Select Case X, Y
Case 15, 15
’ 重新改变控件尺寸及移动控件。
txtName.Height = 200
txtName.Width = 500
txtName.Move 200, 200
’ 增加为其它分辨率编写的代码。
…
End Sub
也需要知道在设计时 Visual Basic 自身窗口的位置。如果在高分辨率下把“工程”窗口放置到屏幕的右边,那么会发现在低分辨率下打开工程时,它不再是可访问的了。
设计不同浓度的颜色
在设计应用程序时,也需要考虑运行应用程序计算机可能的颜色显示能力。有些计算机可以显示 256 色或更多的颜色,而另一些只能显示 16 种颜色。如果使用 256 色的调色板来设计窗体,那么在 16 色上显示时,抖动(模仿无效颜色的一种方法)会使窗体上的一些元素消失。
为了避免这种情况,最好把应用程序使用的颜色局限于 Windows 标准的 16 颜色。这些颜色由 Visual Basic 的颜色常数来表示(如 vbBlack、vbBlue 和 vbCyan 等等)。如果在应用程序中需要用 16 种以上的颜色,那么对于文本、按钮以及其他界面元素仍然应当坚持用标准颜色。
-
编程中最常使用的三种界面设置: - [VB学习]
2004-04-03
编程中最常使用的三种界面设置:
单文档界面
多文档界面
资源管理器界面 -
在应用程序中使用 DLL 过程 - [VB学习]
2004-04-03
在应用程序中使用 DLL 过程
由于 DLL 过程存在于 Visual Basic 应用程序之外的文件中,在使用时必须指定过程的位置和调用参数。可以用 Declare 语句提供这类信息。在声明了 DLL 过程之后,可以把它当做 Visual Basic 自己的过程使用。
重点 如果在 Visual Basic 中直接调用 DLL,那么 Visual Basic 环境下固有的安全机制将受到不利影响。这意味着在测试和调试程序时可能会遇到更多的系统故障。为了减少这种危险,在声明 DLL 过程、传递参数和指定类型的时候务必要小心。无论在什么情况下,一定要经常保存已经完成的工作。DLL 可以提供不同凡响的功能,但是要用好它也不容易。
下例将演示如何调用 Windows API 中的过程。调用函数 SetWindowText 来改变一个窗体的标题栏。当然,在实际应用中,通常总是利用 Visual Basic 的 Caption 属性来改变标题栏。该示例的目的在于说明如何声明并调用过程。
声明 DLL 过程
首先,在模块的声明部分对过程进行声明:
Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" (ByVal hwnd As Long, _
ByVal lpString As String) As Long
过程的精确语法定义可以用 API Viewer 应用程序找到,在 Win32api.txt 文件中也可以找到它。如果将 Declare 放在 Form 或者 Class 模块内,那么必须在它的前面加上 Private 关键字。同一个 DLL 过程在一个工程中只需声明一次;然后可以任意调用。
详细信息 关于如何声明语句,请参阅本章后面的“声明 DLL 过程”主题。
调用 DLL 过程
在声明了函数之后,调用它的方式与标准的 Visual Basic 函数相同。在下例中,Form Load 事件调用了上面声明的过程。
Private Sub Form_Load()
SetWindowText Form1.hWnd, "Welcome to VB"
End Sub
在运行这段代码时,函数首先使用 hWnd 属性确定要修改标题栏的窗口(Form1.hWnd),然后将标题栏修改为“Welcome to VB”。
需要牢记的是:Visual Basic 不能验证传递到 DLL 过程的值是否正确。如果传递了错误的值,那么过程将出错,并可能因此导致 Visual Basic 应用程序停止运行。这样就不得不重新加载和启动应用程序。在测试 DLL 过程时千万要小心,一定要经常地保存自己的工作。
注意 极少数 API 调用能够识别缺省的 Variant 数据类型。最好声明具体的变量类型并使用 Option Explicit,这样,API 的可靠性要高得多。
-
VB编程基础教程二十六 - [VB学习]
2004-04-03
第28楼
创建对象
创建对象的最简单方法是在“工具箱”中双击控件。但是,对 Visual Basic 中的所有可用对象以及来自其它应用程序的所有可用对象,要想充分体现它们的优势,可在运行时用 Visual Basic 的可编程性能创立对象。
用对象变量创建对象引用。
用类模块“从零开始”创建自己的对象。
用集合对象创建自己的集合。
详细信息 其它章节会介绍如何访问对象。例如,在“用部件编程”中将讨论 CreateObject 和 GetObject 函数。
使用对象变量
除了存储值以外,变量可引用对象。如同给变量赋值一样,基于下列相同理由,可把对象赋给变量:
变量名往往比变量所含的值(或者,在此情况下,所含值就是它们引用的对象)短而好记。
在运行代码时,为了引用其它对象,应改变变量。
引用包含对象的变量比反复引用对象本身有更高的效率。
使用对象变量与使用常规变量一样,只不过多了把对象赋予变量这一步:
首先声明变量:
Dim variable As class
然后把对象赋予变量:
Set variable = object
声明对象变量
声明对象变量的方法和声明其它变量一样,要用 Dim、ReDim、Static、Private 和 Public。仅有的不同在于可选的 New 关键字和 Class 参数,本章后面将会对 New 关键字和 Class 参数都作介绍。语法是:
{Dim | ReDim | Static | Private | Public} variable As [New] class
例如,可以声明一个对象变量,它引用应用程序中的被称做 frmMain 的窗体:
Dim FormVar As New frmMain ’声明一个类型为 frmMain
’的对象变量。
也可以声明一个对象变量,它引用应用程序中的任何窗体:
Dim anyForm As Form ’一般窗体变量。
类似地,可以声明一个对象变量,它能够引用应用程序中的任何文本框:
Dim anyText As TextBox ’可以引用任何文本框
’(但只能是一个文本框)。
还可以声明一个对象变量,它能够引用任何类型的控件:
Dim anyControl As Control ’一般控件变量。
注意,可以声明一个引用应用程序中的指定窗体的窗体变量,但不能声明引用特定控件的控件变量。可以声明能够引用控件的特定类型(如 TextBox 或列表框)的控件变量,但不是引用那种类型的一个特定控件(如 txtEntry 或 List1)。但是,可把特定的控件赋予那种类型的变量。例如,对于具有列表框 lstSample 的窗体可以这样编码:
Dim objDemo As ListBox
Set objDemo = lstSample
赋值对象变量
用 Set 语句将对象赋予对象变量:
Set variable = object
无论何时,只要希望对象变量引用对象,就可使用 Set 语句。
有时可用对象变量,尤其可用控件变量直接缩短要键入的代码。例如,原来的代码是这样的:
If frmAccountDisplay!txtAccountBalance.Text < 0 Then
frmAccountDisplay!txtAccountBalance.BackColor = 0 frmAccountDisplay!txtAccountBalance.ForeColor = 255
End If
如果使用控件变量,程序就可显著缩短:
Dim Bal As TextBox
Set Bal = frmAccountDisplay!txtAccountBalance
If Bal.Text < 0 Then
Bal.BackColor = 0
Bal.ForeColor = 255
End If
特定对象类型与一般对象类型
特定的对象变量必须引用特定类型的对象或类。特定的窗体变量只能引用应用程序中的一个窗体(尽管可在该窗体的诸多实例中引用其中之一)。与此相似,特定的控件变量只能引用应用程序中的特定类型的控件,比如 TextBox 或者列表框。请看一例,打开新的工程,在窗体中放置一文本框。将下列代码添加到窗体中:
Private Sub Form_Click ()
Dim anyText As TextBox
Set anyText = Text1
anyText.Text = "Hello"
End Sub
运行应用程序并单击窗体。文本框的 Text 属性将变成 "Hello"。
一般对象变量可在多种特定对象类型中引用其中一种。例如,一般窗体变量可引用应用程序中的任何窗体;一般控件变量可引用应用程序中任何窗体上的任何控件。请看一例,打开新的工程并在窗体中按任意顺序放置若干 Frame、Label 和 CommandButton 控件。将下列代码添加到窗体中:
Private Sub Form_Click ()
Dim anyControl As Control
Set anyControl = Form1.Controls (3)
anyControl.Caption = "Hello"
End Sub
运行程序并单击窗体。刚才放入窗体中的第三个控件的标题将变成 "Hello"。
Visual Basic 中有四种一般对象:
一般对象类型 可引用的对象
Form 应用程序中的任何窗体(包括 MDI 子窗体和 MDI 窗体)。
Control 应用程序中的任何控件。
MDIForm 应用程序中的 MDI 窗体(如果应用程序有 MDI 窗体的话)。
Object 任何对象。
在不知道变量运行时是否引用特定类型的对象时,一般对象变量是很有用的。例如,如果要书写代码,并使之在应用程序的任何窗体中都可操作,则必须使用一般窗体变量。
注意 由于应用程序中只能有一个 MDI 窗体,因此不必使用一般的 MDIForm -
VB编程基础教程二十五 - [VB学习]
2004-04-03
对象之间的关系
在同一窗体上放置两个命令按钮时,它们是两个具有不同 Name 属性设置值(Command1 和 Command2)的分开的对象,但都分享同一个类— 命令按钮。
它们也共享这样一个特征,即它们在同一窗体上。在本章前面已看到,窗体上的控件也包含在窗体中。这就把控件放在一个层次上。要引用控件就必须先引用窗体,就如同打电话拨号一样,首先要拨国家/地区号码或区域号码,然后再拨具体的电话号码。
这两个命令按钮也共享这样一个特征,即它们都是控件。所有控件都具有公共特性,使它们不同于窗体以及 Visual Basic 环境中的其它对象。以下章节中将说明 Visual Basic 如何用集合使相关的对象分组。
对象的层次
对象层次提供了一种组织结构,它决定了对象间的相互关系以及访问它们的方法。在大多数情况下不必考虑 Visual Basic 对象的层次。但是:
在操作其它应用程序的对象时,应当熟悉那个应用程序的对象层次。关于定位对象层次的信息,请参阅“用部件编程”。
在使用数据访问对象时,应当熟悉数据访问对象层次。就象在 Professional Features 一书上的《数据访问对象指南》部分描述的那样,该书包括在 Visual Basic 的专业版和企业版中。
在 Visual Basic 中,一个对象包含其它对象的一般情况时有发生。 下面我们要详细讨论。
使用对象集合
集合对象有自己的属性和方法。对象集合中的对象作为集合的成员被引用。集合中的每个成员从 0 开始顺次编号;这就是成员的索引号。例如,控件集合包含已给定窗体上的所有控件 ,如图 5.10 所示。如果对集合中的所有对象都必须执行相同操作,则可用集合简化代码。
图 5.10 控件集合
例如,下列代码遍历控件集合,并在列表框中列出每个成员的名字。
Dim MyControl as Control
For Each MyControl In Form1.Controls
’把每个控件的名字送到列表框。
List1.AddItem MyControl.Name
Next MyControl
应用集合成员的属性与方法
有两种通用方法可用来对集合对象成员寻址:
指定成员的名称。以下两个表达式等价:
Controls ("List1")
Controls!List1
利用成员的索引号:
Controls (3)
一旦能够从整体上对全体成员寻址,而且还能够个别地对单个成员寻址,就可用下面随便一种方式应用属性和方法:
’将 ListBox 控件的 Top 属性设置为 200。
Controls!List1.Top = 200
-或者-
Dim MyControl as Control
For Each MyControl In Form1.Controls ()
’将每一个成员的 Top 属性设置为 200。
MyControl.Top = 200
Next MyControl
包含其它对象的对象
在 Visual Basic 中,一些对象包含其它对象。例如,窗体通常包含一个或数个控件。把一个对象当作其它对象的容器,这样做的好处在于,在代码中引用容器即可明了要使用哪个对象。例如,图 5.11 说明在一个应用程序中可有两个不同的窗体,一个用来输入应付帐交易,另一个用来输入应收帐交易。
图 5.11 两个不同窗体可以包含同名的控件
两个窗口可以有名为 IstAcctNo 的列表框。通过引用包含列表框的窗体就可准确指定要使用的列表框:
frmReceivable.lstAcctNo.AddItem 1201
-或者-
frmPayable.lstAcctNo.AddItem 1201
Visual Basic 中的公共集合
在 Visual Basic 中一个对象包含其它对象的一般情况时有发生。下表简要叙述 Visual Basic 中最常用的集合。
集合 描述
Forms 包含载入的窗体。
Controls 包含窗体上的控件。
Printers 包含可用的打印机对象。
在 Visual Basic 中也可实现对象控制。
详细信息 关于对象容器的详细信息,请参阅“再论编程”中的“使用集合替代数组”。关于打印机集合的信息,参阅“使用文本和图形”。关于窗体集合和控件集合的详细信息,请参阅语言参考。
容器属性
在窗体内,可用 Container 属性改变对象的容器。以下控件可包含其它控件:
Frame 控件
PictureBox 控件
ToolBar 控件(仅对专业版和企业版而言)
如何在窗体上将命令按钮从一个容器移动到另一个容器,该例对此作了演示。打开新工程,并在窗体上画出 Frame 控件、PictureBox 控件和 CommandButton 控件。
下列代码在窗体单击事件中,这些代码使计数器变量增加,并通过 Select Case 循环使命令按钮在容器之间移动。
Private Sub Form_Click ()
Static intX as Integer
Select Case intX
Case 0
Set Command1.Container = Picture1
Command1.Top= 0
Command1.Left= 0
Case 1
Set Command1.Container = Frame1
Command1.Top= 0
Command1.Left= 0
Case 2
Set Command1.Container = Form1
Command1.Top= 0
Command1.Left= 0
End Select
intX = intX + 1
End Sub
详细信息 请参阅语言参考中的“Container 属性”。
对象之间的通讯
除了在 Visual Basic 中使用和创建对象外,还可与其它应用程序通讯并在自己的应用程序中操作其它应用程序的对象。在应用 -
VB编程基础教程二十四 - [VB学习]
2004-04-03
使用对象初步
Visual Basic 对象支持属性、方法和事件。在 Visual Basic 中,称对象的数据(设置和属性)为属性,称各种可在对象上操作的过程为方法。事件是可被对象识别的动作,例如单击鼠标和按下键盘键,还可编写代码来响应事件。
改变对象的属性就可改变对象的特性。用收音机打比方,收音机的一个属性是音量。用 Visual Basic 的行话来说,就是收音机有个“Volume”属性,改变其值就可调节音量大小。假定收音机的音量值可设置在 0 到 10 之间。 如果能够通过 Visual Basic 控制收音机,则可在一个过程中写代码,把“Volume”属性值从 3 提高到 5,使声音更响一些:
Radio.Volume = 5
除了属性以外,对象还有方法。方法和属性都是对象的一部分。一般说来,方法就是要执行的动作,而属性就是要设置或检索的特性。以拨号打电话为例。可以说电话有一个“拨号”方法,拨一个 7 位电话号码的语法就是:
Phone.Dial 5551111
对象还有事件。当对象的某方面有变动时就触发了事件。例如,收音机可能有“VolumeChange”事件。电话可能有“Ring”事件,等等。
用属性控制对象
个别属性随着可以设置和取得它们的值的时间不同而不同。有的属性可在设计时设置。可在“属性”窗口设置这些属性的值而无需编写任何代码。而有的属性在设计时是不可用的;因此,这些属性只有通过代码在运行时设置。
在运行时可以设置并可获得值的属性叫做读写属性。在运行时只能读取的属性叫做只读属性。
设置属性值
在想改变对象的外观或特性时设置属性的值。例如,通过改变 TextBox 控件的 Text 属性,就可以改变文本框的内容。
用下列语法设置属性值:
object.property = expression
下面是设置属性的语句:
Text1.Top = 200 ’ 设置 Top 属性为 200 缇。
Text1.Visible = True ’ 显示文本框。
Text1.Text = "hello" ’ 在文本框中显示 "hello"。
读取属性值
想要在代码执行附加动作(例如给另一个对象赋值)之前得知对象的状态,这时就要读取属性值。例如,在运行代码之前能够返回 TextBox 控件的 Text 属性值,以确定文本框的内容,这里,代码可能改变值。
在大多数情况下可以用以下语法获得属性值:
variable = object.property
属性值可以作为较复杂的表达式的一部分,而不必将属性赋予变量。下面的代码计算控件数组中的一个新成员的 Top 属性,它等于前一个成员的 Top 属性加上 400。
Private Sub cmdAdd_Click ()
’ [语句]
optButton (n).Top = optButton (n-1).Top + 400
’ [语句]
End Sub
提示 如果不只一次使用一个属性值,而且将这个值存储到一个变量中,则代码执行起来会更快。
用方法来执行动作
方法能够影响属性值。例如在用收音机打比方的例子中,SetVolume 方法改变了 Volume 属性。与此类似,在 Visual Basic 中列表框具有 List 属性,而 Clear 和 AddItem 方法可以改变这一属性。
在代码中使用方法
在代码中使用方法时如何书写语句,这取决于该方法要求多少参数,以及是否返回一个值。如果方法不要求参数,则用以下语法编写代码:
object.method
下例中,用 Refresh 方法重画图片框:
Picture1.Refresh ’ 强迫重画控件。
有些方法,如上面的 Refresh ,既无参数又不返回值。
如果方法要用多个参数,就用逗号将它们分开。例如, Circle 方法就要用代表窗体上圆的位置、半径和颜色的参数:
’ 画一个半径为 1200 缇的蓝色园。
Form1.Circle (1600, 1800), 1200, vbBlue
如果要保存方法的返回值,就必须把参数用括号括起来。例如, GetData 方法从剪贴板返回一张图片:
Picture = Clipboard.GetData (vbCFBitmap)
如果没有返回值,则参数不会出现在括号中。例如,AddItem 方法没有返回值。
List1.AddItem "yourname" ’ 在列表框中添加 "yourname"。
详细信息 关于 Visual Basic 对所有方法提供的语法和参数,请参阅语言参考。
-
VB编程基础教程二十三 - [VB学习]
2004-04-03
用对象能做什么
对象可提供现成代码,省却书写麻烦。例如,可以自己创建打开文件和保存文件的对话框,但实际上大可不必。取而代之的是利用 Visual Basic 提供的 CommonDialog 控件(一个对象)。虽然用户也能撰写日程管理和资源管理的程序,但也大可不必。在此亦可使用 Microsoft Project 提供的 Calendar、Resources 和 Task 对象。
Visual Basic 可以组合来自其它来源的对象
Visual Basic 提供了把来自不同资源的对象组合起来的工具。现在可把 Visual Basic 的各种强有力的特性以及支持自动化(先前以 OLE 自动化闻名)的应用程序结合起来,建立定制的解决方法。自动化是部件对象模式 (COM) 的一个特性,它是应用程序使用的工业标准,用来陈列对象以开发工具和其它应用程序。
可把 Visual Basic 内部的控件结合在一起,也可使用其它应用程序提供的对象。考虑把下列对象放入 Visual Basic 窗体:
Microsoft Excel Chart 对象
Microsoft Excel Worksheet 对象
Microsoft Word Document 对象
可用这些对象建立如图 5.9 所示的支票簿应用程序。由于不必书写代码,重建已由 Microsoft Excel 和 Word 等对象提供的功能,因而节省很多时间。
图 5.9 利用其它应用程序的对象
-
VB编程基础教程二十二 - [VB学习]
2004-04-03
使用对象
在 Visual Basic中创建应用程序之际,也就是和对象打交道之时了。可以使用 Visual Basic 提供的对象— 比如控件、窗体和数据访问对象。也可以在一个 Visual Basic 应用程序内部控制另一个应用程序对象。甚至还可建立自己的对象,定义它们的属性和方法。
以下主题将详细讨论对象:
对象是什么 介绍对象的基本概念。
用对象能做什么 讨论应用程序中使用对象的几种方法。
使用对象初步 介绍对象的属性和方法。
对象之间的关系 讨论对象的层次、集合和容器。
创建对象 讨论在运行时如何创建和使用对象。
对象是什么
对象是代码和数据的组合,可以作为一个单位来处理。对象可以是应用程序的一部分,比如可以是控件或窗体。整个应用程序也是一个对象。下表列出了在 Visual Basic 中可能用到的几种类型的对象:
示例 描述
命令按钮 窗体上的控件,象命令按钮和框架,它们都是对象。
窗体 Visual Basic 工程中的每一个窗体都是独立的对象。
数据库 数据库是对象,并且还包含其他对象,如字段、索引等。
图表 Microsoft Excel 中的图表是对象。
对象从何而来
Visual Basic 中的每个对象都是用类定义的。用饼干模子和饼干之间的关系作比,就会明白对象和它的类之间的关系。饼干模子是类。它确定了每块饼干的特征,比如大小和形状。用类创建对象。对象就是饼干。
下面再用两个例子进一步说明 Visual Basic 中类与对象之间的关系。
在 Visual Basic 的“工具箱”上,控件代表类。直到在窗体上画出这些被称作控件的对象为止,它们实际上并不存在。在创建控件之时也就是在复制控件类,或建立控件类的实例。这个类实例就是应用程序中引用的对象。
在设计时操作的窗体是类。在运行时,Visual Basic 建立窗体的类实例。
“属性”窗口显示 Visual Basic 应用程序中的对象的类和 Name 属性,如图 5.8 所示。
图 5.8 “属性”窗口中显示的对象和类名
把对象看作是类的原原本本的复制品,从而建立所有对象。一旦它们以单个对象的形式存在,属性就可改变。例如,如果在窗体上画了三个命令按钮,则每个命令按钮对象都是命令按钮类的实例。 每个对象都具有一组由类定义的公共的特征和功能(属性、方法和事件)。但是,每个对象都有自己的名字,都能分别设置成有效或无效,都能放在窗体的不同位置,等等。
为简单起见,本章之外的大部分内容将不过多引用对象的类。例如,只要记住术语“ListBox 控件”意味着“列表框类的一个实例”。
-
VB编程基础教程二十一 - [VB学习]
2004-04-03
使用控制结构
嵌套控制结构
可以把控制结构放入另一个控制结构之内(例如在 For...Next 循环中的 If...Then 块)。一个控制结构内部包含另一个控制结构叫做 nest(嵌套)。
在 Visual Basic 中,控制结构的嵌套层数没有限制。按一般习惯,为了使判定结构和循环结构更具可读性,总是用缩排方式书写判定结构或循环的正文部分。
例如,下面的过程要把打印机和屏幕共有的字体名全部打印出来:
Private Sub Form_Click ()
Dim SFont, PFont
For Each SFont In Screen.Fonts ()
For Each PFont In Printer.Fonts ()
If SFont = PFont Then
Print SFont
End If
Next PFont
Next SFont
End Sub
注意,第一个 Next 关闭了内层的 For 循环,而最后一个 For 关闭了外层的 For 循环。同样,在嵌套的 If 语句中,End If 语句自动与最靠近的前一个 If 语句配对。嵌套的 Do...Loop 结构的工作方式也是一样的,最内圈的 Loop 语句与最内圈的 Do 语句匹配。
退出控制结构
用 Exit 语句可以直接退出 For 循环、Do 循环、子过程或函数过程。Exit 语句的语法很简单:Exit For 在 For 循环中出现的次数没有限制,Exit Do 在 Do 循环中出现的次数也没有限制。
For counter = start To end [Step increment]
[statementblock]
[Exit For]
[statementblock]
Next [counter[, counter] [,...]]
Do [{While | Until} condition]
[statementblock]
[Exit Do]
[statementblock]
Loop
Exit Do 语句可以在 Do 循环语法的所有版本中使用。
Exit For 和 Exit Do 非常有用,因为它有时适于立即退出循环,而且不再执行循环中的任何进一步迭代或者语句。例如,在前面的打印屏幕和打印机共有字体的例子中,程序不断将打印机字体和给定的屏幕字体作比较,甚至在已经找到了一个相符的打字机字体后还在继续寻找。对这个函数有一个效率更高的改进版,在此,只要找到相匹配的字体后就立即退出循环:
Private Sub Form_Click ()
Dim SFont, PFont
For Each SFont In Screen.Fonts ()
For Each PFont In Printer.Fonts ()
If SFont = PFont Then
Print Sfont
Exit For ’退出内圈循环。
End If
Next PFont
Next SFont
End Sub
正如此例所表明的, Exit 语句几乎总是出现在 If 语句或 Select Case 语句内部,而 If 语句或 Select Case 语句在循环内嵌套。
用 Exit 语句中断循环时,计数器变量的值会因退出循环的方式而不同:
在完成循环时,计数器的值等于上限值加上步进值。
在提前退出循环时,计数器变量保持其值,并遵从有关取值范围的一般规则。
在集合之外叠代时,如果计数器变量为 Object 类型,则其值为 Nothing;如果计数器变量为 Variant 类型,则其值为 Empty。
退出子过程或函数过程
也可从控制结构内部退出过程。Exit Sub 和 Exit Function 的语法,和上一节“退出控制结构”中的 Exit For 和 Exit Do 相似。Exit Sub 可以出现在子过程主体内的任何地方,出现的次数随需要而定。
当过程已完成每个任务并可直接返回时,Exit Sub 和 Exit Function 是非常有用的。例如,如果想改动前面的例子,使得对查找到的打印机和屏幕的共有字体,只打印其中的第一个,则可用 Exit Sub :
Private Sub Form_Click ()
Dim SFont, PFont
For Each SFont In Screen.Fonts ()
For Each PFont In Printer.Fonts ()
If SFont = PFont Then
Print Sfont
Exit Sub ’退出过程。
End If
Next PFont
Next SFont
End Sub
-
VB编程基础教程二十 - [VB学习]
2004-04-03
第21楼
循环结构
循环结构允许重复执行一行或数行代码。Visual Basic 支持的循环结构有:
Do...Loop
For...Next
For Each...Next
Do...Loop
用 Do 循环重复执行一语句块,且重复次数不定。Do...Loop 语句有几种演变形式,但每种都计算数值条件以决定是否继续执行。如同 If...Then condition 必须是一个数值或者值为 True(非零)或 False(零)的表达式。
在下面的 Do...Loop 循环中,只要 condition 为 True 就执行 statements。
Do While condition
statements
Loop
当 Visual Basic 执行这个 Do 循环时会首先测试 condition。如果 condition 为 False(零),则跳过所有语句。如果 condition 为 True(非零),则 Visual Basic 执行语句,然后退回到 Do While 语句再测试条件。
因此,只要 condition 为 True 或非零,循环可以随意执行多少次。如果 condition 一开始便为 False,则不会执行语句。例如,以下过程将计算某一目标字符串在另一字符串中出现的次数,只要发现目标串就执行循环:
Function CountStrings (longstring, target)
Dim position, count
position = 1
Do While InStr (position, longstring, target)
position = InStr(position, longstring, target)_
+ 1
count = count + 1
Loop
CountStrings = count
End Function
如果目标字符串未出现在另一个字符串中,则 InStr 返回 0,而且不再执行循环。
Do...Loop 语句的另一种演变形式是先执行语句,然后在每次执行后测试 condition。这种形式保证 statements 至少执行一次:
Do
statements
Loop While condition
其它两种演变形式类似于前两个,所不同的是,只要 condition 为 False 而不是 True,它们就执行循环。
循环零次或多次 至少循环一次
Do Until condition
statements
Loop Do
statements
Loop Until condition
.
For...Next
在不知道循环内需要执行多少次语句时,宜用 Do 循环。但是,在知道要执行多少次时,则最好使用 For...Next 循环。与 Do 循环不同, For 循环使用一个叫做计数器的变量,每重复一次循环之后,计数器变量的值就会增加或者减少。For 循环的语法如下:
For counter = start To end [Step increment]
statements
Next [counter]
参数 Counter、Start、end 和 increment 都是数值型的。
注意 increment 参数可正可负。如果 increment 为正,则 Start 必须小于等于 end,否则不能执行循环内的语句。如果 increment 为负,则 Start 必须大于等于 end,这样才能执行循环体。如果没有设置 Step,则 increment 缺省值为 1。
在执行 For 循环时,Visual Basic
设置 counter 等于 start。
测试 counter 是否大于 end。若是的话,则 Visual Basic 退出循环。
(若 increment 为负,则 Visual Basic 测试 counter 是否小于 end。)
执行语句。
counter 增加一,或者增加 increment(如果已指定的话)。
重复步骤 2 到步骤 4。
以下代码打印出所有有效的屏幕字体名:
Private Sub Form_Click ()
Dim I As Integer
For i = 0 To Screen.FontCount
Print Screen.Fonts (i)
Next
End Sub
在 VCR 示例应用程序中,HighlightButton 过程使用 For...Next 循环,一步步经过 VCR 窗体的控件集合,并显示适当的 Shape 控件:
Sub HighlightButton (MyControl As Variant)
Dim i As Integer
For i = 0 To frmVCR.Controls.Count - 1
If TypeOf frmVCR.Controls (i) Is Shape Then
If frmVCR.Controls (i).Name = MyControl Then
frmVCR.Controls (i).Visible = True
Else
frmVCR.Controls (i).Visible = False
End If
End If
Next
End Sub
For Each...Next
For Each...Next 循环与 For...Next 循环类似,但它对数组或对象集合中的每一个元素重复一组语句,而不是重复语句一定的次数。如果不知道一个集合有多少元素, For Each...Next 循环非常有用。
For Each...Next 循环的语法如下:
For Each element In group
statements
Next elementt
例如,下面的子过程打开 Biblio.mdb,把每一个表的名字加到列表框中。
Sub ListTableDefs ()
Dim objDb As Database
Dim MyTableDef as TableDef
Set objDb = OpenDatabase("c:\vb\biblio.mdb", _
True, False)
For Each MyTableDef In objDb.TableDefs ()
List1.AddItem MyTableDef.Name
Next MyTableDef
End Sub
请记住使用 For Each...Next 时的几点限制:
对集合,element 只能是 Variant 变量,或一般的 Object 变量,或“对象浏览器”中列出的对象。
对数组,element 只能是 Variant 变量。
For Each...Next 不能与用户自定义类型的数组一起使用,因为 Variant 不可能包含用户自定义类型。 -
VB编程基础教程十九 - [VB学习]
2004-04-03
判定结构
Visual Basic 过程能够测试条件式,然后根据测试结果执行不同的操作。Visual Basic 支持的判定结构有:
If...Then
If...Then...Else
Select Case
If...Then
用 If...Then 结构有条件地执行一个或多个语句。单行语法和多行块语法都可以使用:
If condition Then statement
If condition Then
statements
End If
Condition 通常是比较式,但它可以是任何计算数值的表达式。Visual Basic 将这个值解释为 True 或 False:一个为零的数值为 False,而任何非零数值都被看作 True。若 condition 为 True,则 Visual Basic 执行 Then 关键字后面的所有 statements。可以使用单行或多行语法有条件地执行一个语句(下面两个例子等价):
If anyDate < Now Then anyDate = Now
If anyDate < Now Then
anyDate = Now
End If
注意:If...Then 的单行格式不用 End If 语句。如果 condition 为 True 时要执行多行代码,则必须使用多行块 If...Then...End If 语法。
If anyDate < Now Then
anyDate = Now
Timer1.Enabled = False ’定时器控制失效。
End If
If...Then...Else
用 If...Then...Else 块定义几个语句块,执行其中一个语句:
If condition1 Then
[statementblock-1]
[ElseIf condition2 Then
[statementblock-2]] ...
[Else
[statementblock-n]]
End If
Visual Basic 首先测试 condition1。如果它为 False,Visual Basic就测试 condition2,依次类推,直到找到一个为 True 的条件。当它找到一个为 True 的条件时,Visual Basic就会执行相应的语句块,然后执行 End If 后面的代码。作为一个选择,可以包含 Else 语句块,如果条件都不是 True,则 Visual Basic 执行 Else 语句块。
If...Then…ElseIf 只是 If...Then...Else 的一个特例。注意,可以使用任意数量的 ElseIf 子句,或者一个也不用。可以有一个 Else 子句,而不管有没有 ElseIf 子句。
例如,应用程序可以根据菜单控件数组中哪个控件被单击而采取相应的动作:
Private Sub mnuCut_Click (Index As Integer)
If Index = 0 Then ’“剪切”命令。
CopyActiveControl ’调用通用过程。
ClearActiveControl
ElseIf Index = 1 Then ’“复制”命令。
CopyActiveControl
ElseIf Index = 2 Then ’“清除”命令。
ClearActiveControl
Else ’“粘贴”命令。
PasteActiveControl
End If
End Sub
注意,总是可以添加更多的 ElseIf 块到 If...Then 结构中去。但是,当每个 ElseIf 都将相同的表达式比作不同的数值时,这个结构编写起来很乏味。在这种情况下可以使用 Select Case 判定结构。
详细信息 请参阅语言参考中的“If...Then...Else 语句”。
Select Case
Visual Basic 提供 Select Case 结构替代 If...Then...Else,从而可在多个语句块中有选择地执行其中一个。Select Case 语句的能力与 If...Then...Else 语句类似,但对多重选择的情况,Select Case 语句使代码更加易读。
Select Case 在结构的上方处理一个测试表达式并只计算一次。然后,Visual Basic 将表达式的值与结构中的每个 Case 的值进行比较。如果相等,就执行与该 Case 相关联的语句块。
Select Case testexpression
[Case expressionlist1
[statementblock-1]]
[Case expressionlist2
[statementblock-2]]
.
.
.
[Case Else
[statementblock-n]]
End Select
每一个 expressionlist 是一个或几个值的列表。如果在一个列表中有多个值,就用逗号把值隔开。每一个 statementblock 中含有零个或多个语句。如果不止一个 Case与测试表达式相匹配,则只对第一个匹配的 Case 执行与之相关联的语句块。如果在表达式列表中没有一个值与测试表达式相匹配,则 Visual Basic 执行 Case Else 子句(此项是可选的)中的语句。
例如,假定在 If...Then...Else 的例子中要向“编辑”菜单添加命令。为此可以另加一个 ElseIf 子句,或用 Select Case 来写函数:
Private Sub mnuCut_Click (Index As Integer)
Select Case Index
Case 0 ’“剪切”命令。
CopyActiveControl ’调用通用过程。
ClearActiveControl
Case 1 ’“复制”命令。
CopyActiveControl
Case 2 ’“清除”命令。
ClearActiveControl
Case 3 ’“粘贴”命令。
PasteActiveControl
Case Else
frmFind.Show ’显示找到的对话框。
End Select
End Sub
注意 Select Case 结构每次都要在开始处计算表达式的值。而 If...Then...Else 结构为每个 ElseIf 语句计算不同的表达式。只有在 If 语句和每一个 ElseIf 语句计算相同表达式时,才能用 Select Case 结构替换 If...Th -
VB编程基础教程十八 - [VB学习]
2004-04-03
控制结构概述
有了控制结构就可控制程序执行的流程。如果未复选控制流语句,程序便从左至右、自顶向下地贯穿这些语句。有些简单程序可以只用单向流程来编写,有些流程可以依靠运算符的优先级来控制,但任何编程语言的效力和用途皆由其通过结构和循环改变语句顺序的能力而得。
关于控制结构的详细信息,请参阅下面的主题:
判定结构 用于分支的判定结构。
循环结构 用于重复处理的循环结构。
使用控制结构 在代码中运用控制结构的基础。
-
VB编程基础教程十七 - [VB学习]
2004-04-03
向过程传递参数
过程中的代码通常需要某些关于程序状态的信息才能完成它的工作。信息包括在调用过程时传递到过程内的变量。当将变量传递到过程时,称变量为参数。
参数的数据类型
过程的参数被缺省为具有 Variant 数据类型。不过,也可以声明参数为其它数据类型。例如,下面的函数接受一个字符串和一个整数:
Function WhatsForLunch(WeekDay As String, Hour _
As Integer) As String
’根据星期几和时间,返回午餐菜单。
If WeekDay = "Friday" then
WhatsForLunch = "Fish"
Else
WhatsForLunch = "Chicken"
End If
If Hour > 4 Then WhatsForLunch = "Too late"
End Function
详细信息 关于 Visual Basic 的数据类型,请参阅本章前面部分。也可以在语言参考中查找指定的数据类型。
按值传递参数
按值传递参数时,传递的只是变量的副本。如果过程改变了这个值,则所作变动只影响副本而不会影响变量本身。用 ByVal 关键字指出参数是按值来传递的。
例如:
Sub PostAccounts (ByVal intAcctNum as Integer)
.
. ’这里放语句。
.
End Sub
按地址传递参数
按地址传递参数使过程用变量的内存地址去访问实际变量的内容。结果,将变量传递给过程时,通过过程可永远改变变量值。按地址传递参数在 Visual Basic 中是缺省的。
如果给按地址传递参数指定数据类型,就必须将这种类型的值传给参数。可以给参数传递一个表达式,而不是数据类型。Visual Basic 计算表达式,如果可能的话,还会按要求的类型将值传递给参数。
把变量转换成表达式的最简单的方法就是把它放在括号内。例如,为了把声明为整数的变量传递给过程,该过程以字符串为参数,则可以用下面的语句:
Sub CallingProcedure ()
Dim intX As Integer
intX = 12 * 3
Foo (intX)
End Sub
Sub Foo (Bar As String)
MsgBox Bar ’Bar 的值为字符串‘ 36 ’。
End Sub
使用可选的参数
在过程的参数列表中列入 Optional 关键字,就可以指定过程的参数为可选的。如果指定了可选参数,则参数表中此参数后面的其它参数也必是可选的,并且要用 Optional 关键字来声明。下面两段示例代码假定有一个窗体,其内有一命令按钮和一列表框。
例如,这段代码提供所有可选参数:
Dim strName As String
Dim strAddress As String
Sub ListText(Optional x As String, Optional y _
As String)
List1.AddItem x
List1.AddItem y
End Sub
Private Sub Command1_Click ()
strName = "yourname"
Optional
strAddress = 12345 ’提供了两个参数。
Call ListText (strName, strAddress)
End Sub
而下面的代码并未提供全部可选参数:
Dim strName As String
Dim varAddress As Variant
Sub ListText (x As String, Optional y As Variant)
List1.AddItem x
If Not IsMissing (y) Then
List1.AddItem y
End If
End Sub
Private Sub Command1_Click ()
strName = "yourname" ’未提供第二个参
’数。
Call ListText (strName)
End Sub
在未提供某个可选参数时,实际上将该参数作为具有 Empty 值的变体来赋值。上例说明如何用 IsMissing 函数测试丢失的可选参数。
提供可选参数的缺省值
也可以给可选参数指定缺省值。在下例中,如果未将可选参数传递到函数过程,则返回一个缺省值。
Sub ListText(x As String, Optional y As _
Integer = 12345)
List1.AddItem x
List1.AddItem y
End Sub
Private Sub Command1_Click ()
strName = "yourname" ’未提供第二个参
’数。
Call ListText (strName) ’添加“yourname”和
’“12345”。
End Sub
使用不定数量的参数
一般说来,过程调用中的参数个数应等于过程说明的参数个数。可用 ParamArray 关键字指明,过程将接受任意个数的参数。于是可以这样来编写计算总和的 Sum 函数:
Dim x As Integer
Dim y As Integer
Dim intSum As Integer
Sub Sum (ParamArray intNums ())
For Each x In intNums
y = y + x
Next x
intSum = y
End Sub
Private Sub Command1_Click ()
Sum 1, 3, 5, 7, 8
List1.AddItem intSum
End Sub
用命名的参数创建简单语句
对许多内建函数、语句和方法,Visual Basic 提供了命名参数方法来快捷传递参数值。对命名参数,通过给命名参数赋值,就可按任意次序提供任意多参数。为此,键入命名参数,其后为冒号、等号和值 (MyArgument := "Somevalue") ,可以按任意次序安排这些赋值,它们之间用逗号分开。注意,下例中的参数顺序和所要参数的顺序相反:
Function ListText (strName As String, Optional strAddress As String)
List1.AddItem strName
List2.AddItem strAddress
End Sub
Private -
VB编程基础教程十六 - [VB学习]
2004-04-03
使用过程
创建新过程
要创建新的通用过程,请
在“代码”窗口输入过程头并按下回车键。过程头以 Sub 或 Function 打头,再接一个名字。例如,可以用以下任一方式输入:
Sub UpdateForm ()
Function GetCoord ()
通过完成新过程的模板, Visual Basic 作出反应。
选择现有过程
要在当前模块中查看过程,请
为了查看现有通用过程,在“代码”窗口的“对象框”中选择“通用”,然后在“过程框”中选择过程。
-或者-
为查看事件过程,在“代码”窗口的“对象框”中选择适当的对象,然后在“过程框”中选择事件。
要查看其它模块中的过程,请
在“视图”菜单中选取“对象浏览器”。
在“工程/库”框中选择工程。
在“类/模块”列表中选择模块,并在“成员”列表中选择过程。
选取“查看定义”。
调用过程
调用过程有诸多技巧,它们与过程的类型、位置以及在应用程序中的使用方式有关。下面的章节说明如何调用 Sub 过程和 Function 过程。
调用 Sub 过程
与 Sub 过程不同,在表达式中,Sub 过程不能用其名字调用。调用 Sub 过程的是一个独立的语句。Sub 过程还有一点与函数不一样,它不会用名字返回一个值。但是,与 Function过程一样,Sub 过程也可以修改传递给它们的任何变量的值。
调用 Sub 过程有两种方法:
’以下两个语句都调用了名为 MyProc 的 Sub 过程。
Call MyProc (FirstArgument, SecondArgument)
MyProc FirstArgument, SecondArgument
注意,当使用 Call 语法时,参数必须在括号内。若省略 Call 关键字,则也必须省略参数两边的括号。
调用函数过程
通常,调用自行编写的函数过程的方法和调用 Visual Basic 内部函数过程(例如 Abs)的方法一样;即在表达式中写上它的名字。
’下面的语句都调用函数 ToDec。
Print 10 * ToDec
X = ToDec
If ToDec = 10 Then Debug.Print "Out of Range"
X = AnotherFunction ( 10 * ToDec)
就像调用 Sub 过程那样,也能调用函数。下面的语句都调用同一个函数:
Call Year (Now)
Year Now
当用这种方法调用函数时,Visual Basic 放弃返回值。
调用其它模块中的过程
在工程中的任何地方都能调用其它模块中的公用过程。可能需要指定这样的模块,它包含正在调用的过程。调用其它模块中的过程的各种技巧,取决于该过程是在窗体模块中、类模块中还是标准模块中。
窗体中的过程
所有窗体模块的外部调用必须指向包含此过程的窗体模块。如果在窗体模块 Form1 中包含 SomeSub 过程,则可使用下面的语句调用 Form1 中的过程:
Call Form1.SomeSub(arguments)
类模块中的过程
与窗体中调用过程类似,在类模块中调用过程要调用与过程一致并且指向类实例的变量。例如,DemoClass 是类 Class1 的实例:
Dim DemoClass as New Class1
DemoClass.SomeSub
但是不同于窗体的是,在引用一个类的实例时,不能用类名作限定符。必须首先声明类的实例为对象变量(在这个例子中是 DemoClass )并用变量名引用它。
详细信息 可在“用对象编程”中找到关于对象变量和类模块的详细信息。
标准模块中的过程
如果过程名是唯一的,则不必在调用时加模块名。无论是在模块内,还是在模块外调用,结果总会引用这个唯一过程。如果过程仅出现在一个地方,这个过程就是唯一的。
如果两个以上的模块都包含同名的过程,那就有必要用模块名来限定了。在同一模块内调用一个公共过程就会运行该模块内的过程。例如,对于 Module1 和 Module2 中名为 CommonName 的过程,从 Module2 中调用 CommonName 则运行 Module2 中的 CommonName 过程,而不是 Module1 中的 CommonName 过程。
从其它模块调用公共过程名时必须指定那个模块。例如,若在 Module1 中调用 Module2 中的 CommonName 过程,要用下面的语句:
Module2.CommonName (arguments)
-
VB编程基础教程十五 - [VB学习]
2004-04-03
Funtion 过程
Visual Basic 包含内置的、或内部的函数,如 Sqr、Cos 或 Chr。此外,还可用 Function 语句编写自己的 Function 过程。
函数过程的语法是:
Private|Public][Static]Function procedurename (arguments) [As type]
statements
End Function
与 Sub 过程一样,Function 过程也是一个独立的过程,可读取参数、执行一系列语句并改变其参数的值。与子过程不同,Function 过程可返回一个值到调用的过程。在Sub 过程与Function 过程之间有三点区别:
一般说来,让较大的语句或表达式的右边包含函数过程名和参数 (returnvalue = function),这就调用了函数。
与变量完全一样,函数过程有数据类型。这就决定了返回值的类型。(如果没有 As 子句,缺省的数据类型为 Variant。)
给 procedurename 自身赋一个值,就可返回这个值。Function 过程返回一个值时,该值可成为较大表达式的一部分。
例如,下面是已知直角三角形两直角边的值,计算第三边(斜边)的函数:
Function Hypotenuse (A As Integer, B As Integer) As String
Hypotenuse = Sqr (A ^ 2 + B ^ 2)
End Function
在 Visual Basic 中调用 Function 过程的方法和调用任何内部函数的方法是一样的:
Label1.Caption = Hypotenuse(CInt(Text1.Text), _
CInt(Text2.Text))
strX = Hypotenuse (Width, Height)
详细信息 关于函数过程的详细信息,请参阅语言参考中的“Function 语句”。调用各种类型的过程的技巧,在本章后面的“调用过程”部分有详细讨论。
-
VB编程基础教程十四 - [VB学习]
2004-04-03
Sub 过程
子过程是在响应事件时执行的代码块。将模块中的代码分成子过程后,在应用程序中查找和修改代码变得更容易了。
子过程的语法是:
[Private|Public][Static]Sub procedurename (arguments)
statements
End Sub
每次调用过程都会执行 Sub 和 End Sub 之间的 statements。可以将子过程放入标准模块、类模块和窗体模块中。按照缺省规定,所有模块中的子过程为 Public(公用的),这意味着在应用程序中可随处调用它们。
过程的 arguments 类似于变量声明,它声明了从调用过程传递进来的值。
在 Visual Basic 中应区分通用过程和事件过程这两类子过程。
通用过程
通用过程告诉应用程序如何完成一项指定的任务。一旦确定了通用过程,就必须专由应用程序来调用。反之,直到为响应用户引发的事件或系统引发的事件而调用事件过程时,事件过程通常总是处于空闲状态。
为什么要建立通用过程呢?理由之一就是,几个不同的事件过程也许要执行同样的动作。将公共语句放入一分离开的过程(通用过程)并由事件过程来调用它,诚为编程上策。这样一来就不必重复代码,也容易维护应用程序。例如,VCR 示例应用程序使用了一个通用过程,几个不同滚动按钮的 Click 事件都调用这个通用过程。图 5.7 说明了通用过程的使用。Click 事件中的代码调用按钮管理器的子过程,子过程运行自身的代码,然后将控制返回到 Click 事件过程。
图 5.7 通用过程如何被事件过程调用
事件过程
当 Visual Basic 中的对象对一个事件的发生作出认定时,便自动用相应于事件的名字调用该事件的过程。因为名字在对象和代码之间建立了联系,所以说事件过程是附加在窗体和控件上的。
一个控件的事件过程将控件的(在 Name 属性中规定的)实际名字、下划线 (_) 和事件名组合起来。例如,如果希望在单击了一个名为 cmdPlay 的命令按钮之后,这个按钮会调用事件过程,则要使用 cmdPlay_Click 过程。
一个窗体事件过程将词汇 "Form"、下划线和事件名组合起来。如果希望在单击窗体之后,窗体会调用事件过程,则要使用 Form_Click 过程。(和控件一样,窗体也有唯一的名字,但不能在事件过程的名字中使用这些名字。)如果正在使用 MDI 窗体,则事件过程将词汇 " MDIForm " 、下划线和事件名组合起来,如 MDIForm_Load。
所有的事件过程使用相同的语法。
控件事件的语法 窗体事件的语法
Private Sub controlname_eventname (arguments )
statements
End Sub
Private Sub Form_eventname (arguments)
statements
End Sub
虽然可以自己编写事