Vous êtes sur la page 1sur 97

第一章 Visual Basic 的基 础知识

§1 Visual Basic 的基础知识


1、 概念和术语
1,对象(Object)
事物都可称作对象,比如桌椅就是对象,在 Visual Basic 里对象主要分为两类:Form 和
Control。
Form:窗体或称表单,其实指的就是 window。
Control:控件,指的是各种按钮、标签等等。
2,属性(Property)
指的是对象的属性,比如姓名、性别、民族、籍贯都是你这个对象的属性。
Caption、Left、Name 是一个命令按钮的属性。
3,事件(Event)
事件是发生在对象上的动作。比如敲桌子是一个事件,它是发生在桌子这个对象上的一
个动作。比如 Click、Dblclick 或 LostFocus 是发生在文本框控件上的事件。然而事件的发生不
是随意的,某些事件仅发生在某些对象上而已,比如“逃避早操被抓住”可以发生在学生
这个对象上,但它不会发生在老师这个对象上。
4,方法(Method)
这是一个直译,是一个较难理解的概念,它是对象本身内含的函数或过程,它也是一
个动作,但不称作事件,在 Visual Basic 里,方法和事件是这样的:
事件:
Private Sub 对象名_事件名
(事件内容)
End Sub
方法:对象名.方法名
所以方法是一个简单的不必知道细节的无法改变的事件,同样,方法也不是随意的,
一些对象有一些特定的方法。如果以上概念你记不住,不要紧,实践中你会明白一切,请继
续学习。
2、 Visual Basic 的开发周期
1,想清楚你想做到什么;
2,拿起笔在纸上画出你的用户界面;
3,拿起鼠标在屏幕上画出你的用户界面,确定对象的属性;
4,告诉计算机你要做的事;
5,让程序运行,看看能否工作;
6,如果不能工作,不必难过;
7,找出那个错误,重新开始。
你应该养成一些良好的习惯,这样在你编大程序时不至于丢三落四,为一些本来可避
免的错误反复做第六步和第七步。
3、 Visual Basic 的存储和运行
1,编写的程序和对象的属性一块儿存在 frm 文件里;
2,整个程序里包含着一个或许多 frm 文件, Visual Basic 将所有 frm 文件名存入一个
vbp 文件里,若丢失了一个 vbp 文件,尽管 frm 文件仍在磁盘上,但程序将不能运
行了;
3,如果你的程序已经自以为成功了,你可以把它编译成 EXE 文件,这样做的好处是:
(1)在没有 Visual Basic 的环境下可以运行;
(2)速度提高;
(3)别人不知道你的编程方法,还以为你是个编程专家,对你的编程效率大加赞叹。
更商业化的做法是做一张安装盘, Visual Basic 6.0 在这方面也为你准备了工具,我们以
后会讲到这个工具
4、 Visual Basic 的不同之处
1,建立用户界面。对 Visual Basic 来讲,用户界面是由你直接在屏幕上画出来的,所以
Visual Basic 的用户界面看上去总是十分完美。
2,程序对用户界面反应。在 Visual Basic 里有许多事件等待你去填写代码,它自动也知
道向机器解释这个事件,仅此一点就已经省去你的许多时间。
3,结构化的语言。在 Visual Basic 里似乎没有主程序一说,所有的代码都在一个一个模
块里,所以所有的程序看起来都是不很长。
5、 Visual Basic 的不足之处
Microsoft 的 C++程序员是不会开发出一样东西之后,让自己失业的,大多数简单好用
的东西都有它的限制,Visual Basic 也是一样。
1, C++ 和 Pascal 有更多的对计算机的控制,所以 Windows 是用 C 和汇编语言编的,
UNIX 也是用 C 语言编的,想用 Visual Basic 做一个操作系统是不可能的;
2, C++ 和 Pascal 是一种速度更快的语言,所以如果速度在程序中很重要,则 Visual
Basic 难以胜任;
3, Visual Basic 不能在 Macintosh、OS/2 上运行,也不能在小型机或巨型机上运行。
当然,任何一门语言的精通都需要长时间的“玩耍”,然而现在,我们只须从玩 Visual
Basic 开始。

§2 制作第一个 Visual Basic 程序


1、 我们要做什么
1,我们要做的第一步是确立我们想做什么,我们想做的第一个自已的 Visual Basic 程
序是让一张幸福的小脸眨眼睛的程序。
2,绘制用户界面,这是第二步。
在开始菜单里选程序项,选择 Visual Basic 6.0 组,选择 Visual Basic 6.0 ,进入 Visual
Basic 环境。下面是画控件的方法:
1,单击工具栏里想画的控件(这个工具栏出现在 Visual Basic 界面的左边);
2,在窗体里单击并拖曳鼠标,画出控件(打开 Visual Basic 时,会有一个名为 Form1
的空白窗体出现)。

2、 绘制用户界面

1,单击工具栏里的选项按钮控件( OptionButton ) ,单击并拖曳鼠标,在 Form1

里,画一个选项按钮,使它看起来象图示一样;
2,再画三个选项按钮;

3,单击工具栏里图标控件( Image) ,单击并拖曳鼠标,在窗体里,画一个图标

轮廓;
4,再在旁边画四个图标;

5,单击工具栏里命令钮控件( CommandButton) ,单击并拖曳鼠标,在窗体里,

画一个按钮;
6,从 File 菜单里选择 Save File 项;
7,在 Save 对话框填上 HellloVB,它的扩展名是 frm,单击 OK 钮;
8,从 File 菜单选择 Save Project 项;
9,在对话框里填上 HelloVB,它的扩展名是 vbp,单击 OK 钮。
现在,我们已完成了用户界面的一部分设计设计,运行的时侯它看起来就是现在这个
样子的。
3、 精确设置对象的属性
首先,我们不一定要设置对象的属性,Visual Basic 有对其对象属性的缺省值,其次,
尽管每个对象有数十个属性,但我们往往只须改变其中的几个值而已。可以在设计阶段改变
对象属性,也可以在运行阶段改变对象属性属性。在这个程序里我们通过设计阶段的改变属
性的方法和运行阶段的改变属性的方法来实行全部的功能。下面是设置属性的方法:
1,选择需要改变属性的对象(用鼠标在控件上单击,这时在控件周围出现八个小黑块,
表示你已选上了这个控件);
2,按 F4 打开属性窗口;
3,选择想要改变的属性;
4,赋新值。
现在开始设置属性。
1,选择 Form 对象,按 F4 键,出现 Property 窗口;
2,选择 Caption 属性;
3,通过输入“My First Visual Basic Application”来改变设置;
4,选择 Icon 属性,单击属性栏旁边标有“…”的键,出现 Load Icon 对话框;
5,选择 VB\icons\misc\face03.ico;
6,按 OK 键
7,选 择 Option1 选 项按 钮, 按 F4 键 ,出 现 Property 窗口 ,选 择 Name 属 性, 键入
“optBoth”。其余的属性设置是这样的:

控件 属性 设置值
Option1 Caption 睁眼睛
Option2 Caption 眨左眼
Name optLeft
Option3 Caption 眨右眼
Name optRight
Option4 Caption 闭眼睛
Name optNone
Command1 Caption 退出
Name cmdExit
Image1 Picture FACE03.ICO
Stretch True
Name imgShow
Image2 Picture FACE03.ICO
Visible False
Name imgBoth
Image3 Picture FACE05.ICO
Visible False
Name imgLeft
Image4 Picture FACE04.ICO
Visible False
Name imgRight
Image5 Picture FACE06.ICO
Visible False
Name imgNone

注:
1,Image 控件的 Picture 属性的设置和 Form1 的 Icon 属性的设置方法是一样的(即在属
性栏旁边找到标有“…”的按钮,并按它。);
2,face04 , face05 , face06 图标并不在 vb\icons 子目录下,那是自已做的。在 Borland
C++、Visual C++、Visual FoxPro、Delphi 等编程工具里都有制作图标的工具,可以用
来制作自已的图标;
3,Visible 属性的真假决定对象在运行时是否可以被看见,False 值表示对象不可见;
4,Stretch 属性决定 Image 控件里的图像能否被放大或缩小,当然,放得很大的图标会
显得很粗糙。
现在我们终于完成了界面的设计,然而,这个程序还不能工作,因为计算机还达不到
人的思维水平,它想象不出这个程序是做什么的,与此同时,你已想像出这个出这个程序
执行时的样子了。

四、编写程序代码──最令人费解和最没有成就感的必要工作,除了程序员、专家,大
多数人对程序代码都感到厌倦,幸好我们都不想成为世界级的程序员,所以目前的 Visual
Basic 程序代码都不是很难。
1,选定一个对象,比如 optLeft,然后按 F7 键或双击它,Visual Basic 显示代码窗口,
Visual Basic 将显示:
Private Sub optLeft_Click()

End Sub
Private 表明这段代码的应用范围,我们先不用深究这个词的内涵, Sub 是一个开头,是
subprogram 的简写,optLeft 是对象名,_是一个下划线,用来分开对象名和事件名, Click
是指一个事件,Click 就是“单击”的意思,()是一对括号,通常里面是过程所使用的参
数,现在它是空的。
这一行的意思是:“这是当用户单击了 optLeft 选项按钮时,程序应该做的事。”
End Sub 是这段代码的结束标志,意思是“这是这段代码的最后一行。”
我们要在这两行间输入指令。
2,现在输入如下指令
Private Sub optLeft_Click()
imgShow.Picture = imgLeft.Picture
End Sub
3,从代码窗口顶部选择 Object 列表框,选择 optRight 控件,Visual Basic 将显示另一个
空的 Click 过程。
4,输入如下代码:
Private Sub optRight_Click()
imgShow.Picture = imgRight.Picture
End Sub
5,用同样方法再输入三条指令:
Private Sub optBoth_Click()
imgShow.Picture = imgBoth.Picture
End Sub
Private Sub cmdExit_Click()
End
End Sub
Private Sub optNone_Click()
imgShow.Picture = imgNone.Picture
End Sub
按下 F5 键运行这个程序,看它是否能运行。如果运行不正确,那么你要找出错误,再
试一次。

我们已经成功地完成了这个例子,你已经首次尝试了 Visual Basic 的编程过程。是否十


分简单?其实编程序就象眨眼的小脸一样有趣。

第二章 用户界 面设计

§1 用户界面设计概述
一,在设计前应该了解的
通常程序总是由用户操纵的,所以用户需要一个界面来进行操纵。往往那些漂亮的简单
的界面更加吸引用户,让他们认为程序有魔术般的力量,这样他们才会使用这个程序。下面
有四条设计界面的原则。
1,了解用户的习惯
2,保持简单
3,允许用户的错误,并给以提示
4,让用户了解他在程序中的位置
二,Visual Basic 用户界面设计基础
通过我们的第一个 Visual Basic 程序的设计,我们已经知道界面的设计有两步:先绘制
控件,然后确定控件属性。我们发现绘制控件并不是很难。在工具箱里单击想画的控件,在
窗体里按下鼠标并拖曳,然后松开鼠标即可。双击工具箱里的控件,将在窗体中央出现那个
控件。如果用这种方法的话,要注意双击第二个控件时把上一个控件移开,否则两个控件会
叠在一起,引起一些混淆。确定属性的方法是先选中控件,然后按 F4 键进入 Properties 窗口,
接着在 Properties 窗口中找到要设置的属性并进行设置。

下面解释一些常用的属性,这些属性几乎总是要被设置和改变。
(1)Name 属性
对象都有名字,尽管我们可以通过描绘一些特性来描绘对象,这样做总是非常麻烦。计
算机也是一样,它把名字看成对象于对象之间的根本差异。由于计算机的这种顽固观点,它
拒绝在同一窗体里出现重名的情况(除非这是一个控件数组),它也拒绝超过 40 个字的名
字。
在简单的程序里,给控件命名不很必要,我们完全可以使用控件 Name 属性的缺省值。
例如 Text1。但在有几十个控件的复杂窗体里,这种方法会使你花更多的时间去区分它们。所
以,Visual Basic 向你推荐由三个小写字母的前缀和一个第一个字母为大写的描述性单词组
成的名字。例如 cmdMyButton 是一个命令按钮(前缀是 cmd)
推荐的前缀是:

对象 前缀 例子
确认框(Check Box) chk chkCareerChioce
组合框(Combo Box) cbo cboCrimesCommitted
命令钮(Command Button) cmd cmdExit
数据库控件(Data Control) dat datTopSecretInfo
目录列表框(Directory List Box) dir dirTree
驱动器列表框(Drive List Box) drv drvHardDisk
文件列表框(File List Box) fil filDocuments
窗体(Form) frm frm1040Tax
框架(Frame) fra fraGroupButtons
水平滚动条(Horizontal Scroll Bar) hsb hsbTemperature
图形(Image) img imgPrettyDrawing
标签(Label) lbl lblFakeName
线(Line) lin linBorder
列表框(List Box) lst lstCandidates
菜单(Menu) mnu mnuHamAndEggs
选项钮(Option Button) opt optStation101
图形框(Picture Box) pic picPrettyPicture
几何图形(Shape) shp shpUpOrShipOut
正文框(Text Box) txt txtWarning
垂直滚动条(Vertical Scroll Bar) vsb vsbMoneyRaised

(2)Caption 属性
这仅仅是一个装饰性的属性,它可以长达 255 字符,包括空格和标点符号,比如一个叫
cmdOk 的命令钮,它的 Caption 属性就可以是“Ok”。
编程序时也要考虑到使用键盘的用户,在设置 Caption 属性在需要加下划线的字母前加
上 “&” 符号,例如 “&File”,输出的就是“File”,这样就可以通过按 ALT 键和标题上那
个带下划线的字母来选取它了。你不必为此编任何代码。
(3)Top,Left 属性
只有两种情况需要在属性窗口里设置这两个属性:第一种是用户没有鼠标,第二种是程
序员需要十分精确地设定这两个值。这两个属性决定对象的位置。当你选中对象,单击并拖
曳它的时候,你便在修改这两个值了。

(4)Height,Width 属性
这两个属性决定了对象的大小,当你选中控件时,它周围出现八个小黑方块,你把鼠标
指向这些方块,鼠标指针将变成一个双向的箭头,这时按下鼠标并拖曳它,即可改变控件
的大小,也就改变了 Height,Width 属性。同 Top,Left 属性一样,我们主要通过鼠标的操作
来设置 Height,Width 属性。

§2 窗体和命令钮介绍
一、窗体
窗体是 Windows 的基本组成部分,这也是为什么这个操作系统叫 Windows 的原因。它的
主要属性除上面介绍的以外,还包括:
1,Appearance 属性
这个属性用来决定控件是否采用三维效果。
2,BorderStyle 属性
这个属性决定了窗体的边框形式,共有 6 种属性值。改变窗体的 BordrStyle 属性后,窗
体在屏幕上没有变化,它只在运行时才变为你所要求的样子。
3,ControlBox 属性
程序员用来决定采用不采用控制框的属性,仅在程序运行时才有效。
4,Font 属性
程序员可以改变该窗体上显示信息的字体,它控制着直接在窗体上打印的文本显示。
5,Icon 属性
这个属性是用户经常要使用的一种属性。当用户的应用程序在工具条上最小化或在
Windows 桌面上变为一个独立应用程序时,该属性决定将采用何种图标,窗体控制框里的
图标也由它决定。为自己的窗体设置该属性时,要控制住自己挑三拣四的冲动。
6,Visible 属性
该属性决定窗体是否可见。错误地改变其值是很危险的,窗体会从眼前消失,这种莫名
其妙的事情会使用户惊惶失措,所以肩负重任的程序员一定要慎重哟!
7,WindowState 属性
指定窗体在运行时的三种状态:正常、最小化、最大化。
二、窗体的主要事件
1,Load 事件
这个事件发生在窗体被装入内存时,且发生在窗体出现在屏幕之前。窗体出现之前,
Visual Basic 会看一看 Load 事件里有没有代码,如果有,那么它先执行这些代码,再让窗体
出现在屏幕上。
2,Click 事件,Dblclick 事件
这两个事件在单击或双击窗体时发生。不过你单击窗体里的控件时,窗体的 Click 事件
并不会发生,Visual Basic 会去看控件的 Click 事件里有没有代码。
3,Activate (活动事件)与 Deactivate(非活动事件)
显示多个窗体时,可以从一个窗体切换到另一个窗体。每次激活一个窗体时,发生
Activate 事件,而前一个窗体发生 Deactivate 事件。
三、窗体控制
1,装入或卸出窗体
要装入或卸出窗体,用 Load 或 Unload 语句。Load 语句的语法如下:
Load formName
而 UnLoad 语句的语法是:
UnLoad formName
FormName 变量是要装入或卸出的窗体名。 Load 语句只是把窗体装入内存,并不显示
出 来,要显示窗体可以使用窗体的 Show 方法。
2,显示或隐藏窗体
要显示窗体,用 Show 方法。若尚未装入内存则先装入再显示。它的语法如下:
formName.show mode
FormName 变量是窗体名,可选变元 mode 为 0(缺省值)时窗体为非模态,为 1 时窗体
为模态。模态窗体完全占有应用程序控制权,不允许切换到别的应用程序,除非关闭!而非
模态窗体则反之。
同理,隐藏窗体用 formName.hide。
四、命令钮
命令钮有两类:一类是简单的命令钮,一类是图形钮。图形钮常常成组地出现在屏幕的
顶端,成为一些程序炫耀自己贴近用户的标志。图形钮充分利用了图形用户界面的特征,而
且比命令钮小,但它的缺点是用户必须知道图形钮是什么意思,而且没有鼠标的用户恐怕
用不了图形钮。命令钮也有 Appearance、Caption、Font、Left、Visible 之类的属性。命令钮的最主
要事件就是 Click 事件,它还有 MouseDown 和 MouseUp 等事件

§3 建立菜单
一般 Windows 的菜单条包含 File,Edit,Window 和 Help 菜单标题。其它的菜单,程序
员应将它们插在 Edit 和 Window 菜单之间。在 Visual Basic 里,为了创建菜单,必须打开菜
单编辑窗口。可以按下 Ctrl+E 键,也可以从 Tools 菜单中选择 Menu Editor 项,或者单击
Visual Basic 主窗口的从左边数第六个图形钮。
一、给菜单命名
菜单标题和菜单命令也有 Caption 和 Name 属性,你设置了这两个属性就等于创建了菜
单。于控件一样 Caption 是屏幕上可见的,而 Name 则是一个抽象名称。别忘了在 Caption 里
加入 “&” 以帮助没有鼠标的用户。
二、增加和删除菜单
在 Menu Editor 中部有三个命令钮分别是 Next,Insert,Delete。Insert 可用来增加新的菜
单。在这三个键下面的 Caption 列表框里选中菜单项(这时它的底色就变成深蓝色),单击
Insert 键,Visual Basic 将上一个增亮菜单下推并增亮一空行,你就可以输入新菜单名和标题
了。Delete 键可用来删掉菜单。你选中要删掉的菜单,单击 Delete 键就可以删掉它了。
三、移动菜单标题
有四种情况,向上移动,向下移动,向左缩排,向右缩排,这就是 Menu Editor 中间上
下左右箭头的功能。选中某一菜单标题,安上下箭头,则这个菜单将上下移动到你喜欢的位
置上,这也决定了它在界面中的位置。如果你按左右箭头,情况则有所不同。由于菜单是分
级的,所以,如果它没有缩排,则它是一个菜单标题;如果它缩排一次,那么它将变成一
个菜单命令;如果缩排两次,那么它将成为一个子菜单命令。 Visual Basic 里你可以总共设计
四层子菜单。
四、设置分离条
分离条是指在菜单中将命令分组的线。
奇怪的是,Visual Basic 将分离条也看成一个菜单项,它也需要 Caption 和 Name 属性,
而且它也有其它属性,分离条与菜单项的区别是分离条的 Caption 属性必须是连字号即减号。
也就是,当你设置了一个 Caption 属性为 “-” 的菜单项时,实际上你就设置了一个分离条,
分离条的名字可以是 barFile1 之类,以表明分离条的位置。

五、菜单的各种简单属性
在 Menu Editor 里有许多确认框和一些正文框及一个下拉式的列表框,这些东西决定了
菜单的各种属性。
1,Checked 属性
这个属性值设置为真,将在菜单命令左边产生一个打勾的确认标志,你可以看看 File
Manager 里的 View 菜单就可以了解什么是确认标志了。
2,Enabled 属性
各种各样的用户会产生千奇百怪的操作,在许多 Edit 菜单里都会有不同形式的让菜单
命令模糊的情况。Enabled 属性就是用来做这件事的。Enabled 属性为真,则菜单命令是清晰
的,Enabled 属性为假,则菜单命令是模糊的,这时用户就不能选中这个菜单项了。
3,Visible 属性
用户看见一个模糊的菜单而不能选的时候,有时会非常生气。所以,如果用户看不见这
个菜单命令时,他也就不会发无名之火了。如果把 Visible 属性设为假,则菜单根本不会出
现在屏幕上。这样做比把 Enabled 属性设为假显得更加干脆!
4,Index 属性
可以生成菜单命令数组,用索引号区分开。例如向 File 菜单中添加一系列最近打开的文
件名。添加菜单可用 Load 方法。
以上属性可以在运行时设置,形成动态的菜单的情况。
例如:
mnuUndo.Enabled = False
mnuProperty.Visible = False
你还可以改变 Caption 等属性。
mnuUndo.Caption = “Redo”
在对窗体,命令钮和菜单有所了解后,工具箱里的其它控件就更加容易理解了。下面这
些控件的熟练运用,将使你做出漂亮的界面。
六、生成弹出式菜单(或浮动菜单)
几乎每个 Windows 应用程序都提供弹出式菜单,用户可以右键单击窗体或控件取得这个
菜单。弹出式菜单也属于普通菜单,只是不固定在窗体上,而是可以在任何地方显示。
弹出式菜单用 PopupMenu 方法调用。假设我们已经用 Menu Editor 生成了名为 mnuedit
的菜单,则可以在 MouseUp 事件加入如下代码:
If Button = 2 Then PopupMenu mnuedit
下面将用一个实例展示动态菜单和弹出式菜单。

左图表单显示了一个弹出式菜单,在表单的空白处右击鼠标就可得到。左图表单显示
了一个动态菜单,单击 Add runtime option 钮一下就会使菜单 Runtime Menu 增加一项,而单
击 Remove runtime option 钮一下就会使菜单 Runtime Menu 减少一项。其源代码如下:
Dim rtmenu
Private Sub cmdadd_Click()
rtmenu = rtmenu + 1
If rtmenu = 1 Then mnuoption(0).Caption = "Runtime Option"
Load mnuoption(rtmenu)
mnuoption(rtmenu).Caption = "option #" & rtmenu
End Sub

Private Sub cmdremove_Click()


If rtmenu = 0 Then
MsgBox "menu is empty"
Exit Sub
End If
Unload mnuoption(rtmenu)
rtmenu = rtmenu - 1
End Sub

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)


If Button = 2 Then PopupMenu mnuedit
End Sub

§4 框架,确认框和选项钮
一、确认框和选项钮就好比多项选择和单项选择,在考试时选择题总比简答题要好做,
因为你可以用瞎蒙的策略。用户界面设计的保持简单的原则使确认框和选项钮成为有用的框
件。确认框和选项钮用于向程序输入信息。确认框选中时会在小方框里打一个钩,菜单设计
窗口里就有这种确认框的例子。
选项钮选中时会在小圆圈里点一个点。它们的主要属性除了 Name,Caption 等,还有:
1,Value 属性
决定它们是否被选中的属性。
2,Alignment 属性
决定它们的对齐方式。
二、有两道选择题或更多时,我们就必须对它们进行分组。这种分组需要借助框架控件。
分组的方法是:
1,在工具箱里单击 Frame 控件;
2,在窗体里拖曳鼠标画出框架;
3,在工具箱里单击确认框或选项钮控件;
4,在框架里画确认框或选项钮;
5,把所需的确认框或选项钮都画好。

§5 正文框和标签

正文框通常用于向计算机输入信息,而标签通常用于输出信息。正文框是一个十分重要
的控件,因为由确认框和选项钮向程序输入的信息毕竟只有少数的几条信息而已。标签和正
文框的区别很小,标签可以看成是一个在运行时不能修改正文的正文框。因此标签主要用于
输出信息。标签是生活中不可缺少的部分,比如教室里的“团结,勤奋,严谨,活泼”就是
一个每天不得不面对的标签。
1,BorderStyle 属性
决定了正文框和标签的边框形式。
2,正文框的 Text 属性和标签的 Caption 属性
这两个属性其实是一样的,它决定了用户在屏幕上看到的东西,只不过正文框的 Text
属性在运行时可以直接在正文框里修改。
3,Alignment 属性
这个属性决定正文或标题的排列方式。
4,正文框的 Multiline 属性
如果正文框里的字太多了,超过了正文框的宽度,那么计算机就在某个我们不知道的地
方显示这行字,所以我们要设置 Multiline 属性为 True,这样正文框就有了字换行的能力。
5,正文框的 PasswordChar 属性
如果用户从事的是一种掌握大量金钱或机密的工作的话(此类用户肯花大钱来买关于计
算机的东西),那么他就需要对自己的工作遮遮掩掩,在 Visual Basic 里你可以作一个口令
正文框来实现这种遮掩。方法是:
(1)选中作为口令正文框的正文框。(它的周围出现八个小方块)
(2)按 F4 键打开属性窗口。
(3)设置 Multiline 属性为 False。
(4)设置 PasswordChar 为用于掩盖的字符。(只能是一个字符,比如 * 号)

第三步使口令正文框只有一行,因为 Multiline 属性为 True 将使 Password 属性失效。


Visual Basic 认为口令不必太长,因为太长的口令更加容易忘记。
6,正文框的 Maxlength 属性
为了防止一些古怪用户输入太多的废话,程序员有限制正文框正文长度的权力,这就是
Maxlength 属性。如果 Maxlength 属性设置为零,那么正文框就只受计算机内存的限制了。
7,Label 的 AutoSize 属性和 WordWrap 属性
这两个属性在一起搭配使用总是让人混淆,以至于 Visual Basic 附带的示例程序里有一
个程序里有这两个属性的例子,它的路径通常是 c:\vb\samples\controls\control.vbp。在 Visual
Basic 里运行这个例子,选择 Options 菜单的 WordWrap and AutoSize。AutoSize 属性使标签自
动地扩大缩小以适应标签的 Caption 属性,但是它只会水平伸展。WordWrap 属性使标签具有
字换行处理的能力。
为了使标签具有垂直伸展和字换行处理,必须设置它的 AutoSize 属性和 WordWrap 属性
同时为 True。
AutoSize 属性为 False , WordWrap 属性为 False 时,若标签不够高而 Caption 太长时,
Caption 将被切割掉。
AutoSize 属性为 False,WordWrap 属性为 True 时,情况同上。
AutoSize 属性为 True ,WordWrap 属性为 False 时,表示可以水平伸展,但只显示一行
信息。
Locked 属性
程序员可以阻止用户改变文本框的内容,用户只可以看文本而不能改变它。这是 Visual
Basic 4.0 的新功能。
§6 图形框(Picture Box)和图象框(Image Box)

Picture Box 和 Image Box 是用来把图形放入程序里的。Picture Box 和 Image Box 可以显示


几种不同格式的图形。Bitmap 文件(.BMP 或.DIB)、Icon 文件(.ICO 或.CUR)、Metafile 图
元文件(.WMF)、增强型图元文件(.EMF)、JEPG(.JPG)及 GIF(.GIF)文件。在 Visual Basic 里
Microsoft 大 概 送 给 了 我 们 几 百 个 上 述 前 三 类 文 件 , 它 们 的 路 径 通 常 是 :
c:\vb\bitmaps、c:\vb\icons、c:\vb\metafile。它们的主要属性有:
1,设置 Picture Box 和 Image Box 的 Picture 属性
(1)单击 Picture Box 或 Image Box。
(2)按 F4 键打开属性窗口。
(3)单击 Picture 属性。
(4)单击设置框右边的省略号,Visual Basic 将显示 Load Picture 对话框。
(5)选择用户需要的文件,单击 Ok 键。
则 Visual Basic 将图形装入 Picture Box 或 Image Box。如果想在程序运行期间装入或删除
图形,就需要用程序代码来实现了。我们可以使用 Load Picture 函数。例:
装入图形
imgMyHand.Picture = LoadPicture ( “c:\graphics\hand.bmp” )
删除图形
imgMyHand.Picture = LoadPicture ( “ ” )
2,Picture Box 和 Image Box 的 BorderStyle 属性
如同正文框和标签一样,你可以设计 Picture Box 和 Image Box 的边框。
3,Stretch 属性和 AutoSize 属性
Image Box 只有 Stretch 属性,而 Picture Box 只有 AutoSize 属性。
AutoSize 属性设为 True,则 Picture Box 改变自己的大小来适应其中的图形。
Stretch 属性设为 True,则 Image Box 中的图形将改变自己的大小来适应外面的边框。

§7 Line 和 Shape 控件
总有一些除了装饰作用没有别的功能的东西。如 Line 和 Shape 控件。
1,Line 和 Shape 的 BorderColor 属性
一般来说边界颜色是黑的,但你也可显示你喜爱的颜色。在属性窗口里单击 BorderColor
属性,再单击省略号,Visual Basic 将显示一块调色板,在调色板里选择你喜爱的颜色。
2,Line 和 Shape 的 BorderWidth 属性
这个属性决定线的粗细。
3,Line 和 Shape 的 BorderStyle 属性
这个属性决定线的轮廓。
4,Shape 的 FillStyle 属性
在形状中我们可能更加喜欢实心的样子,这也可以做到。

我们已经了解了窗体,菜单,及十种不同的控件,这正是 Windows 的基本元素,再加


上它们的各种属性,就可以画出各式各样的用户界面了!

§6&§7 总结:Image、Shape 和 Line 控件有时被称作轻量图形控件。它们需要较少的

系统资源,因此比 PictureBox 控件显示得快并且包含 PictureBox 中可用的属性、方法和事


件的子集。每一个控件都适用于一个特定的目的。
1、其它控件的容器: PictureBox 2、Printing 或 graphics 方法: PictureBox 3、显示图片
Image 或 PictureBox 4、控件显示简单图形元素:Shape 或 Line 控件

第三章 编程的 基础

在我们设计完用户界面后,我们就将开始了编写指令代码的过程。这是一个相对枯燥但
却是必须的过程。

§1 Visual Basic 编程概述


一、事件驱动应用程序
简单地说就是当事件发生时程序才工作,否则程序将等待事件的发生。在事件驱动程序
中,用户的操作或系统事件执行一个事件过程,这样,程序执行的顺序就由哪一个事件的
发生决定,由用户的操作决定。就是用户管理,代码响应。
二、事件过程
用户界面对事件响应的三个部分是:
1,窗体
2,控件
3,菜单
编写程序代码的通常过程是:
1,确定哪一个对象(窗体,控件或菜单)做出反应——单击此对象选中它;
2,打开代码窗口——简单的方法是按 False7 键或者双击对象;
3,找到响应的事件;

代码窗口的 Object 列表框可以选择对象,旁边的 Proc 列表框可以选择对象的事件。如果


事件已经有了代码的话,那么在 Proc 列表框里这个事件名用黑体显示。空的事件代码都由
两行组成,如:
Private Sub Form_Load()
|
End Sub
4,编写程序代码。
三、变量
程序总是要做三件事:
1,得到数据;
2,处理数据;
3,输出数据。
在程序运行时,这些数据被储存在变量里,变量可理解为计算机内存条上的一个微观
的东西。一旦关机,变量就消失了。变量在 Visual Basic 里有两种类型:
1,程序员建立的变量;
2,对象的属性往往也看成变量。
变量必须满足:
1,字母开头;
2,不超过 40 个字;
3,只包括字母,数字,下划线;
4,不是保留字。
创建变量的方法:
1,用 Dim 语句说明它;
2,可以省略声明语句而用变量声明字符生成确定类型的变量。在程序执行时若要生成
变量并指定数据类型,可加入下表所示的变量声明字符后缀。
符号 数据类型 举例
$ String A$, message Text$
% Integer Counter%, var%
& Long Population&,colorValue%
! Single Distance!
# Double ExactDistance#

3,把一个值赋给一个名称,Visual Basic 就把这个名称看成变量。


Dim 语句的语法是:
Dim VariableName As Type
例如: Dim MyName
As Type 部分可以省略,它涉及到我们将要讲的关于数据类型的问题。 Dim 语句的作用
是声明变量并分配存储空间。
赋值语句的语法是:VariableName = Value 或 VariableName1 = VariableName2
与数学中的等号意义不同,这里等号只表示把后者的值赋给前者,所以, A = A + 1
在 Visual Basic 里是合法的。例如:cmdExit.Caption = “Exit” (这是一个改变对象属性的例
子)
四、数据类型
变量可以存放数字或字符串等东西,但是 MyName 变量并不需要存放数字,所以你可
以限制存放的数据类型。你可以规定 MyName 只能字符串。Visual Basic 提供了七种数据类型:
1,整型(Integer)
2 字 节 整 数 , 标 识 符 ( 同 上 面 的 变 量 声 明 字 符 ) 为 百 分 号 ( % ) , 范 围 从 -32768 到
32767,运算很快。
2,长整型(Long)
4 字节整数,标识符为&,范围从-2147483648 到 2147483647,运算很快。
3,单精度型(Single)
4 字节浮点数,标识符为!,范围可达 38 位数字,前 7 位可靠,运算比整型和长整型慢。
4,双精度型(Double)
8 字节浮点数,标识符为#,范围可达 300 多位,但是可靠的只有前 16 位数字。
5,字符串型(String)
标识符为$,在 32 位版本的 Visual Basic 4.0 中,字符串可容纳高达 200 兆字节的内容。
6,货币型(Currency)
8 字节定点数,标识符为@,小数点右边 4 位,左边 15 位。
7,日期型(Date)
用于存放日期,范围从 #January 1,100# 到#December 31,9999#,日期的格式取决于系统
的设定,赋值方法是:New = #January 1,2000# 。
8,字节型(Byte)
Visual Basic 4.0 新增加的数据类型,用于存放 0 到 255 的整数。
9,布尔型(Boolean)
只有 True 或 False 两个值。
10,变体型(Variant)
如果你不告诉 Visual Basic 你的变量是什么类型, Visual Basic 就自动把它看成变体型。
变体型的意思就是它没有类型,或者是任何类型。如果声明了 Variant 变量而未赋值,则其
值为 Empty。
例如:Dim MyName As String
事实上,语句 Dim MyName 只是将 MyName 变量声明为变体类型罢了,因为变体类型
是 Visual Basic 的缺省类型。但是,我们使用数据类型的原因是什么呢?
1,使用最小的数据类型可节省内存;
2,程序员可以容易地找出每一变量所存放的数据类型;
3,可以防止数据类型存放错误引起的错误。
例如:
Private Sub Form_Load()
Dim MyName As String
MyName = “DongShan”
End Sub

变换变量类型
有时需要将一种变量类型变成另一种变量类型,下表列出了进行变量类型转换的函数:

函数 说明 函数 说明
Cbool 将变元变成布尔值 CLng 将变元变成长整型值
Cbyte 将变元变成字节值 CSng 将变元变成单精度值
CCur 将变元变成货币型值 CStr 将变元变成字符串值
CDate 将变元变成日期值 Cvar 将变元变成变体值
CDbl 将变元变成双精度值 CVErr 将变元变成错误值
CInt 将变元变成整型值

例如要将如下的初始化变量:
Dim A As Integer
变成双精度值,可用下列函数:
B=CDbl(A)

用户自定义的数据类型 ------记录
保存多个相同或不同类型数值的结构称为记录(record)。
在 VISUAL BASIC 中定义记录,用 Type 语句,其语法如下:
Type varType
Variable1 As varType
Variable2 As varType

Variablen As varType
End Type
例如定义一个名为 CheckRecord 的记录:
Type CheckRecord
CheckNumber as Integer
CheckDate as Date
CheckAmount as Single
End Type
CheckRecord 结构可以像普通变量类型一样使用。要定义这个类型的变量,使用如下语
句:
Dim check1 As CheckRecord
要对结构的各个字段访问, 可使用如下语句:
check1. CheckNumber=123
check1. CheckDate=#08/14/1996#
check1. CheckAmount=240.00

强制的变量声明
Visual Basic 并不要求变量声明,但对于编写大型应用程序时,变量声明的确很有好处。
因此 Visual Basic 提供强制声明的方法,只要在窗体或模块的声明部分加上一条语句:
Option Explicit
这个语句使编译器检查每个变量的声明,如果要用的变量没有声明,则发出一个错误
消息!

数组
单个变量只能存放单个实体,而数组可以存放一组相关的数据。像变量一样,数组有名
称,存放在数组中的数值通过一个索引来访问。
数组的定义必须用 Dim 语句声明,如下:
Dim Names(9) As String '也可以不指定数据类型
Names 是保存了 10 个元素的数组,Names(0)是第一个元素,Names(9)是最后一个元素。
数组元素的赋值如下:
Names(0)="John"
Names(1)="Tom"

Names(9)="Xionghui"
数组的第一个元素的索引可以不是 0,可以在 Dim 语句中指定下限:
Dim Names(1 To 16)
Dim Names(5 To 16)

动态数组
有时可能不知道需要多大的数组,这时可以生成动态数组,其长度可以在运行程序时改
变。定义动态数组,和平常一样用 Dim 语句(或 Private 和 Public),但不要指定长度(或
维数):
Dim DynArray()
后面等能确定维数的时候,再用 ReDim 语句重新确定实际长度(或维数):
ReDim DynArray(UserCount)
ReDim 语句只能出现在过程之中,它是可执行语句。
但每次执行 ReDim 语句,数组中原先存放的所有当前值会消失。但有时可能想改变数
组的长度,而不损失原有的数据,幸好 Visual Basic 提供了 Preserve 关键字,它就能作到!
例如下面语句将数组加大一个元素而不改变原有数据:
ReDim Preserve DynArray(Ubound(DynArray)+1)

五、变量的使用范围
Visual Basic 的变量有三种使用范围。
1,局部变量;
2,模块级变量,也可以叫做窗体级变量,因为窗体和模块是同级的;
3,全局变量。
局部变量只存在于说明它的过程里,为说明一个局部变量,应在一个事件过程中说明。
模块级变量可存在于这个窗体或模块中,可以被所有窗体内的事件过程所引用和改变 ,
说明模块级变量的方法是:
1,按 F7 键打开代码窗口;
2,在 Object 列表框中选择(general);
3,在 Proc 列表框里选择(declarations);
4,用 Dim 语句说明。
全局变量从程序开始时存在至程序结束,不过全局变量的错误也许会导致致命的错误 ,
你不得不读遍程序来寻找到底在说明地方改变了全局变量。创建全局变量的方法是:
1,从 Insert 菜单里选 Module 项,这个命令为一个 BAS 模块文件显示代码窗口;
2,在 Object 列表框中选择(general);
3,在 Proc 列表框中选择(declarations);
4,用 Public 语句说明全局变量。
六、算术,逻辑,比较运算符
1,算术运算
尽管一台上万元的计算机看来很高科技,但它在算术运算方面并不比一个几十元的计
算器强多少。

运算符 运算 运算符 运算
+ 加(也是字符串拼接) \ 整数除
- 减(也是取负值) Mod 取余数
* 乘 ^ 乘方
/ 浮点数除 & 字符串拼接
2,逻辑运算
逻辑运算是对 True 和 False 进行操作的运算。Visual Basic 将 True 的值看成-1,将 False
的值看成 0。

运算符 使用 意义
And 变量 1 And 变量 2 两个量均为 True ,才返回 True
Or 变量 1 Or 变量 2 只要有一个量为 True ,返回值就为 True
Xor 变量 1 Xor 变量 2 两个量一个为 True,一个为 False 才返回 True
Not 变量 1 Not 变量 2 简单地把 True 变为 False ,把 False 变为 True

3,比较运算
比较运算是比较两个数或字符串的大小。

运算符 意义 运算符 意义
< 小于 >= 大于等于
<= 小于等于 = 等于
> 大于 <> 不等于

有时候,复杂的运算会把我们搞晕,良好的习惯是加括号。如:x = ( 5 * ( 8 + 9 ) ) ^ 2,
则计算机先处理 ( 8 + 9 ) ,再处理 ( 5 * ( 8 + 9 ) ) ,最后才是乘方。再如:x = ( 5 * 6 ) / 2,这
个括号加得似乎没什么意义,但它使我们清晰地知道是从哪儿开始运算的。
七、字符串操作
有时程序需要对字符串进行操作,比如从一个文件的完整路径名中找出文件的名称。下
面介绍几个常用的函数。
1,Len 函数
返回字符串的长度。如 Length = Len(“string”),则 Length = 6。
2,LCase 函数,UCase 函数
LCase 函数把字符串变为小写字母。UCase 函数把字符串变为大写字母。如:
x = LCase (“DONGSHAN”)
x = UCase (“visual Basic”)
3,Left 函数,Right 函数
语法是:
Left (VariableName , N)
Right (VariableName , N)
Left 函数从字符串的左边提出 N 个字符。Right 函数从字符串的右边提出 N 个字符。
4,Mid 函数
语法是:
x=Mid (VariableName , n, m)
Mid 函数从 VariableName 字符串的第 n 个字符开始取出 m 个字符。
5,Instr 函数
语法是:
Instr (VariableName1 , VariableName2)
Instr 函 数 从 VariableName1 里 找 出 VariableName2 的 位 置 。 如 : x = Instr (“ABCD” ,
”CD”),此时 x = 3。如果计算机没找到要找的字符串,则这个函数返回 0。
6,LTrim 函数,RTrim 函数,Trim 函数
LTrim 函数将去掉字符串前的空格。
RTrim 函数将去掉字符串后的空格。
Trim 函数将去掉字符串前后的空格。如:x = RTrim (“John “),此时 x = “John”。
7,Val 函数
语法是:
x = Val (VariableName )
这个函数将字符串里的数字字符串转化为数字。如:Y = Val (“123”),则 Y = 123。
当 Visual Basic 发现下一个字符不是数字时就停止继续转化。
8,Str 函数
与 Val 函数相反,Str 函数将数字转化为字符串。
语法是:
x = Str (VariableName )
八、常量及注释
1,使用常量
如果我们编一个程序从每笔收入中拿出 40%用于饭卡的消耗,则在程序中我们会总是
用到 0.4 这个数字。这时粮食涨价了,我们不得不把 0.4 全都改成 0.5,这就显得非常麻烦。
我们本可以定义并使用一个常量为 0.4,在涨价时把它小小调整一下就可以了。常量命名的
要求与变量一样。常量的使用范围也与变量一样,分为:局部常量(在过程里用 Const 说
明)、 模块级常量(在窗体,模块的声明区用 Const 说明)、全局常量(在模块的声明区
用 Public Const 说明)
2,使用注释
用 “ ‘ “ 注释。如:‘ This Sub is used to get Windows version
撇号右边的东西 Visual Basic 通常用绿色的字来显示,而且 Visual Basic 将忽略注释的东
西。在 Visual Basic 4.0 所附的示例程序里使用了大量的注释,这样使其他人(也包括自己)
能更好地读懂程序,所以使用注释是一个好习惯。
注释的忽略性也有一些小用处,如:
x = ( 3.5 ^ 2 - 4 ) * ( 5 + 6.73 * 7 \ 2 ) - 10.89
现在你需要测试这一语句是否是必要的,于是你把它删除,再运行看是否能得出正确
的答案,如果它是不必要的,那就很顺利,如果它是必要的,你就不得不痛苦地再输入一
遍而且还有输错的可能。现在你可以选择把它注释掉,这样程序运行将忽略它的存在,也可
达到上面测试的目的。

§2 Visual Basic 的语句


一、条件选择语句
人们面临选择的时候精神会变得脆弱,这就是为什么我们总是轻信偷看来的答案。因此,
选择对于人类来说是一件复杂的事情,而对于计算机来说,则非常简单。它头脑简单,因而
永远不会发出哈姆雷特式的疑问——“是生,还是死?”
1,条件式
条件式必然代表一个值,是真( True )或者是假( False)计算机可以检测出这个值以
做出相应的行动。下面就是判断的例子,其中加下划线的部分就是指条件式。
If Love = True Then...
与之相同的简略的形式是:
If Love Then...
而 If Love = False Then... 与 If Not Love Then... 的意义是相同的。
条件式中可加入逻辑运算符,如:
If x < 20 And x > 15 Then 表示当 15 < x < 20 程序将做什么。
If x < 15 Or x > 20 Then 表示当 x < 15 或 x > 20 时程序将做什么。
2,If - Then 语句
语法是:
If Condition Then Instruction
例如: If n > 25 Then txtABC.Text = “ABC”
3,If - Then - End If 语句
If Condition Then
Instruction 1
Instruction 2
End If
这种结构可指示计算机执行一串语句。
4,If - Then - Else 语句
If Condition Then
Instructions1
Else
Instructions2
End If
这种结构指示计算机在条件不成立时应该做的事,这样保证了计算机至少执行一些语
句。
5,If - Then - Else If 语句
If Condition 1 Then
Instructions 1
ElseIf Condition 2 Then
Instructions 2
ElseIf Condition 3 Then
Instructions 3
Else
Instructions 4
End If
类似这样的完整的语句可做出多次判断,又保证计算机至少执行一些代码。
6,Select - Case 语句
被选择的值为许多定值时,这个语句就更有用一些。
Select Case VariableName
Case Value 1
Instructions 1
Case Value 2
Instructions 2
Case Value 3
Instructions 3
End Select
Select - Case 语句的不足是它需要确切的值。
7,嵌套结构
我们可以把许多各式各样的条件语句嵌套在一起,而且这种嵌套在理论上没有限制。但
事实上嵌套使用得越少,代码就越容易被理解。在嵌套时最好使用便于观察的缩排的格式。
如:
Select Case Grade
Case "95"
If Class = "31" Then
Dorm = "1106-1108"
ElseIf Class = "33" Then
Dorm = "1104-1105"
End If
End Select

二、循环语句
计算机擅长反复地做一件事,循环语句将发挥它的这种优势。
1,Do - Loop 循环
Do - Loop 循环基本上是一个死循环,所以需要在循环时判断一些条件。
(1)Do While 循环 当 Condition 条件为真时执行循环
Do While Condition
Instructions
Loop
While 也可以放在 Loop 语句上。
(2)Do - Loop While 循环
Do
Instructions
Loop While Condition
这两种循环的不同之处是: Do While 循环先判断条件,所以, Do While 循环可能一次
都不执行。Do Loop While 循环先执行指令,再判断循环条件。所以 Do Loop While 循环至少
执行一次指令。但它们都是当一定条件为真时的循环。
(3)Do Until 循环 当一定条件为假时执行循环
Do Until Condition
Instructions
Loop
Do Until 先判断条件,所以循环可能一次都不执行,它是当一定条件为假时的循环。
Do Until 等同于:
Do While Not Condition
Instructions
Loop
(4)Do Loop Until 循环
Do
Instructions
Loop Until Condition
Do Loop Until 先执行指令再判断循环条件,所以指令至少被执行一次。Do Loop Until 是
当一定条件为假时的循环。
2,计数的循环 For - Next
(1)For - Next 循环必须有一个控制变量,这个控制变量一般为整型。语法是:
For Counter = Start To End
Instructions
Next Counter
这里的 Counter 就是控制变量。如果想运行 5 次,可用下面的循环:
For i = 1 To 5
Instructions
Next i
这时,每循环一次,i 的值就加 1。
(2)向前向后计数
For Counter = Start To End Step Increment
Instructions
Next Counter
Increment 表明每次循环控制变量所加的值。如下面代码也可循环 5 次:
For i = 5 To 1 Step -1
Instructions
Next i
只有当 Counter <= End 时循环才执行,当 Counter > End 的时候循环就不执行了。所以
For i = 1 To 10 Step 7
Instructions
Next i
循环将执行两次,一次是当 i = 1 时,一次是当 i =8 时。
最好不要在循环内改变控制变量的值,这样往往会导致逻辑上的错误。
3,与条件语句一样,循环语句也可以嵌套。如:
Do While Condition
For i = 1 To 5
Instructions
Next i
Loop
循环总是先从内部开始的。比较:
For i = 1 To 4 For i = 1 To 4
For j = 1 To 5 For j = 1 To 5
Next j Next i
Next i Next j
是允许的 这种 For - Next 的缠绕是不允许的
4,从循环中快速退出
通过使用命令 Exit Do 和 Exit For ,我们可以在循环未结束前跳出循环。但我们应该保
证所需的动作完成后再跳出来,否则也许会遇到新的错误。而且不要试图用 Goto 语句从循
环外跳入循环。
下面的代码可以检测出 3 至 20 之间的质数。其中使用了循环的嵌套及条件语句,并且
当发现 i 不是质数时立即用 Exit For 转向对下一个数的检测。
Sub Form_Click ()
Dim i, j, x As Integer
For i = 3 To 20
x = False
For j = 2 To i - 1
If (i Mod j) = 0 Then Exit For
If j = i - 1 Then x = True
Next j
If x Then Print i
Next i
End Sub
三、建立过程与函数
如同常量的定义一样,有时不仅仅是几个数字反复出现在程序中,而且是很多段代码
在做几乎同样的事,如果有一些通用的代码可供调用的话,那么程序就会简练得多,而且
更为清晰,这就是过程与函数。过程和函数保存在 FRM 文件和 BAS 文件里。若一个过程保
存在 BAS 文件里,那么这个过程可供程序里所有的代码调用;如果一个过程保存在 FRM
文件里,那么这个过程只能被本窗体里的代码调用到。创建过程或函数的简单方法是选择
Insert 菜单的 Procedure 项。过程名,函数名的命名规则与变量名,常量名的命名规则一样。
1,过程结构
Sub subname (argumentlist)
Instructions
End Sub
argumentlist 指的是参数列表,所谓参数,就是指过程操作所需的指导条件。如下面过程:
Sub PrintHello (n As Integer)
Dim i As Integer
For i = 1 To n
Print "Hello"
Next i
End Sub
n 参数就是指导这个过程打印 “ Hello” 的个数。当有许多参数时,可用 “ ,” 将它们分
开。
如果在 Form_Click 事件过程里调用 PrintHello 过程,就可用键入:
Call PrintHello(5) ‘其中 Call 是 Visual Basic 的保留字
PrintHello 5
后一种省略 Call 和括号的方法使这个过程看起来更象一个 Visual Basic 的语句,所以我
们可以这样认为:建立好的过程可以当作语句来使用。
2,函数结构
函数结构与过程结构基本上是一样的。
Function functionname (argumentlist) As type
Instructions
End Function
函数就是有返回值的过程,它自己是有数据类型的。但 As type 部分是可以省略的,这
时函数的返回值将是变体类型的值。在调用没有参数的函数时也必须加括号。如:
Function Total (a As Integer, b As Integer, c As Integer) As Integer
Total = a + b + c
End Function
调用时可以这样:
Answer = Total (10, 20, 30)
又如:
Function CurrentTime ( ) As String
CurrentTime = Time
End Function
调用时应该这样:
s = CurrentTime( )
我们看出建立好的函数与 Visual Basic 本身的函数在调用时也没有什么不同。程序员可
以建立自己的过程与函数库以加快编程效率。
3,传值方式
当过程内改变了参数的值时,Visual Basic 并不会产生错误信息,但这样可能引起一些
混乱,如:
Sub PassedNotByValue (x As Integer)
x=x+1
End Sub
在事件过程中调用:
Sub Form_Click ()
Dim i As Integer
i = 1000
PassedNotByValue i
Print i
End Sub
结果会是什么呢?是 1001。在复杂的过程里不小心改变了参数的值,而调用过程的代码
里这个参数又不应该改变的情况是很有可能发生的。改进的方法是:
Sub PassedByValue (ByVal x As Integer)
x=x+1
End Sub
调用改为:
Sub Form_Click ()
Dim i As Integer
i = 1000
PassedByValue i
Print i
End Sub
结果将是 1000,这就是传值方式,传值方式在参数行开始处加上 ByVal 保留字。属性
总是用传值方式传递的。

第四章 Windows 95的新 控件 Visual Basic的输入 输

§1 ToolBar(工具条)控件
ToolBar 就是那些在菜单下面的图形钮,这已经成为 Windows 应用程序的样板。
1、 建立工具条
1,在工具箱里单击工具条图标,拖到窗体的任何位置, Visual Basic 自动将 ToolBar 移
到顶部。
2,按 F4 键打开属性窗口。
3,双击(Custom),打开 ToolBar 属性窗口。
4,选择 Buttons 标签。
5,单击 Insert 按钮,Visual Basic 就会在你的工具条上显示一个空按钮,现在为你的每
一个按钮重复这一步。
6,单击确定按钮。
如果你想把按钮分组,首先生成一个分隔的按钮,再在刚才提到的对话框里将这个按
钮的 Style 属性改为 3-Separator。
2、 为工具条增加图画

1,在 Visual Basic 工具箱里单击 ImageList 图标 ,并将它拖到窗体的任何位置(位

置不重要,因为它总是不可见的)。
2,按 F4 打开属性窗口。
3,双击(Custom),打开 ImageListCtrl 属性窗口。
4,选择 Image 标签。
5,单击 Insert Picture,在现在图形的对话框里选择你想使用的位图或图标,然后单击
打开按钮。为每个你想添加图形的工具条按钮重复此步。
6,单击确定按钮。
7,单击你的工具条,按 F4,双击(Custom),显示 ToolBar 属性对话框。
8,选择 General 标签,在 ImageList 框里选择刚才添加的 ImageList 控件。
9,选择 Buttons 标签,单击紧挨 Index 框的向左或向右箭头以选择一个按钮序号。出现
在工具条最左边的按钮序号为 1。
10,在 Image 框里输入一个数,输入为 1,则显示刚才 ImageList 控件里的第一个图形,
输入为 2,则显示刚才 ImageList 控件里的第二个图形。
11,为每个按钮重复第 10 和第 11 步。
12,单击确定按钮,现在 Visual Basic 就会在工具条上显示精美的图形了。
3、 为工具条添加文本信息
在刚才提到的 ToolBar 属性对话框中选择 Buttons 标签,在 Caption 框里输入你想显示在
按钮上的文本。
4、 添加 ToolTips
ToolTips 是一种当你点到工具按钮是弹出的小标签。 ToolTips 很方便,可以告诉那些新
手每个按钮是干什么用的。在刚才提到的 ToolBar 属性对话框中选择 Buttons 标签,在
ToolTipText 框里输入你想作为 ToolTip 的文本。
5、 如何编写代码
双击你的工具条,以下面的格式输入代码就可以了。
Private Sub Toolbar1_ButtonClick(ByVal Button As Button)
Select Case Button.Index
Case 1
'Code to follow if user clicks the first button
Case 2
'Code to follow if user clicks the second button
Case 3
'Code to follow if user clicks the third button
End Select
End Sub

§2 StatusBar(状态条)控件

和 ToolBar 一样,选中状态条,按 F4 键进入属性窗口,双击(Custom)可以进入主要


的设置窗口 SBarCtrl 属性窗口。
1、 选择面板形状
在 SBarCtrl 属性窗口里选择 General 标签,在 Style 列表框里选择多面板(缺省形式)
或单面板简单文本形式。
2、 添加或删除状态条面板
在 SBarCtrl 属 性 窗 口 里 选 择 Panels 标 签 , 单 击 Insert 按 钮 添 加 一 个 面 板 , 或 单 击
Remove 按钮删除一个面板。
3、 在单面板里显示文本
在 SBarCtrl 属性窗口里选择 General 标签,在 SimpleText 框里输入你想显示在状态条面
板里的文本。用代码显示的方式是:
StatusBar1.SimpleText = "New string to appear"
四、在多面板里显示文本或图形
1,在 SBarCtrl 属性窗口里选择 Panels 标签,用 Index 旁的按钮选择面板序号。
2,在 Text 框里输入你想显示在状态条面板里的文本。
3,如果你想加入图形,单击 Browse 按钮打开一个图形选择对话框,选择你想加入的
图形,然后单击打开按钮。
4,最后按确定按钮。
5,用代码显示的方式是:StatusBar1.Panels(x).Text = "New string to appear"
5、 如何编写代码
如果是一个单面板状态条,当用户单击状态条时,只需用下面的事件过程来响应:
Private Sub StatusBar1_Click()
End Sub
如果是一个多面板状态条,就需要鉴别用户单击的是哪一个面板,可用下面的事件过
程来识别用户所单击的面板:
Private Sub StatusBar1_PanelClick(ByVal Panel As Panel)
Select Case Panel.Index
Case 1
'Code to follow if user clicks the first panel
Case 2
'Code to follow if user clicks the second panel
Case 3
'Code to follow if user clicks the third panel
End Select
End Sub

§3 ProgressBar(进程条)控件

1、 进程条的三个属性
1,Min 属性代表进程条全空时的值,缺省时为 0。
2,Max 属性代表进程条全空时的值,缺省时为 100。
3,Value 属性代表进程条当前的值(不用在属性窗口里找这个属性,它不出现在属性
窗口中,但它的确存在),它大于 Min 属性,小于 Max 属性。改变 Value 属性的值
将改变进程条的进度显示。
为了了解进程条的功能,在窗体里添加一个进程条和一个命令钮,双击命令钮进入代
码窗口,键入如下代码:
Private Sub Command1_Click()
If ProgressBar1.Value < ProgressBar1.Max Then
ProgressBar1.Value = ProgressBar1.Value + 5
Else
ProgressBar1.Visible = False ‘当进程条满了的时候让进程条消失
End If
End Sub

§4 Slider(滑块)控件

一、选择滑块的外观
1,Orientation 属性决定滑块的方位,可以是垂直的或水平的滑块。
2,TickStyle 属性决定滑块标记的样子。
3,TickFrequency 属性规定了沿着滑块的标记的间隔大小,缺省的状态是 1,表明每个
可能值都出现标记,如果你把值设置为 3,则每三个可能值出现一个标记。
2、 滑块的 Min,Max,Value 属性
这三个属性和进程条的这三个属性差不多, Min , Max 表示滑块的最小和最大值,
Value 表示进程条的当前值。
三、滑块的 LargeChange,SmallChange 属性
LargeChange 规定了当用户用鼠标单击滑块时,滑块可移动的距离。SmallChange 规定了
用户按左箭头或右箭头时滑块的移动距离。

§5 TabStrip 控件(象笔记本书签或一组文件夹的标签)

和 ToolBar 一样,选中 TabStrip,按 F4 键进入属性窗口,双击(Custom)可以进入主要


的设置窗口 TabStrip 属性窗口。
一、设置样式
在 TabStrip 属性窗口里选择 General 标签,在 Style 列表框里选择 Tabs 或 Buttons 样式。
二、规定 TabStrip 的标题,ToolTips 和
1,在 TabStrip 属性窗口里选择 Tabs 标签,在 Caption 框里输入标题。
2,在 TabStrip 属性窗口里选择 Tabs 标签,在 ToolTipText 框里输入 ToolTip。
3、 增减标签总数
在 TabStrip 属性窗口里选择 Tabs 标签,单击 Insert Tab 按钮增加标签,单击 Remove Tab
按钮删除标签。
4、 在 TabStrip 上显示图形
1,在窗体里拖入一个 ImageList 控件,
2,按 F4 打开属性窗口。
3,双击(Custom),打开 ImageListCtrl 属性窗口并选择 Image 标签。
4,单击 Insert Picture,在现在图形的对话框里选择你想使用的位图或图标,然后单击
打开按钮。为每个你想添加图形的 Tab 按钮重复此步。
5,单击确定按钮。现在 ImageList 里存储了你需要的图形。
6,选择你的 TabStrip ,进入 TabStrip 属性窗口并选择 General 标签,在 ImageList 列表
框里选择 ImageList1。
7,现在选择 Tabs 标签,单击紧挨 Index 框的向左或向右箭头以选择一个 Tab 序号。在
Image 框里输入一个数,输入为 1,则显示刚才 ImageList 控件里的第一个图形,输
入为 2,则显示刚才 ImageList 控件里的第二个图形。
8,单击确定按钮。
5、 用户响应
可用类似下面的代码来识别用户在哪一个项目上单击。
Private Sub TabStrip1_Click()
Select Case TabStrip1.SelectedItem.Index
Case 1
'Code to follow if user clicks the first tab
Case 2
'Code to follow if user clicks the second tab
Case 3
'Code to follow if user clicks the third tab
End Select
End Sub
6、 在 TabStrip 上放置其它控件
在用户选择了标签后,TabStrip 要求你编写代码来显示或隐藏控件。下面的代码上是一
个 TabStrip 上有一个命令钮和一个选项钮的例子,当用户选择了第一个 Tab 时,选项钮出
现,当用户选择了第二个 Tab 时,命令钮出现。
Private Sub TabStrip1_Click()
Select Case TabStrip1.SelectedItem.Index
Case 1
Command1.Visible = False
Option1.Visible = True
Case 2
Command1.Visible = True
Option1.Visible = False
End Select
End Sub

§6 Visual Basic 的输入机制


程序的基本操作就是数据的输入,数据处理和数据的输出。Visual Basic 的可用于输入的
控件主要有:
正文框 Text Box 、确认框 Check Box 、选项钮 Option Button 、列表框 List Box 、组合框
Combo Box、滚动条 Scroll Bar、通用对话框控件。还有一个函数叫 InputBox 函数,也可用于
数据的输入。
一、通过正文框输入数据
1,我们只要取得正文框的 Text 属性就可以对其进行操作了。如下面代码可将 Text1 正文
框的正文变成大写输出至 Text2 正文框。
Private Sub Form_Click ()
Text2.Text = UCase(Text1.Text)
End Sub
二、通过确认框和无线钮输入数据
我们只要检测到 Check Box 和 Radio Button 的 Value 属性值就可以知道它们是否被选上
了。
3、 通过列表框和组合框输入数据

1,列表框 List Box 和组合框 Combo Box 在 Windows 的 Open,Save As 对话框里最为常


见。组合框又包括三种类型,这三种类型要在它的 Style 属性里设置。列表框仅仅把
可以选择的项目列出来,而组合框里有的类型可以允许用户输入数据。它们的异同
是:

名称 是否有下拉选项 是否允许用户输入
列表框 否 否
组合框类型 0 是 是
组合框类型 1 否 是
组合框类型 2 是 否

2,列表项目的增减
使用 AddItem,RemoveItem 语句。通常将项目增减的语句放入 Form_Load 事件里。
ListBoxName. AddItem item
ComboBoxName. AddItem item
item 是新项目名称,必须是字符串类型,非字符串类型可通过 Str 函数或 Format 函数来
转换。
列表框,组合框的每一项目都有一个 Index 值,第一个项目的 Index 值是 0,第二个是
1,依此类推。删除项目可通过删除其 Index 值来实现。
ListBoxName. RemoveItem item
ComboBoxName. RemoveItem item
如:ListBoxName. RemoveItem 0 则删除了第一项,这时原来的第二项就变成了第一项。
在 Visual Basic 4.0 里程序员终于可以在设计阶段设定列表项目了。方法是:
在 属 性 窗 口 选 择 List 属 性 , 将 出 现 一 个 下 拉 列 表 , 在 列 表 中 输 入 第 一 项 , 按
Ctrl+Enter,输入第二项……,最后用 Enter 结束。
3,取得列表框,组合框的数据
可以通过取得 Text 属性或通过取得 ListIndex 属性来判断哪一项被选择了。ListIndex 属
性的值也同样是第一个为 0,第二个为 1……如:
If List1.Text = “Visual Basic” Then Instructions
If List1.ListIndex = 1 Then Instructions
组合框有时允许用户自己输入数据,这时所输入数据的 ListIndex 值为-1。
4、 通过滚动条 Scroll Bar 取得数据

在 Visual Basic 的工具箱里有两种滚动条:一种是垂直的,一种是水平的,它们的差异


无非是摆放的方向不一样。
1,滚动条的主要属性及事件
(1)Min,Max 属性
Min 属性决定滚动条最左端或最顶端所代表的值。Max 属性决定滚动条最右端或最下端
所代表的值。
(2)LargeChange,SmallChange 属性
SmallChange 决定在滚动条两端的箭头钮上单击时改变的值。LargeChange 决定在滑块上
方或下方区域单击时改变的值。
(3)Value 属性
Value 属性代表当前滑块所处位置的值,这个值由滑块的相对位置决定。
(4)Change 事件
当滑块位置发生变化时就引发了 Change 事件。
2,取得滚动条的数据
滚动条并不是一个数据输入的好控件,因为你无法从滚动条上直接看出输入的数据,
但它的优点是可以表示一定范围里的相对位置。为了得到数据,只要取得滚动条的 Value 属
性就可以了。
五、InputBox 函数
InputBox 函数提供一个简单的对话框供用户输入信息。在把其它版本的 BASIC 程序移植
到 Visual Basic 时,InputBox 函数通常用来代替 INPUT 语句。这个对话框的样子基本上是下

面的样子。

它的完整语法是:x = InputBox (prompt, title, default, xpos, ypos, helpfile, context)


其中,prompt 是提示的字符串,这个参数是必须的。title 是对话框的标题,是可选的。
default 是正文框里的缺省值,也是可选的。xpos,ypos 决定输入框的位置。helpfile,context
用于显示与该框相关的帮助屏幕。返回值 x 将是用户在正文框里输入的数据,x 是一个字符
串类型的值。如果用户按了 Cancel 钮,则 x 将为空字符串。

六、使用通用对话框控件

Windows 应用程序里的 Open 对话框,Save As 对话框在各个应用程序里看起来都是一


样的,通用对话框控件就可以提供这些对话框的标准功能。
1,Open 对话框及 Save As 对话框
打开 Open 对话框使用 ShowOpen 方法,打开 Save As 对话框使用 ShowSave 方法。
Private Sub mnuOpen_Click ()
On Error GoTo ErrorHandler
CommonDialog1.CancelError = True
CommonDialog1.Filter = "Text Files (*.txt)|*.txt|Batch Files (*.bat)|*.bat|All Files (*.*)|
*.*"
CommonDialog1.ShowOpen ' display Open common dialog box.
Call OpenFile(CommonDialog1.FileName)
ErrorHandler:
Exit Sub
End Sub
其中第三行决定了在文件格式类型栏里出现的文件类型。第五行需要一个你自己的打开
文件的过程,这个过程需要的参数就是通用对话框返回的文件名。通用对话框的
CancelError 属性设为 True 的话,用户单击 Cancel 按钮将产生一个错误信息程序,凭借这个
信息程序可以检测到用户的放弃操作。
2,Color 对话框
下面的过程可用用户选择的颜色作为窗体的底色。
Private Sub mnuColor_Click ()
On Error GoTo CancelButton
CommonDialog1.CancelError = True
CommonDialog1.ShowColor
Form1.BackColor = CommonDialog1.Color
CancelButton:
Exit Sub
End Sub
代码的第三行出现了通用对话框的 Flags 属性决定了通用对话框的一些可选项,不过即
使不赋值给 Flags,代码也一样会按缺省的情况去执行的。
3,Fonts 对话框
下面的过程可用字体对话框改变正文框的字体。
Private Sub mnuFonts_Click ()
On Error GoTo CancelButton
CommonDialog1.CancelError = True
CommonDialog1.Flags = cdlCFBoth ' Flags property must be set to cdlCFBoth
CommonDialog1.ShowFont ' Display Font common dialog box.
Text1.FontName = CommonDialog1.FontName
Text1.FontSize = CommonDialog1.FontSize
Text1.FontBold = CommonDialog1.FontBold
Text1.FontItalic = CommonDialog1.FontItalic
Text1.FontUnderline = CommonDialog1.FontUnderline
Text1.FontStrikethru = CommonDialog1.FontStrikethru
Text1.ForeColor = CommonDialog1.Color
CancelButton:
Exit Sub
End Sub

§7 Visual Basic 的输出机制


通过正文框等控件的输入,经过程序代码的处理,现在我们要把结果输出了。作为输出
的对象,Visual Basic 提供了标签,正文框,窗体,图片框(Picture Box)等用于输出,而
且 Visual Basic 里也有一堆命令、属性涉及信息的输出,较常用的有: MsgBox 函数,Print
方 法 , Cls 方 法 , Tab 函 数 , Format 函 数 ,
FontName , FontSize , FontBold , FontItalic , FontStrikethru , FontUnderline 属 性 ,
CurrentX,CurrentY 属性等。
一、通过 MsgBox 函数输出
了解 Windows 应用程序的人都知道当用户操作错误时,应用程序往往打出一个消息框
来提示用户的错误,象这样:
Dim Action As Integer

Action = MsgBox(" 单 击 确 定 键 将 引 爆 此 计 算 机 ! ", vbYesNo + vbCritical +


vbDefaultButton2, "警告!")

If Action = 6 Then Explode

这个功能在 Visual Basic 里是通过 MsgBox 函数来实现的,这样程序员就不必自己去画


一个消息框了。语法是:
Action = MsgBox (msg, type, title)
其中,msg 是消息的内容,是一个字符串型的变量, type 及 title 参数是可以省略的,
type 参数指定显示的按钮是什么及使用什么样的图标(这个参数往往让新程序员思考几分
钟),title 参数指定消息框的标题。type 参数的含义是:

数值 符号常量 意义
0 vbOKOnly 只显示 Ok 按钮
1 vbOKCancel 显示 Ok,Cancel 按钮
2 vbAbortRetryIgnore 显示 Abort,Retry,Ignore 按钮
3 vbYesNoCancel 显示 Yes,No,Cancel 按钮
4 vbYesNo 显示 Yes,No 按钮
5 vbRetryCancel 显示 Retry,Cancel 按钮
16 vbCritical Stop Sign 对极其重要的问题提醒用户

32 vbQuestion Question Mark 增亮没有危险的问题

48 vbExclamation Exclamation Mark 强调警告用户必须知道的事情

64 vbInformation Information Mark 可以使乏味的信息变得有趣

0 vbDefaultButton1 第一个按钮缺省
256 vbDefaultButton2 第二个按钮缺省
512 vbDefaultButton3 第三个按钮缺省

例如:Action = MsgBox (“Are you girl?”, vbYesNo + vbQuestion, “Question”)。使用这个函


数时 Visual Basic 将产生一个标题为 Question,具有问号和 Yes,No 按钮的消息框。作为一
个函数,本质上还是要返回值的, MsgBox 的返回值确定了用户的选择,程序可根据返回
值做出相应的动作。

返回值 含义 返回值 含义
1 选择 Ok 按钮 5 选择 Ignore 按钮
2 选择 Cancel 按钮 6 选择 Yes 按钮
3 选择 Abort 按钮 7 选择 No 按钮
4 选择 Retry 按钮

二、Print 方法,Cls 方法,Tab 函数


1,Print 方法
我清晰地记得小学时所学的第一个计算机语句就是 Print,并且成功地用这个语句及一
堆 “*” 号 “#” 号在屏幕上打出一间小屋。Print 方法的语法是:object. Print expressionlist
object 表示 Print 作用的对象,比如是 Form 或者是 Picture Box ,object 是可以省略的,
省略时的 Print 往往在窗体上输出。expressionlist 是输出的内容,允许许多项数据的输出,在
数据间你可以加入“,”或”;”。加入分号将使下一数据项紧挨着上一数据项输出。而加入逗号,
则 Visual Basic 将下一数据项在下一打印区输出,其实就是空了几个空格后再输出。两个打
印区之间有 14 个字符的宽度,其实这也很难衡量,比如 14 个“W” 所占的宽度大概是 14
个“i”所占宽度的三倍多。幸好中国日本之类的方块字所占的宽度基本上是一样的,所以较
好处理一些。

2,Tab 函数
Tab 函数只用在 Print 方法中,它用来移动下一个字符到打印位置,这将省去你数空格
的功夫。语法是:Tab (column)
Tab 函数将 Visual Basic 自定义的 14 字符宽的打印区扔到一边,用自己的方式定义了新
的灵活的打印区宽度。
3,Cls 方法
Cls 也是一个古老的 BASIC 语句原来它的作用总是把屏幕变成黑色,然后在左上角或
左下角闪烁一个光标,Visual Basic 里它的作用是清除绘图语句和 Print 语句产生的文字和图
形。语法是:object. Cls
object 指清除的对象,可以是 Form 或 Picture Box 。如果 object 省略,通常 Visual Basic
都把当前的窗口作为 Cls 操作的对象。

三、Format 函数
Format 函数用于制定字符串或数字的输出格式。语法是:x = Format (expression,fmt)
expression 是所输出的内容。fmt 是指输出的格式,这是一个字符串型的变量,这一项若
省略的话,那么 Format 函数将和 Str 函数的功能差不多。如:

语句 输出
Format (2, “0.00”) 2.00
Format (.7, “0%”) 70%
Format (1140, “$#,##0”) $1,140

简单地,fmt 里的字符是这样的:

字符 意义 字符 意义
0 显示一数字,若此位置没有数字则 . 小数点
补0
# 显示一数字,若此位置没有数字则 , 千位的分隔符
不显示
% 数字乘以 100 并在右边加上”%”号 -+$() 这些字出现在 fmt 里将原样打出

Format 函数也可用来对时间进行输出。

fmt 输出 fmt 输出
m/d/yy 8/16/96 h:mm:ss a/p 10:41:29 p
d-mmmm-yy 16-August-96 h:mm 22:41
d-mmmm 16-August h:mm:ss 22:41:29
mmmm-yy august-96 m/d/yy h:mm 8/16/96 22:41
hh:mm AM/PM 10:41 PM

四、FontName,FontSize,FontBold,FontItalic,FontStrikethru,FontUnderline 属性
很明显,这些属性都与字体有关,许多控件都有这些属性。通常它们在设计阶段可以双
击 font 属性来设置,运行期间可以直接设置。它们的意义是:
FontName 字体的名称 FontItalic 字体是否用斜体显示
FontSize 字体的大小 FontStrikethru 字体是否有删除线
FontBold 字体是否用粗体显示 FontUnderline 字体是否有下划线

如:Text1.FontBold = True,将把 Text1 正文框的 FontBold 属性设为 True。


五、窗体,图片框的 CurrentX,CurrentY 属性
这两个不可见的属性确定了下一次打印或绘图的水平及垂直坐标。如上面讲的 Print 方法,
当 expression 后使用 “,” 时,Visual Basic 将改变 CurrentX,CurrentY 值为下一打印区域开
始 的 值 , 于 是 , 输 出 便 指 向 了 下 一 个 打 印 区 域 。 而 Cls 方 法 将 把 操 作 对 象 的
CurrentX,CurrentY 的值设为(0,0)。
六、通过标签控件输出
标签控件的特点是运行时不能直接修改它,通常一个正文框旁边都有一个标签用来标
识正文框。标签的 Autosize 和 WordWrap 属性是一对有用且令人困惑的属性。

第五章 Visual Basic的鼠标 事件和 绘图

§1 Visual Basic 的鼠标事件


Click 就 是 一 个 鼠 标 事 件 , 它 可 以 发 生 在 许 多 对 象 上 。 同 时 鼠 标 事 件 还 有
DblClick,MouseDown,MouseUp,MouseMove 以及拖曳后放下的事件。在 Visual Basic 所
附的示例程序里,有一个介绍鼠标事件的例子,它的通常的路径及文件名是:
c:\vb\samples\mouse\mouse.vbp
一、MouseDown,MouseUp 事件
MouseDown,MouseUp 事件分别发生在按下鼠标按键和松开鼠标按键时,窗体的空的
MouseDown,MouseUp 事件是这样的:
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
End Sub
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)

End Sub
1,MouseDown,MouseUp 事件与 Click 事件的不同
Click 事件不能检测到是哪一个按键按下了,也不能检测到按下鼠标的同时键盘上是否
按着 Shift,Ctrl,Alt 键,而且 Click 事件还不能确定按鼠标时鼠标指针的位置。而这些在
MouseDown,MouseUp 事件里都可以知道,这也是这两个事件过程发生时后面四个参数的
意义。在需要上面所说的参数时,可以用 MouseDown 事件或 MouseUp 事件代替 Click 事件。
2,Button 参数
这个参数确定按下的鼠标按键是哪一个。

参数值 符号常量 意义
1 vbLeftButton 按下左键
2 vbRightButton 按下右键
4 vbMiddleButton 按下中键

但是这个参数无法判断出两个键或三个键同时按下时的情况。比如当你同时按下左右键
时将引发两个 MouseDown 事件,Button 参数分别为 1 和 2,或者是 2 和 1。
3,Shift 参数
这个参数用来确定 MouseDown,MouseUp 发生时键盘是否同时按着 Shift,Ctrl,Alt 键

参数值 意义 参数值 意义
0 没按 4 Alt(常量 vbAltMask)
1 Shift(常量 vbShiftMask) 5 Shift 和 Alt 同时被按下
2 Ctrl(常量 vbCtrlMask) 6 Alt 和 Ctrl 同时被按下
3 Shift 和 Ctrl 同时被按下 7 三个键同时按下

所以 Shift 参数是可以判断多个键同时被按下的情形的。
4,X,Y 参数
这两个参数表明 MouseDown,MouseUp 发生时,鼠标指针所指向的位置。
二、MouseMove 事件
1,MouseMove 事件发生在鼠标移动的时候。窗体的空的 MouseMove 事件是这样的:
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)

End Sub
MouseMove 的四个参数与 MouseDown , MouseUp 的四个参数的意义是一样的,但
MouseMove 的 Button 参数可以判断出多个按键按下时的情形。

参数值 意义 参数值 意义
0 三个键都没按 4 中键
1 左键 5 左中键
2 右键 6 右中键
3 左右键 7 三个键都按着
2,了解了鼠标的这三个事件后就会发现 Windows Paintbrush 里的绘图也不过如此,下
面的代码就可以实现用鼠标当作画笔在窗体上乱画的功能。
把下面代码拷到窗体的声明区就可以了。
Dim Draw As Integer
Sub Form_MouseDown (Button As Integer, Shift As Integer, X As Single, Y As Single)
Draw = True
CurrentX = X
CurrentY = Y
End Sub
Sub Form_MouseMove (Button As Integer, Shift As Integer, X As Single, Y As Single)
If Draw = True Then Line -(X, Y)
End Sub
Sub Form_MouseUp (Button As Integer, Shift As Integer, X As Single, Y As Single)
Draw = False
End Sub

三、关于“拖曳后放下”的属性和方法
1,DragMode 属性
这个属性决定了拖放操作是手动还是自动方式。前者必须用 Drag 方法来让程序知道拖
曳已经开始或用 Drag 方法让程序知道拖曳结束了。而后者则计算机自己就可以知道拖曳的
开始及结束。这说明手动方式更具有灵活性,而自动方式则简单一些。

属性值 意义
0 (缺省)手动,需使用 Drag 方法初始化源控件的拖动操作
1 自动,单击源控件就可以自动初始化拖动操作

2,DragIcon 属性
这个属性确定拖放操作中显示指针的图标。在运行期间可用赋值方式或 LoadPicture 函数
给出 DragIcon 属性。如:
Image1. DragIcon = Image2. DragIcon
Image1. DragIcon = LoadPicture (“C:\VB\ICONS\OFFICE\CRDFLE01.ICO”)
3,Drag 方法
语法是:control. Drag action
control 决定被拖动的控件,action 指出执行的动作。

action 值 意义
0 取消拖动
1 开始拖动控件
2 放下控件

四、关于“拖曳后放下”的事件
1,DragDrop 事件
拖动时总是要放下的,如果拖动的控件放在了另一个窗体或控件上,就引发了后者的
DragDrop 事件。空的 DragDrop 事件基本上是这样的:
Private Sub Form_DragDrop(Source As Control, X As Single, Y As Single)

End Sub
Source 参数指明了前者——被拖动的对象,Control 类型的变量就是说明这个变量代表
一个控件,也就是控件的名字,但在传递这个参数时不必打上引号。X,Y 参数表明鼠标指
针所在的位置。
2,DragOver 事件
在拖放操作进行之中,被拖动的控件可能会从其它控件上空飘过,或者在目标控件上
空盘旋一下,这时,就引发了在被拖动控件下方的控件的 DragOver 事件,这时它可以修改
被拖动控件的 DragIcon 属性,使它可以表明是否允许控件的着陆。在 Explorer 里通过鼠标
拖动实现文件的拷贝与移动时就可看到 DragOver 事件的应用。空的 DragOver 事件差不多是
这样的:
Private Sub Form_DragOver(Source As Control, X As Single, Y As Single, State As Integer)

End Sub
Source, X, Y 参数的意义与 DragDrop 的意义相同。State 参数表明被拖动的控件相对于它
飘过的控件的迁移状态。

State 值 描述
0 Source 控件飘进本控件的领空
1 Source 控件飘出本控件的领空
2 Source 控件在本控件上空盘旋

DragOver 事件的例子可以参考 Visual Basic Help 里的例子。

§2 在 Visual Basic 程序里绘图


计算机的绘图和动画是一件奇妙且引人入胜的主题,许多软件公司都开发了优秀的关
于 图 象 的 软 件 , 三 维 的 有 3D Studio Max 、 LightWare 、 True Space 等 , 二 维 的 有
CorelDRAW、FreeHand 等等。这也是计算机渗透到其它领域的一个很好的例子,在许多影片
中都可以看到计算机的出色表现。
速度并不是 Visual Basic 的优势,不过 Visual Basic 已经为我们提供了不少的素材。已经
有一些厚达 600 页以上的书籍在介绍 Visual Basic 下的图象处理技术,包括绘图,色彩,动
画,三维空间,虚拟现实,甚至计算机仿真的基础。听起来很诱人的东西往往需要大量不诱
人的知识,比如数学,物理,逻辑等等。
一、在 Visual Basic 程序里加入图片
1,图片通常可以放在 Form,Picture Box,Image Box 里,用代码加入图片的方法有两
种,一种是用 LoadPicture 函数,如:Image1.Picture = LoadPicture(“c:\pic\demo.bmp”)
另一种是用赋值的方式,如:ThisPicture.Picture = ThatPicture.Picture
删除图片的方法是:Image1.Picture = LoadPicture(“”)
2,Visual Basic 送给我们的几百个 ICO 文件是非常有趣的,这些文件通常的子目录是:
C:\VB\ICONS
它包括 12 类。在这些 ICO 文件里,有许多是成对出现的,用这些图标,可以做出一些
简单的动画。
3 , 这 个 例 子 用 VB 目 录 下 的 ICONS\TRAFFIC 子 目 录 下 的
trffc10a.ico,trffc10b.ico,trffc10b.ico 图标模拟一个红绿灯的变化。建立如下界面:

控件名 属性 设置值
img(右上) Index 0
Picture c:\vb\ icons\traffic\trffc10a
Visible False
img(右中) Index 1
Picture c:\vb\ icons\traffic\trffc10b
Visible False
img(右下) Index 2
Picture c:\vb\ icons\traffic\trffc10c
Visible False
imgShow(左) Picrure c:\vb\ icons\traffic\trffc10a

键入代码:
Private Sub Form_Click()
Static i As Byte

If i = 2 Then
i=0
Else
i=i+1
End If
imgShow.Picture = img(i).Picture
End Sub
这里出现的 Static 语句同 Dim 语句一样用于声明变量。用 Dim 语句声明的变量在退出这
个过程时,变量的值就不存在了,第二次进入这个过程时变量的值将变成 0,而不是上次
处理后的值。而用 Static 语句声明的变量在第二次进入过程时将保持上次退出时变量的值,
这就是 Static 与 Dim 的不同之处,用 Static 语句声明的变量被称作静态变量。
二、可用于制作特殊效果的数学及语句
1,Move 方法
Move 方法的语法是:object.Move left, top, width, length
object 是被移动的对象,这个参数是可以省略的。left 参数是必须的,指定对象左边的水
平坐标。top 参数是可以省略的,指定对象上面的垂直坐标。width 参数是可以省略的,指定
对象的新宽度。length 参数是可以省略的,指定对象的新长度。width,length 参数的指定也
就是指移动的同时改变对象的大小。
三、Visual Basic 的坐标系统
1,Visual Basic 的坐标系和笛卡尔的平面坐标系不同,计算机屏幕的坐标系是这样的。

窗体的左上角是原点,X 轴的正向水平向右,Y 轴的正向垂直向下,这是计算机领域里


的顽固传统之一。所以窗体里的控件的位置用 Left,Top 属性描述,Left 是控件左上角到窗
体左边的距离,Top 是控件左上角到窗体上边的距离。
2,建立自己的坐标系
这涉及到窗体的许多 Scale 属性。ScaleLeft 属性确定对象左边的水平坐标, ScaleTop 属
性确定对象顶端的垂直坐标,ScaleWidth 属性确定对象内部水平的单元数目,ScaleHeight
确定对象内部垂直的单元数目。如:
ScaleLeft = -50
ScaleTop = 50
ScaleWidth = 100
ScaleHeight = -100
将建立一个笛卡尔的坐标系如下:

更简单的方法是用 Scale 方法:Form1.Scale (-50, 50) - (50, -50)


也可建立上面的笛卡尔坐标系,其中前一个括号里是左上角的坐标,后一个括号里是
右下角的坐标。
3,刻度系统
这是由控件的 ScaleMode 属性设置的。ScaleMode 的值有:

ScaleMode 值 意义 ScaleMode 值 意义
0 用户自定义 4 字节(Character)
1 点素(Twip) 5 英寸(Inch)
2 点(Point) 6 毫米(Millimeter)
3 象素(Pixel,这与屏 7 厘米(Centimeter)
幕分辨率有关)

1 Inch = 1440 Twips


1 Centimeter = 567 Twips
1 Inch = 72 Points
1 字符宽(水平方向)= 120 Twips
1 字符高(垂直方向)= 240 Twips
有一次,我设置 ScaleMode = 7,并在屏幕上打印了三个厘米长的线段,我拿尺子在屏
幕上量了量,觉得好象和三个厘米的长度有一定的差距,这是为什么呢?后来知道除了
0,3 之外,其它值都是以打印长度为准的,也就是说打印出来才是三厘米。
四、基本的绘图
1,AutoRedraw 属性
当 AutoRedraw 属性设为 True 时,所有的绘图都将被储存在内存上,当程序比较在意内
存且绘图不很复杂的时候,可以在 Form,Picture Box 的 Paint 事件里编写绘图代码。Paint 事
件发生在 Form 或 Picture Box 重画时(如盖在上面的窗口移开,或窗体变大变小)。
2,色彩
决定用哪种色彩可以用三种办法
(1)使用 RGB 函数。语法是: RGB(Red, Green, Blue)
这三个参数分别决定红色,绿色,蓝色的亮度强度,三个参数的范围是 0-255,0 表
示最浅最弱,255 表示最深最强。如:Form1.BackColor = RGB(255,255,0) ‘黄色
(2)使用 QBColor 函数
这是 Quick Basic 的颜色系统可决定 16 种颜色,16 种颜色是:

值 颜色 值 颜色 值 颜色 值 颜色
0 黑 4 红 8 灰 12 淡红
1 蓝 5 品红 9 淡蓝 13 淡紫
2 绿 6 黄 10 淡绿 14 淡黄
3 青 7 白 11 淡青 15 亮白

如:Form1.BackColor = QBColor(5)
(3)直接输入数值
颜色值的格式是 16 进制的,为&HBBGGRR。BB 代表蓝色,GG 代表绿色,RR 代表红
色。所以 Form1.BackColor = &HFF0000
与 Form1.BackColor = RGB(0, 0, 255)的含义是一样的。
(4)取得特定点的颜色值,使用 Point 方法。如:x = Point (20,30)
x 将是一个长整型数字,它代表了 (20,30)点的 RGB 值。x 如果直接输出的话会让人难以
理解,它是一个按 16 进制&HBBGGRR 的方式排列的数。如何才能拆出 Red,Green,Blue
的值呢,可以用下面的公式。
Red = (object.Point(x, y) And &HFF)
Green = (object.Point(x, y) And &HFF00&) \ 256
Blue = (object.Point(x, y) And &HFF0000) \ 65536
计算机有时是通过抖色的方法来实现一些它表现不了的一些颜色。抖色就是比如一块淡
红的颜色实际上是一些红点和一些白点组成的。这时从这块淡红的颜色里取一个点读它的
RGB 值也许会令你失望,你明明用 RGB(255,128,128) 填充了底色,但你用 Point 方法取出
点的颜色时却是 RGB(255,255,255)或 RGB(255,0,0)。
3,绘图方法
包括 Cls 方法,Pset 方法,Line 方法,Circle 方法
(1)Cls 方法
前面已经介绍过的 Cls 方法将以背景色清除绘图区域。
(2)Pset 方法
语法是:object.Pset (x, y) , color
Pset 方法将在 object 对象的(x, y)点用 color 参数决定的颜色画一个点。object 参数和 color
参数是可以省略的。
(3)Line 方法
Line 方法用于画直线或方框。基本的语法是:object .Line (x1, y1) - (x2, y2) , color
如:Line (250,300) - (400,500)
画一条从(250,300)到(400,500)点的直线。
Line - (400,500)
从当前位置(由 CurrentX,CurrentY 决定)画到(400,500)
Line (150,250) - Step (150,50)
出发点是(150,250),终点是向 X 轴正向走 150,向 Y 轴正向走 50 的点。
等同于:Line (150,250) - (300,300)
又如: Line (20,40) - (150,200) , , B
画一个左上角在(20,40),右下角在(150,200)的矩形,注意在 color 参数省略时,逗号并
不省略。
Line (20,40) - Step (50,70), RGB(255,0,0), BF
用红色从(20,40)到(70,110)画一个实心的矩形。
Line - (30,50), RGB(0,255,255), ABC
这个语句是错的,因为 color 参数后面的参数只有 B,或 BF 两种形式。
(4)Cricle 方法
Cricle 方法用于画圆或椭圆,它的参数很多,语法是: object.Circle (x,y), r, color, start,
end, aspect
(x,y) 参数是不能省略的参数,表示圆心的位置。r 是不能省略的参数,表示半径。color
是可以省略的参数,表示画的颜色。start、end 用于画弧,是用弧度度量的。

start、end 为负值将在圆心至这个负值的点画出半径,这样就可以画出扇形了。如:
Circle (2000,2000) , 2000 , , -1.571 , -2.543
可画出扇形。这里的负号并没有更深的含义,仅仅表示多画了一条半径。
Circle (2000,2000) , 2000 , , -2.543 , -1.571
将画出右边那样的饼图。
五、关于绘图的属性
这 些 属 性 包 括 :
CurrentX、CurrentY、DrawMode、
DrawStyle、DrawWidth、Fillcolor、FillStyle、
BackColor、ForeCol
or 等属性。CurrentX、CurrentY 已经介绍过了,就不再介绍了。
1,DrawMode 属性
这个属性用来决定用什么逻辑关系将一个图案画到另一个图案上, DrawMode 有 16 个
值可供选择。可以用这些逻辑关系作出一些有趣的效果。
2,DrawStyle 属性
这个属性决定了线的类型,有六种设置。
3,DrawWidth 属性
这个属性决定了线的粗细。
4,BackColor、ForeColor 属性
这两个属性分别决定了对象的背景色和前景色。
5,FillColor 属性
这个属性确定填充在 Shape 控件或用 Circle 和 Line 方法建立的圆形或矩形里的颜色。
6,FillStyle 属性
这个属性同 Shape 控件的 FillStyle 属性是一样的,指的是填充 Shape 或用 Circle 和 Line
方法建立的圆形或矩形里的模式。
六、在 Visual Basic 的绘图程序里使用 Windows API 里的绘图函数将使程序有更灵活的
变化性,例如涉及到画笔和刷子的 API 函数就有十几个,而在 Windows NT ,Windows 98
及未来的 32 位的 Windows 操作系统里将有更多的关于绘图的函数。

第六章 Visual Basic的数据 库

§1 数据库的一些知识
数据库编程,无论是从 Visual Basic 中还是从其它更为成熟的数据库管理系统中去做,
都不太容易。如果你热衷于此,你就会发现更多的专业书籍,仅仅介绍 Visual Basic 的数据
库编程功能就将足够再开设一门讲座了。所以这里的介绍只是简单的介绍。(但我还得介绍,
以便使这本书的覆盖面看起来更广一些)
开始,简单的数据库就象一张张表格一样,有行有列。后来一些管理数据库又有数学头
脑的人,想出了一些好点子,于是数据库就发展成为一门计算机的分支的学科,到了现在
数据库似乎拥有无限的玄机。一些公司靠数据库发了财,做学生的就有越来越多的人学习数
据库的知识了。
但我们要知道的是数据库的建立无非是为了让人们更好的获得、使用、分析众多的信息
(随着科学的发展,信息越来越多了)。通常的操作是用户有了好奇心,于是他问:“我想
知道从有邮票以来,邮票的印刷数量排名前十名的都是什么?”计算机经过一系列艰难的
筛选终于显示了结果。用户并不知道计算机是如何做到的,他只不过得到了方便的可以处理
的数据(可能是放在表格里的)。
术语中把用户的问题叫做“查询”,把得到的结果叫做“表”或“视图”。在 Visual
Basic 里解决这类问题的是 Microsoft Access “Jet” 机。查询关系数据库的常用语言叫做
SQL ( Structured Query Language )结构化查询语言。在 Visual Basic 的专业版和企业版中
SQL 是固有的。

§2 通过数据库控件(Data Control)处理 Visual Basic 的数据库

通过数据库控件( Data Control )处理的数据库类型里,最适合 Visual Basic 的就是


Access 类型的数据库,可以说 Visual Basic 的数据库和 Access 的数据库是完全相同的。如果
使用的是 Jet database engine(也就是 Access 类型)的数据库,则我们不必设置数据库控件
的 Connect 属性,否则我们得设置 Connect 属性为所使用的数据库类型名。

数据库类型 设置 Connect 属性 设置路径


Access ";" "drive:\path\filename.MDB"
dBASE III "dBASE III;" "drive:\path"
dBASE IV "dBASE IV;" "drive:\path"
Paradox 3.x "Paradox 3.x;" "drive:\path"
Paradox 4.x "Paradox 4.x;" "drive:\path"
Btrieve "Btrieve;" "drive:\path\filename.DDF"
FoxPro 2.0 "FoxPro 2.0;" "drive:\path"
FoxPro 2.5 "FoxPro 2.5;" "drive:\path"
FoxPro 2.6 "FoxPro 2.6;" "drive:\path"
Excel 3.0 "Excel 3.0;" "drive:\path\filename.XLS"
Excel 4.0 "Excel 4.0;" "drive:\path\filename.XLS"
Excel 5.0 "Excel 5.0;" "drive:\path\filename.XLS"

如果你找不到 Microsoft Access 的话,你就不得不用 Visual Basic 自带的 Data Manager


建立自己的 Access 数据库文件,然而在使用过后会发现 Data Manager 是十分不便利的,你
可以在 Visual Basic 的 Add-Ins 菜单下找到 Data Manager。
1、 显示数据
例如用一个正文框和一个数据库控件读取一个 MDB 文件里一个表( Table )里的一个
域(Field)里的信息,这个功能我们连一条代码也不用编,这正是 Visual Basic 在数据库方
面的优势所在。
(1)画出一个数据库控件,按 F4 键打开 Properties 窗口。
(2)选择 DatabaseName 属性并单击设置框旁边的有省略号的那个钮, Visual Basic 显
示 DatabaseName 对话框,在这个对话框里选择你要的数据库文件。
(3)选择 RecordSource 属性,从下拉的列表里选择一个 Table ,这个数据库控件在运
行时将指向这个 Table。现在数据库控件的属性设置完了。
(4)画出一个正文框,按 F4 键打开 Properties 窗口。
(5)选择 DataSource 属性,从下拉列表里选择正文框对应的数据库控件。
(6)选择 DataField 属性,从下拉列表里选择正文框对应的 Field。
所以,简单地说,画两个控件设置四个属性就可以读取一个数据库一个 Table 的一个
Field 了。在运行时,数据库控件的四个按钮可以用来移动记录。最左边的钮表示移动到第一
条记录上,最右边的钮表示移动到最后一条记录上,另两个在内侧的钮分别表示每次向前
或向后移动一条记录。
2、 移动记录
除了使用数据库控件四个按钮来移动记录外,代码也可以实现这些功能,假设数据库
控件的名字叫 Data1。

功能 代码
显示第一个记录 Data1.Refresh
Data1.Recordset.MoveFirst
显示最后一个记录 Data1.Recordset.MoveLast
显示下一个记录 Data1.Recordset.MoveNext
显示上一个记录 Data1.Recordset.MovePrevious

3、 删除记录
首先用上面的那些方法找到这个倒霉的记录,然后用下面的代码删除它。
Data1.Recordset.Delete
Data1.Recordset.Update
第一行表明要删除这个记录,第二行表明让数据库文件知道这个不幸的决定。
4、 增加记录
Data1.Recordset.AddNew
Data1.Recordset.Fields(“FieldName”) = “NewData”
Data1.Recordset.Update
第一行决定要增加一个新记录,第二行表示增加的内容,其中 FieldName 是 Field 的名
称,NewData 是增加的内容,第三行把这个决定通知数据库文件,让它去做这件事。
5、 找出指定的记录
假定在一个 Table 里的 Age 域里寻找记录值为 18 的记录,则:

功能 代码
找出第一个匹配的记录 Data1.Recordset.FindFirst “ Age = ‘18’ ”
找出最后一个匹配的记录 Data1.Recordset.FindLast “ Age = ‘18’ ”
找出下一个匹配的记录 Data1.Recordset.FindNext “ Age = ‘18’ ”
找出上一个匹配的记录 Data1.Recordset.FindPrevious “ Age = ‘18’ ”

6、 从数据库域中取得数据
x = Data1. Recordset.Fields(“FieldName”).Value
这条指令将取出存在域 FieldName 中的数据并赋给 x。
7、 改变数据库中域的数据
Data1.Recordset.Edit
Data1.Recordset.Fields(“FieldName”).Value = NewValue
Data1.Recordset.Update
这段指令将 NewValue 中的值代替 FieldName 域中的当前值。
§3 使用数据库网格、数据库组合框、数据库列表框控件

现 在 我 们 先 加 入 一 个 数 据 库 控 件 ( 它 暂 时 叫 做 Data1 ) , 我 们 为 它 设 置 好
DatabaseName、RecordSource 属性。
1、 生成数据库网格
1,在工具箱中单击数据库网格控件,拖动它成为数据库网格;
2,按 F4 键;
3,单击 DataSource 属性,选择刚才建立的数据库控件 Data1。
现在就可以显示你所选择的数据记录,不需要你编写任何代码。
2、 修改显示在网格里的数据
你可以编辑在网格里的数据,因为它与数据库控件已经建立了联系。但你必须改变下面
三种数据库网格的属性。

属性 值 含义
AllowUpdate True 可任意修改数据库网格中的数据
False 只显示数据,不能修改
AllowDelete True 可删除所有记录
False 不可删除记录
AllowAddNew True 可增加新记录
False 不可增加新记录

3、 数据库组合框
数据库组合框用来在数据库中输入新数据。数据库组合框可以显示储存在某一字段的数
据内容,这一字段用户可以从中选择,也可以输入一新值。生成数据库组合框的方法:
1,在工具箱中单击数据库组合框控件,拖动它成为数据库组合框;
2,按 F4 键;
3,单击 DataSource 属性,选择你的数据库控件 Data1;
4,单击 RowSource 属性,选择你的数据库控件 Data1;
5,单击 ListField 属性,选择你想在数据库组合框中出现的字段;
6,单击 DataField 属性,选择你想在数据库组合框中作为默认选择而出现的字段。(通
常和上一步一样)
4、 数据库列表框
数据库列表框可以显示储存在数据库字段中的数据内容,虽然你可以看到数据,但你
不能增加、删除和编辑它的内容。生成数据库列表框的方法:
1,在工具箱中单击数据库列表框控件,拖动它成为数据库列表框;
2,按 F4 键;
3,单击 DataSource 属性,选择你的数据库控件 Data1;
4,单击 RowSource 属性,选择你的数据库控件 Data1;
5,单击 ListField 属性,选择你想在数据库列表框中出现的字段;
6,单击 DataField 属性,选择你想在数据库列表框中高亮度显示的字段。(通常和上一
步一样)
总之,数据库的建立是十分有用的,然而当你发行你的应用程序的时候,含有数据库
控件的应用程序往往所需的发行文件比你想象的要大。

第七章 从文件 中存取 资料

每个程序几乎都要往磁盘上存储数据,这些数据可能是表格、图形、姓名和地址清单、或
者是游戏的存储进度。很难想象一个大型的 RPG 游戏不允许游戏者存盘。这一章将学习关于
存储文件的知识。

§1 文本文件,就象盒式磁带机
1、 生成文本文件,使用下列命令:
Open "Filename" For Output As #FileNumber
其中 Open 告诉 Visual Basic 生成一个新文件; Filename 是文件名(可以包含路径);
For Output 表明文本文件要接受程序输出的数据; FileNumber 是文件号(1-511 之间),
Visual Basic 很傻,不知道文件名,它只认文件号,程序可能打开多个文件,如果你忘了
该生成哪一号文件,你可以用 FreeFile 函数来得到一个文件号。如:
Dim Free As Integer
Free = FreeFile
Open "c:\abe.def" For Output As #Free
则生成文件 c:\abe.def,Visual Basic 替你找一个未用的文件号来代表它。
2、 打开已有的文本文件
Visual Basic 不仅仅想知道你要打开文件,它还想知道你打开文件后想做什么。
1, 如果你想从文本文件中读取数据给计算机,则使用下面命令:
Open "Filename" For Input As #FileNumber
如果文件不存在,Visual Basic 就会对你的玩笑表示生气,它会发出叫声,然后指出你
的错误。
2, 如果你想把数据写到文本文件中,则使用下面命令:
Open "Filename" For Output As #FileNumber
快看这个命令和生成新文件的命令一样!你可以这样理解:如果 Visual Basic 找不到那
个文件,那么它就生成一个新的,如果它找到了,就打开文件并准备向里面写东西。但是如
果程序员向已存在的文件内写数据,那么将会把原来的数据覆盖掉。这可要小心!
3, 如果你想把数据追加写到文本文件中,则使用下面命令:
Open "Filename" For Append As #FileNumber
这种操作也是准备写数据到文本文件中,不过 Visual Basic 将把数据追加到文件的末尾。
3、 向文本文件中写数据
Print #FileNumber, "Text String"
将 Text String 字符串写入#FileNumber 代表的文件中,写到什么地方取决于你打开文
件的方式。For Output 方式写到文件的开头,For Append 方式写到文件的末尾。
4、 关闭文件
不论什么时候生成了文本文件或打开了已有的文本文件都要在程序终止前关闭它。否则,
可能会出现一些问题,甚至把文件内的数据搞坏。
关闭所有打开的文件,可使用命令:Close
关闭特定的文件,可使用命令:Close #FileNumber
5、 从文本文件中读取数据
首先要用 For Input 方式打开文本文件,然后可将文件内容赋给一个字符串变量。由于
在 32 位系统中,字符串的容量可达百兆,所以可以简单地把文件的内容赋给一个字符串变
量。在 16 位的系统中读取大文件时,恐怕还要考虑内存的问题。
Dim FileContents As String
Open "Filename" For Input As #FileNumber
FileContents = Input(LOF(FileNumber), FileNumber)
Close #FileNumber
第三句就可以将文件的所有内容读入 FileContents 中,LOF 函数用以去得文件的长度。
6、 改变文本文件的内容,这是很烦琐的过程,需用下面的步骤。
1, 打开文件。
2, 取出文件内容赋给一个变量。
3, 关闭文件。
4, 编辑变量内容。
5, 打开文件。
6, 变量存入文件。
7, 关闭文件。

§2 随机存取文件,就象 CD
文本文件就象盒式磁带机,因为如果你想读取后面的数据就得把前面的数据先放过去。
随机存取文件就象 CD ,因为你可以立即跳至你想听的那一首歌。随机存取文件是以结构
(Structure)来存取的,在文件里数据放在一个一个结构里,
每个结构里的数据是一样的。
1、 使用结构(Structure)保存信息
写程序时,也许要生成几个变量来保存信息。如要跟踪如下的信息:姓名、地址、年龄。
可以为各信息生成单独的变量,如:
Dim Name As String
Dim Address As String
Dim Age As Integer
然而,Visual Basic 看不出这些信息的关联之处,对 Visual Basic 来说这些信息散乱地
堆放在内存中的某个地方,没有很好地组织起来。为了解决这个问题,Visual Basic 使用叫
做结构(Structure)的东西将分散的东西组织起来。在别的一些语言里这被称为记录类型。
如下面的例子:
Type PersonRecord
Name As String
Address As String
Age As Integer
End Type
1, 生成结构
只能在代码窗口的声明区生成结构。即在 Object 列表框中选择(General),在 Proc 列表
框中选择(declarations)后再输入结构。在窗体的声明区生成结构须加上 Private 关键字。
2, 定义变量为结果类型
Dim VariableName As StructureName
如上面的 PersonRecord 结构,可用下面的代码定义:
Dim Employees As PersonRecord
3, 赋值给结构中的数据
例如赋值给上面定义的 Employees 变量:
Employees.Name = "Tom"
Employees.Address = "1-107"
Employees.Age = 22
4, 取出结构中的数据
例如取出上面赋值过的 Employees 变量中的数据:
Who = Employees.Name
5, 随机存取文件里的结构
随机存取文件里有一个一个的结构,它们安静地象下面一样排列着:
Name Address Age Name Address Age
2、 随机存取文件使用的重要变量
用一个变量代表你定义的结构,用一个变量跟踪现在的位置,再用一个变量表明最后
一个结构的位置。
Dim Friends As FriendStructure
Dim Position As Long
Dim LastOne As Long
必须有一个变量来代表你定义的结构。
3、 生成和打开随机存取文件
Open "Filename" For Random As #FileNumber Len = StructureLength
看起来和生成和打开文本文件的语句差不多,如果 Visual Basic 找不到文件的话则
Visual Basic 就生成一个新的文件,如果找到的话就把旧文件打开。 For Random 告诉
Visual Basic 你想打开一个随机存取文件。#FileNumber 还是文件号,你可以用 FreeFile 让
Visual Basic 替你选一个没有用过的文件号。StructureLength 是你的结构的长度,如果你不
知道的话,可以用 Len 函数来获得。如:
Dim StructureLength As Long
Dim Friends As PersonRecord ‘PersonRecord 是一个结构名称
StructureLength = Len(PersonRecord)
4、 向随机存取文件写入数据
Put #FileNumber, Posetion, DataName
Put 表明你想向由#FileNumber 决定的随机存取文件里写入数据,Posetion 是你想放置
数据的位置。在随机存取文件里第一个结构放在位置 1,第二个结构放在位置 2,等等。需要
知 道 的 是 : 随 机 存 取 文 件 的 写 入 和 读 出 不 需 要 以 不 同 的 方 式 打 开 文 件 , Open…For
Random 打开文件后既可以写入又可以读出,比文本文件方便多了。
下面是向文件的末尾增加数据的代码的示例, LastOne 变量用于表明文件已存在多少
结构:
Dim StructureName As StructureType ‘StructureType 是一个结构的名字
Dim SLength As Long
Dim LastOne As Long
SLength = Len(StructureName)
Open "FileName" For Random As #FileNumber Len = SLength
LastOne = LOF(FileNumber) \ Slength ‘LOF 函数返回 FileNumber 文件号代表的文
件的长度
LastOne = LastOne + 1
Put #FileNumber, LastOne, StructureName
Close #FileNumber
下面是替换文件中结构的代码的示例:
Dim StructureName As StructureType ‘StructureType 是一个结构的名字
Dim SLength As Long
SLength = Len(StructureName)
Open "FileName" For Random As #FileNumber Len = SLength
Put #FileNumber, Position, StructureName ‘Position 是你想替换的结构的位置
Close #FileNumber
5、 从随机存取文件中读出数据
Dim GetData As StructureType ‘StructureType 是一个结构的名字
Get #FileNumber, Position, GetData
这样就可以把 #FileNumber 代表的文件中的在 Position 位置上的数据读到 GetData 变
量中。
6、 关闭文件
一定要在程序终止前关闭打开的文件。否则,可能会出现一些问题,甚至把文件内的数
据搞坏。
关闭所有打开的文件,可使用命令:Close
关闭特定的文件,可使用命令:Close #FileNumber

§3 二进制文件
二进制文件并不是一种新的文件类型,而是操作任何种类文件的一种方法。二进制文件
技术允许程序员修改文件中的任意字节。所以说,二进制文件技术是一种强有力的工具,但
是强有力的工具往往必须小心使用。使用二进制文件可以操作许多文件类型,甚至直接读写
图形文件等等。具体的实现方法请参考其他详细介绍的书籍。
1、 生成和打开二进制文件
Open "FileName" For Binary As #FileNumber
2、 从二进制文件中读出数据
GetData = Input(Number, #FileNumber)
以上命令从 #FileNumber 代表的文件中在当前位置上开始 Number 个字节的数据读到
GetData 变量中。
3、 定位文件的当前位置
Seek FileNumber, PositionNumber
4、 以上命令将#FileNumber 代表的文件的当前位置移到 PositionNumber 位置。

第八章 发行应 用程序


§1 把你的应用程序编译成扩展名为 EXE 可执行文件
终于,你把自己的应用程序编制完成了,而且你已经极其耐心地测试了你的程序或者
你的程序已经通过质量部门的检测,于是要把它散发给用户去使用。为了散发程序,你必须
把程序编译为可执行的文件(通常以 EXE 为扩展名)。下面是把程序编译为可执行文件的
步骤:
1, 保存文件;
2, 从 File 菜单选择 Make EXE File 项,弹出 Make EXE File 对话框;
3, 按 Options 按钮,弹出 EXE Options 对话框;
4, 做你需要的修改后,按 OK 按钮;
5, 在 Make EXE File 对话框填入可执行文件名后按 OK 按钮。
这样你就生成了可执行文件。现在来解释一下 EXE Options 对话框中各项的含义。

Version Number 是程序的版本号,现在的版本号是 1.06。Auto Increment 被选择上后


每次编译,Visual Basic 将自动把 Revision 加 1。
Application Title 是程序的标题,Application Icon 是程序的图标。
Version Information 是一系列版本信息,包括:说明、公司名、文件描述、合法版权、合法
商标、产品名称。

§2 使用 Package & Deployment Wizard


当你完成了你的伟大应用程序后,如何让你的朋友或任何一个人了解你编程的艰辛和
胜利的喜悦呢?你可以把程序发行出去。看看 Microsoft 的各种软件均有简便的安装程序,
这时你想:“天哪!我还得编个安装程序。”然而,在 Visual Basic 中有工具来帮助你完成
这相任务,我极力建议你使用这个安装工具来取代你打算自己编个安装程序的念头,原因
有三:
1, 此安装工具可在几分钟内替你搞定一切,不论你想用磁盘或光盘来发应用程序;
2, 安装工作复杂的配置会使人走火入魔;
3, 安装工具生成的安装程序还提供卸载功能。
在开始菜单程序组的 Visual Basic 组里有”Package & Deployment 向导”的图标,单
击它可进入”Package & Deployment 向导”。
1、 第一步
在选择工程(J)里填入.vbp 文件的名字,如果按右边带“…”的按钮将会打开一个对
话框搜索.vbp 文件;
单击打包(P)到下一步。

二、第二步
要生成应用程序的可执行文件,如果已编译并生成了可执行文件,向导会跳过这一步 ,
否则会提示生成它。
3、 第三步
选择生成包类型,有两种:“标准安装包”和“相关文件”。
4、 第四步
在硬盘中生成文件夹,存储所有生成的部件。
5、 第五步
选择向包中添加文件。
6、 第六步
确定安装程序的发行类型。
7、 第七步
定义安装程序标题。
8、 第八步
为安装包中的文件选择图标。
9、 第九步 选择安装包中的文件的位置。
10、第十步选择安装后可共享的文件。
11、第十一步 FINISH
单击“展开”可将安装程序包分发出去。
单击“管理脚本”可对“包装脚本”和“展开脚本”进行管理。
你用 Setup wizard 生成的安装盘安装的应用程序可通过 Windows 95 的控制面板中的
添加/删除程序功能卸载。现在,把你的程序送给你的朋友们吧!

第九章 使用 Windows API和用 Visual Basic建立自

己的屏 幕保护 程序

§1 关于 Windows API
我们现在将要探讨的是 Windows Application Programming Interface (API)的知识,这
个冗长的词汇的汉语意思是应用程序编程接口。这是一系列很复杂的函数、消息和结构,它
使编程人员可以用不同类型的编程语言编制出在 Windows 95 和 Windows NT 上运行的程
序。Visual Basic 程序员使用 API 深入 Windows 的内部过程,充分利用 Windows。然而利用
Windows API 时要小心,因为如果你使用得不正确,就会彻底崩溃 Windows。(不崩溃几
回你怎么能学到东西呢)
Windows API 是一系列的 DLL 文件,使用 API 函数和使用 DLL 文件中的函数是一样的。
那么你怎么知道 Windows API 里有什么函数呢?如果你只需要了解 API 的函数清单,
那么你可以查看 Visual Basic 自己带的 API Text Viewer;如果你想了解 API 每一个函数、消
息或结构的具体含义,那么 Visual Basic 目前没有这方面的帮助。你需要购买 Windows
Software Development Kit (SDK ),查询他们的手册(查询这种“手”册可是需要一定
的臂力的,很厚哟)。在 Visual C++里也有关于 API 函数、消息和结构的具体含义的帮助。

§2 使用 API Text Viewer


Visual Basic 自己带的 API Text Viewer 可以让你寻找 Windows API 函数,你还可以拷
贝所需常数、函数声明语句或结构定义。在开始菜单的 Visual Basic 6.0 组里有 API Text
Viewer 的菜单项,你可以选择它来打开 API Text Viewer。

使用 API Text Viewer 请遵循以下步骤:


1, 打开 API Text Viewer。
2, 从 File 菜单选择 Load Text File,出现 Select a Text API File 对话框
3, 单击下列文件之一:
WIN32API.TXT 32 位 Windows API 函数清单
WINMMSTS.TXT 多媒体 Windows API 函数清单
4, 单击 Open 按钮(可能会出现对话框,问你是否想要将文本文件转换为数据库),
API 函数清单出现在 Available Items 列表框。
5, 单击 API 列表框,选择下列项目之一:
Constants(常数声明)
Declares(函数声明)
Types(结构定义)
6, 单 击 你 想 在 程 序 中 使 用 的 项 , 然 后 单 击 Add 按 钮 , 你 想 选 择 的 项 就 出 现 在
Selected Items 列表框中。
7, 对你想在程序中加入的每个常数、函数声明或结构定义重复 5、6 步。
8, 单击 Copy 按钮。
9, 切换回 Visual Basic,将复制项粘贴到代码窗口的声明区。
10,最后退出 API Text Viewer。
当然你可以不必使用 API Text Viewer,但是 API Text Viewer 可以确保你没有拼写错误。
但是不要轻信 API Text Viewer ,Visual Basic 提供的 API 声明始终没有做到完全正确
(至少上一个版本的 Visual Basic 就没有提供完全正确的 API 声明),所以如果调用 API
不成功的话,可能是 API 声明有误的原因,请查阅 Windows SDK 来寻找正确的 API 定义。
这种 Bug 令使用 Visual Basic 的程序员十分伤心,所以作为编程者,一定要编制稳定可靠
的程序才能让你的用户满意。

§3 用 Visual Basic 制作自己的屏幕保护程序


当我得知用 Visual Basic 可以制作自己的屏幕保护程序时,我的兴奋不亚于第一次看到
流星。最初建立屏幕保护程序是用来保护屏幕不被不常变化的象素点“烧灼”出印记而编制
的程序,现在,屏幕保护程序更多地用于娱乐而不是屏幕保护了。现在我们使用 Visual
Basic 来制作我们自己的屏幕保护程序,这里仅仅是一个简单的例子,如果你了解了程序
的原理,就可以编制更好的屏幕保护程序了。当你的朋友看到你的屏幕保护程序,他(她)
八成会对你表示钦佩的。
1、 对屏幕保护程序的设想
我们得想想一个屏幕保护程序需要什么功能?
1, 屏幕保护程序覆盖整个屏幕,甚至把汉字输入条都覆盖住。
2, 屏幕保护程序可以检测到用户单击鼠标、移动鼠标、按键等事件。
3, 鼠标指针不能出现。
4, 适当地处理通过显示器属性对话框访问的 Setting、Preview、Password 选项。
5, 有一些简单的动画来吸引用户。
6, 还有一个现实的问题,不能让两个或两个以上屏幕保护程序运行,因为如果每隔一
段时间就打开一个屏幕保护程序,那么系统的资源迟早得被耗尽。
这些功能有一些需要调用 Windows API 的函数来实现。现在我们来实现我们简单的屏幕
保护程序。它是仿造 Windows 自带的滚动字幕屏幕保护程序设计的。

2、 生成界面
对象 属性 设置值
Form1 AutoRedraw True
BackColor 黑色
BorderStyle 0 - None
Caption 我的编程世界……
ControlBox False
KeyPreview True
MaxButton False
MinButton False
Name frmScreenSaver
ScaleMode 3 - Pixel
WindowState 2 - Maximized
Label1 AutoSize True
BackStyle 0 - Transparent
BorderStyle 0 - None
Caption 我的编程世界……
ForeColor 红色
Font 幼圆
Timer1 Enabled False
Interval 1

三、编写代码
在窗体下加入下面的代码:
Option Explicit

Dim QuitFlag As Boolean


Const SPI_SETSCREENSAVEACTIVE = 17
Private Declare Function SetWindowPos Lib "user32" ( _
ByVal hwnd As Long, _
ByVal hWndInsertAfter As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal cx As Long, _
ByVal cy As Long, _
ByVal wFlags As Long _
) As Long
Private Declare Function ShowCursor Lib "user32" ( _
ByVal bShow As Long _
) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function SystemParametersInfo Lib "user32" Alias
"SystemParametersInfoA" ( _
ByVal uAction As Long, _
ByVal uParam As Long, _
ByVal lpvParam As Long, _
ByVal fuWinIni As Long _
) As Long

Private Sub Form_Click()


QuitFlag = True
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
QuitFlag = True
End Sub
Private Sub Form_Load()
Dim Throw As Long

Throw = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, ByVal 0&, 0)


Select Case UCase$(Left$(Command$, 2))
Case "/A"
MsgBox "此屏幕保护程序不可以设置口令。"
Unload Me
Exit Sub
Case "/C"
MsgBox "此屏幕保护程序没有设置项。"
Unload Me
Exit Sub
Case "/P"
Unload Me
Exit Sub
Case "/S"
Show
Throw = ShowCursor(False)
Throw = SetWindowPos(hwnd, -1, 0, 0, 0, 0, (&H2 Or &H1))
Label1.Left = frmScreenSaver.ScaleWidth
Label1.Top = (frmScreenSaver.ScaleHeight - Label1.Height) / 2
Do
Label1.Left = Label1.Left - 3
Sleep (50)
If Label1.Left <= -Label1.Width Then Label1.Left =
frmScreenSaver.ScaleWidth + Label1.Width
DoEvents
Loop Until QuitFlag = True
Timer1.Enabled = True
Case Else
Unload Me
Exit Sub
End Select
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As
Single)
Dim Xnow As Single, Ynow As Single
Static Xlast As Single, Ylast As Single

Xnow = X
Ynow = Y
If Xlast = 0 And Ylast = 0 Then
Xlast = Xnow
Ylast = Ynow
Exit Sub
End If
If Xnow <> Xlast Or Ynow <> Ylast Then
QuitFlag = True
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim Throw As Long

Throw = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, ByVal 0&, 0)


Throw = ShowCursor(True)
End Sub
Private Sub Label1_Click()
QuitFlag = True
End Sub
Private Sub Label1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y
As Single)
QuitFlag = True
End Sub
Private Sub Timer1_Timer()
Unload Me
End Sub
我们稍过一会儿再分析着段代码。
四、项目设置
1, 从 Tool 菜单中选择 Options 项。
2, 选中 Advanced 标签。
3, 把 Command Line Arguments 设置为/S。
4, 从 File 菜单中选择 Make EXE File 项,弹出 Make EXE File 对话框。
5, 按 Options 按钮,弹出 EXE Options 对话框。
6, 把 Application 组 里 的 Title 设 置 为 “ SCRNSAVE 我 的 编 程 世 界 ” , 注 意 以
SCRNSAVE 开头是十分重要的。
7, 按 OK 按钮。
8, 在文件名里输入“我的编程世界 .SCR” ,注意以 SCR 为扩展名是十分重要的,这
样 Windows 才把这个程序看成是一个屏幕保护程序。
9, 按 OK 按钮, Visual Basic 为你生成你的屏幕保护程序,你只要把它拷贝到你的
Windows 目录下就可以了。
5、 使用我们的屏幕保护程序
1, 在背景上用鼠标右键单击,从弹出的快捷菜单中选择属性项。
2, 选中屏幕保护程序标签。
3, 从屏幕保护程序的下拉列表框里找到刚才制作的“我的编程世界”屏幕保护程序。
(Windows 自动在 Windows 目录和 Windows\System 子目录下寻找扩展名为 SCR
的文件作为屏幕保护程序)
4, 按确定按钮。
当你等待一段时间后你就会看到自己屏幕保护程序的运行了。
6、 当你看到自己的屏幕保护程序后,我们来看看这个程序的代码的有趣之处
QuitFlag 变量是一个布尔型的变量,它用于判断是否我们应该结束我们的屏幕保护程
序。
接下来的一个常量声明和四个 API 函数声明是从 API Text Viewer 里拷贝下来的,这些
函数使我们需要的一些功能得以实现。
SetWindowPos 函数帮助我们使窗体成为最上层的窗体,这种窗体甚至可以覆盖住汉
字输入条。ShowCursor 函数使鼠标消失和重现。Sleep 过程让程序暂停一段时间,它的唯一
的参数决定了暂停的毫秒数。SystemParametersInfo 函数在程序开始时通知系统已经有一
个屏幕保护程序被激活,在程序结束时通知系统该屏幕保护程序不再使用,这样就不会激
活新的屏幕保护程序了。
Windows 启动屏幕保护程序时会加一个命令行参数来起动程序,所以屏幕保护程序运
行起来后在 Form_Load 过程中先判断该程序的命令行参数,这些命令行参数的描述是:
命令行参数 描述
/A 在显示器属性对话框中按更改口令的按钮
/C 在显示器属性对话框中按设置按钮
/P 当选中屏幕保护程序标签时,在小显示器上显示预览
/S 在显示器属性对话框中按预览按钮,或该屏幕保护程序由系统正常启动

在本程序中,只有/S 参数有效。
下面程序将陷入一个循环,它使 Label1 一直在窗体上运动直到 QuitFlag 为 True,由于
不可以在 Form_Load 过程里卸载程序,所以我们打开一个计时器控件,让它来执行卸载的
任务。
当程序启动的时候,尽管鼠标并未移动,但还是会产生一个 MouseMove 事件(不能理
解 Visual Basic)。所以我们得忽略第一个 MouseMove 事件,在 Form_MouseMove 过程
里有一点小技巧来实现这个忽略。
怎么样?Visual Basic 比你想象的有乐趣吧!
第十一 章 创建 ActiveX控件

ActiveX 控件可添加到任一工程类型中。当控件作为某个 .exe 文件的一部分编译时,它不


能被其它应用程序共享。在本章后面的步骤中,ShapeLabel 控件被编译进一个 .ocx 文件,
这样它可以被共享。 因此将像 ActiveX 控件工程那样创建 ControlDemo 工程。
一个 ActiveX 控件工程能够包含任意个所需的控件。 创建工程时,.ocx 结果文件包含已
添加的所有控件。
§1 创建 ControlDemo 工程
1 在“文件”菜单上单击“新建工程”打开“新建工程”对话框。(这将关闭当前工程或
工程组,系统会提示保存所作的改变。)双击“ActiveX 控件”图标用以创建新工程。
Visual Basic 自 动 地 把 一 个 UserControl 设 计 器 添 加 到 此 工 程 中 。 缺 省 名
UserControl1 作为设计器的标题出现。

2 在“工程”菜单上单击“Project1 属性”,打开“工程属性” 对话框。选择“通用”


选项卡,填写如下所示的信息后单击“确定”。

3 在“工程资源管理器”窗口中双击 UserControl1 使设计器置前。


4 在“属性”窗口中双击“名称” 属性并且把用户控件名改为 ShapeLabel。新名字出现
在设计器的标题和“工程资源管理器”窗口中。
用户指定的名字成为用户控件的类名,正如 CommandButton 是命令按钮的类名一样。
“建立 ActiveX 控件”提供了选择控件类名的指南。
要注意“属性”窗口看上去很像 Visual Basic 窗体。只是习惯见到的某些属性消失了,
而有的一些属性在一般的 Visual Basic 窗体上又找不到。这些属性将在“建立 ActiveX
控件”中讨论。
5 在该控件设计器中,控件右下角的拖曳点可调整控件的大小,向左上拖动该点使控件
变小。
这样就设置了控件的默认尺寸。 为了后面过程中方便,ShapeLabel 控件应有适当的大
小。
6 在“文件”菜单上单击“保存工程”可保存工程文件。用下表所示方式给它们命名。
Visual Basic 自动提供所指定的扩展名。
文件 文件名 扩展名
用户控件 ControlDemo_ShapeLabel .ctl
工程 ControlDemo .vbp

控件中诸如位图之类的二进制信息会保存到一个同名的二进制文件中,该文件的扩展
名为 .ctx 。

§2 添加 TestCtlDemo 工程
为了测试 ShapeLabel 控件,需要有一个测试窗体。由于 .ocx 工程不能独立运行,所以不
能只是把测试窗体添加到 ControlDemo 中后运行该工程。(这样相当于只靠自身运行 .ocx
文件。)
为了能够调试运行中的部件,Visual Basic 允许在同一工程组中装入两个或更多的工程。
除了使运行中的调试生效以外,该工程组还使得 .ocx 工程和测试工程的装入更加容易。
为了将测试工程添加到工程组中
1 在“文件”菜单上单击“添加工程”用以打开“添加工程”对话框。
重点 不要单击“打开工程” 或“新建工程”,否则会关闭控件工程。
2 可双击“Standard EXE”图标以添加普通的 .exe 工程。 现在既可以看见“工程资源
管理器”窗口中的工程,也可以看见“工程资源管理器”窗口的标题所显示的缺省工程组
名。
该新工程立即成为这个工程组的“启动”工程。“工程资源管理器”窗口以其黑体名字
的显示来标识“启动”工程。 一个像 ControlDemo 那样的 ActiveX 控件工程是不能作为
启动工程的。
3 在“文件”菜单上单击“保存工程组”用以保存测试工程和工程组。 按如下所示方式
给文件命名。Visual Basic 自动提供所指定的扩展名。
文件 文件名 扩展名
窗体 TestCtlDemo_Form1 .frm
工程 TestCtlDemo .vbp
工程组 ControlDemo .vbg

§3 设计时运行 ShapeLabel 控件
与其它可编程对象不同,控件同时具有设计时和运行时的两种行为。 即开发者在设计时把
一个控件实例放入窗体时,控件中的一些代码将会执行。
例如,放置在 UserControl_Resize 事件过程中的代码在设计和运行时都会执行。
为了调试控件设计时的行为,当放置有控件的测试窗体保持在设计模式中时,必须能够执
行控件中的代码。
以下两个过程演示了这种灵活技巧。在第一个过程中,把代码添加到 ShapeLabel 控件的
Resize 事件中。在第二个过程中,当测试工程保持在设计模式中时,使 ControlDemo 的一
部分进入运行模式后把 ShapeLabel 控件的实例添加到测试工程的窗体中。
为了把代码添加到 Resize 事件中
1 在“工程资源管理器”窗口双击“ShapeLabel”使其成为活动的设计器。
2 双击“ShapeLabel”控件打开代码窗口。
3 在过程框中单击 Resize 事件以进入它的事件处理过程。添加下列代码:
Private Sub UserControl_Resize()
Static intCt As Integer
intCt = intCt + 1
Debug.Print "Resize " & intCt
End Sub

注意 事 件 处 理 过 程 名 具 有 “ UserControl” 前 缀 , 正 如 相 对 普 通 窗 体 的
Form_Resize 事件过程具有前缀“添加窗体”一样。

开发普通的 Visual Basic 应用程序时,需要单击工具栏上的“启动”按钮或者按下 F5


键来运行应用程序。然而要把 ShapeLabel 控件放入 Form1,只须运行此控件的代码而把其
它代码保持在设计模式中。
在设计时运行 ShapeLabel 控件
1 在“工程”口中双击 ShapeLabel ,将设计器前置,然后按下 CTRL+F4 来关闭窗口。
关闭设计器窗口使 ShapeLabel 控件进入运行模式。只要控件进入运行模式,其图标(用户
控件的默认工具箱图标)就出现在工具箱中。
重点 不要单击工具栏上的“启动”按钮或者按下 F5 键,因为那样会使整个工程组
进入运行模式从而无法把新控件添加到窗体中。
当控件进入运行模式时,是否关闭设计器窗口就是无关紧要的了。(因为控件工具箱将变成
灰色,所以总知道设计器是否打开。)
2 在“工程资源管理器”窗口双击“Form1”使其置前。
3 双击“ShapeLabel”图标以便把 ShapeLabel 控件添加到 Form1 中。该控件以带有抓
取控点的灰色平面矩形形式出现。
在“属性”窗口可以看见新控件的默认属性。刚刚添加到窗体中的 ShapeLabel 控件已
被赋予缺省名 ShapeLabel1。
注意 开始设计控件时便为其命名可避免引起混淆。假定把一个具有缺省名(比如
UserControl1)的控件放入窗体,新控件自动编号功能会把一个数字附加到这个控件名之
后,得到一个象 UserControl11 这样的易混淆的名字。
4 当 ShapeLabel 控件放入窗体时,Resize 事件被引发。查看“立即”窗口能够见到这
一事件。使用抓取控点进行数次调整控件大小的动作。每次调整控件大小时,Resize 事件均
再次引发。
如果只是在窗体里简单地移动控件,Resize 事件不会引发。
5 在 Form1 上双击“ShapeLabel”控件以便打开 Form1 的代码窗口。光标将出现在缺省
事件过程 ShapeLabel1_GotFocus 上。可以用“过程”框来查看 Visual Basic 自动为控件
提供的另外三种事件。 完成工作后要关闭代码窗口。
6 在“工程资源管理器”窗口双击“ShapeLabel”以便打开 ShapeLabel 设计器。 请注
意放在 Form1 上的 ShapeLabel 控件标记上了阴影,这表明它是非活动的。
打开一个控件的设计器会使该控件的所有实例变成非活动的。 更改控件代码窗口的代
码也会使控件实例变成非活动的。
7 当设计器打开时,不能执行 ShapeLabels 代码模块中的代码。 可用控点来调整 Form1
中带阴影的 ShapeLabel 控件的大小。Resize 事件不激发,因此在“立即”窗口不会出现
新消息。
8 确保 ShapeLabel 的设计器在前面,然后按下 CTRL+F4 以关闭窗口,重新激活控件实
例。阴影从 Form1 的控件上消失表明实例又被激活了。
如果由于改动控件的代码而使控件变成非激活状态时,那么可用鼠标右键单击测试窗
体以便显示其上下文菜单,单击“更新用户控件”可重新激活控件实例。
§4 UserControl 对象的存活期
普 通 的 Visual Basic 窗 体 存 活 期 由 一 些 关 键 事 件 所 标 记 , 比 如
Initialize、Load、QueryUnload 和 Unload 等事件。为了创建行为符合标准的应用程序,知
道这些事件在窗体存活期中何时引发是十分重要的。
这 对 控 件 也 同 样 适 用 。 UserControl 存 活 期 中 的 关 键 事 件 是
Initialize,InitProperties,ReadProperties,WriteProperties 和 Terminate。下列过
程将探讨这些事件。
为了观察 ShapeLabel 的关键事件,
1 在“工程资源管理器”窗口双击“ShapeLabel”以便打开其设计器。
2 双击设计器,为 ShapeLabel 打开代码窗口,并输入下列事件过程中的代码:
Private Sub UserControl_Initialize()
Debug.Print "Initialize"
End Sub

Private Sub UserControl_InitProperties()


Debug.Print "InitProperties"
End Sub
Private Sub UserControl_ReadProperties(PropBag As _
PropertyBag)
Debug.Print "ReadProperties"
End Sub

Private Sub UserControl_WriteProperties(PropBag _


As PropertyBag)
Debug.Print "WriteProperties"
End Sub

Private Sub UserControl_Terminate()


Debug.Print "Terminate"
End Sub

注意 对于 UserControl 对象而言,Load 和 Unload 事件被 ReadProperties 和


WriteProperties 事件所代替。“建立 ActiveX 控件”中的“理解控件的存活期和关键事
件”部分将更加详细地讨论这些内容。
3 确保 ShapeLabel 的设计器在前面,然后按下 CTRL+F4 以关闭窗口,使控件进入运行
模式。 调试信息将出现在“立即”窗口中。
这里发生了什么事情呢? 尚未将 ShapeLabel 控件的另一个实例放入 Form1。所有这
些事件来自何处?
这说明了有关控件的一个重要问题。 把控件放入窗体后,它就被视为这个窗体的永久
设施了。以控件作者的眼光来看,控件总是在被撤消和重建。
通过关闭 ShapeLabel 的设计器而将 ShapeLabel 置于运行模式时, Form1 上的
ShapeLabel 实例被撤消并重建,这时它接收一个 Initialize 事件。为什么首先看不见
Terminate 事 件 ? 这 是 因 为 置 在 Form1 上 的 原 始 ShapeLabel 实 例 是 添 加
UserControl_Terminate 事件过程代码之前创建的!欢迎来到充满活力的创建控件的拓荒
之地。
注意 单击窗体上下文菜单上的“更新用户控件”时,控件各个实例也都将被撤消和
重建。
4 按下 CTRL+F5 键或者单击工具栏上的“启动” 按钮来运行 TestCtlDemo。工程运行时,
Form1 上的网格消失,因此看不见 ShapeLabel,但是在“立即”窗口可以看见其实物的闪
现。
控件实例创建之后,ReadProperties 事件提供机会,从包含此控件实例的窗体所属的
.frm 文件获取该控件所保存的属性值。
当设计时的控件实例被撤消时,WriteProperties 事件提供机会以保存在设计时设置
的属性值。属性值保存于包含窗体的 .frm 文件中,正如在本章后面“保存 ShapeLabel 控
件的属性值”中所见到的一样。
控件撤消时引发 Terminate 事件。
注意 根据默认,在(由“工具”菜单访问的)“选项”对话框的“通用”选项卡上
选中“请求时编译”选项。用 CTRL+F5 (或“运行”菜单上的“启动全编译”)覆盖“请
求时编译”,并在进入运行模式之前编译组中全部工程。这是很有用的,因为编译错误通常
要求重新设置工程,这意味着要返回设计模式。在调试控件时,可能宁可关闭“请求时编译
”,也不愿意使用 CTRL+F5。
5 关闭 Form1 将工程返回到设计模式。在“立即”窗口中,当运行时期的 ShapeLabel
实 例 被 撤 消 时 , 将 看 见 一 个 Terminate 事 件 ( 但 不 是 WriteProperties , 为 什 么 不 是
呢?)。然后当设计时的控件实例被创建时会看见 Initialize、ReadProperties 和 Resize
事件。
运行时期的控件实例永远不会获得 WriteProperties 事件,因为它并不需要保存其属
性值。要知道为什么,应考虑 ShapeLabel 的未来。 当它被便编译成 .ocx 文件时,它会被
添加到另一个工程,把一个实例放入窗体,将此工程编译成一个 .exe 文件并使其运行。
关闭该 .exe 文件时,ShapeLabel 实例能够保存其属性值的唯一地方就是该 .exe 文件。
而行为标准的操作系统不能容许这类行为。
6 滚动到“立即”窗口的顶端,单击左上角,拖动以选择该窗口的全部文本。 按下
DELETE 键清除此窗口。
7 在“工程资源管理器”窗口双击 Form1 使其置前。
8 在“工具箱”上双击“ShapeLabel”图标把另一个控件实例添加到“Form1”中。这时
会看见一个新事件。
把控件的新实例放入容器时,它获得一个 InitProperties 事件。 可把代码放入
UserControl_InitProperties 事件过程以便:
■ 为每个控件属性值设置缺省值
■ 无论何时创建控件实例均执行任务。
1 单击 Form1 设计器的“关闭”按钮或在设计器前置时按下 CTRL+F4 使其关闭。在“立
即”窗口会看见两组 WriteProperties 和 Terminate 事件,各自对应 ShapeLabel 的一
个实例。
2 在“工程资源管理器”窗口双击 Form1 再次打开其设计器。当设计器打开时,Form1
上 的 所 有 控 件 均 被 创 建 并 且 它 们 的 Initialize 事 件 被 触 发 。 之 后 所 有 控 件 接 收
ReadProperties 事件,从而允许它们检索其已保存的属性值。 InitProperties 事件不会
引发,因为 ShapeLabel 控件的两个实例均已存在。
§5 ShapeLabel 控件的画出
可使用诸如 Circle 和 Line 的图形方法绘出控件,或者使用已有的 ActiveX 控件和
Visual Basic 内在的控件创建自己控件的外观。添加给 UserControl 为其创建外观的那些
控件称之为子控件。
就象它的名字所表明的一样,ShapeLabel 的外观就是由 Shape 控件和 Label 控件创建的。
给 ShapeLabel 添加字控件
1 在“工程资源管理器”窗口双击“ShapeLabel”打开它的设计器。
2 在“工具箱”上双击 Visual Basic Shape 控件把 Shape 控件放到 ShapeLabel 设计
器中。如果以前尚未使用过 Shape 控件,把鼠标保持在工具框按钮上直至发现其 ToolTip
是“形状”。
3 在“属性”窗口为 Shape 控件设置以下属性值:
属性 值
BorderStyle 0 - 透明的
FillColor &H000000FF (红色)
FillStyle 0 - 实线
Name shpBack
Shape 2 - 椭圆

注意 要将诸如 FillColor 和 ForeColor 等的属性设置成指定的颜色,应选择“颜


色选择”对话框的“调色板”选项卡。
4 在“工具箱’上双击 Label 控件,在 Shape 控件顶部添加一个选项卡。在“属性”窗
口为 Label 控件设置以下属性值:
属性 值
Alignment 2 - 居中
BackStyle 0 - 透明的
ForeColor &H00FFFFFF (白色)
Name lblCaption

5 使用底部抓取控点调整此选项卡的高度,使它稍高于所包含的正文。
6 双击 ShapeLabel 设计器使代码窗口置前,用以下代码替换 UserControl_Resize 事
件过程中的代码:
Private Sub UserControl_Resize()
' 变换 Shape 控件的大小
' 以便填充 ShapeLabel 的可见表面。
shpBack.Move 0, 0, ScaleWidth, ScaleHeight
' 使 Label 控件垂直居中,
' 并使它的宽度与 ShapeLabel 一致。
lblCaption.Move 0, (ScaleHeight _
- lblCaption.Height) / 2, ScaleWidth
End Sub
7 在对用户控件进行设计时,要记住只能在由控件的 ScaleWidth 和 ScaleHeight 约束
的区域内工作。这个区域以外的任何事物对用户都是不可见的。此外,客户区的大小将随着
用户的想法而改变。于是 Resize 事件就是控件设计中最重要事件之一。
8 确保 ShapeLabel 的设计器在前面,然后按下 CTRL+F4 以关闭窗口,使 ShapeLabel
进入运行模式。在“工程”窗口双击 Form1 使其置前。
9 现在两个 ShapeLabel 控件将以红色椭圆形式出现,带有居中的 Label1 的白色标题。
可以调整 ShapeLabels 大小以测试 Resize 事件代码。
§6 保存 ShapeLabel 控件的属性值
与在类模块中借助创建公共过程的方式添加属性名和方法类似,可以在 Active 控件中添
加属性和方法。由于 ShapeLabel 将成为一个增强的控件,所以具有 Caption 属性将是很
有意义的。
下列过程添加一个 Caption 属性和保存和检索属性值的支持代码。控件的属性值一直是和
描述容器的其它数据一起保存,本例中的容器是 Form1。
在 ShapeLabel 控件中添加 Caption 属性
1 在 “ 工 程 资 源 管 理 器 ” 窗 口 双 击 “ ShapeLabel” 打 开 其 设 计 器 , 再 双 击
“ShapeLabel”使其代码窗口置前。
2 在“工具”菜单上单击“添加过程”打开“添加过程”对话框。在“名称”框输入名字
Caption。 单击“属性”和“公共的”后再单击“确定”。
3 在代码窗口更改如下面所出现的新创建的属性过程。
Public Property Get Caption() As String
Caption = lblCaption.Caption
End Property

Public Property Let Caption( _


ByVal NewCaption As String)
lblCaption.Caption = NewCaption
PropertyChanged "Caption"
End Property
注意 如上所示,在加入 As String 时要注意同时更改两个声明行。Property Get
和 Property Let 声明必须匹配。使用特定的类型名可加快执行速度,并且能为使用控件的
开发者提供类型检查。
无论何时给 Caption 属性赋新值均执行 Property Let 过程。 它把新值直接保存到
ShapeLabel 上的 lblCaption 选项卡的 Caption 属性中。
无论何时检索该属性值均执行 Property Get 过程。它要读取保存在 lblCaption 选项
卡的 Caption 属性中的该值。
如“建立 ActiveX 控件”中的“给控件添加属性”所述,控件中的 Property Let 过
程必须调用 PropertyChanged 。这就告诉“属性”窗口刷新其显示内容,并通知 Visual
Basic ,窗体已经改变了。
Property 过程的讨论可在《程序员指南》的 “用对象编程”中的“给类添加属性”部
分找到。
4 为了初始化 Caption 属性,在 UserControl_InitProperties 事件过程中添加下列代
码:
Private Sub UserControl_InitProperties()
'将 ShapeLabel 实例的名字
'赋给 Caption 属性
'作为它的初始值。
Caption = Extender.Name
Debug.Print "InitProperties"
End Sub

该例中的 Extender 对象是什么? 对控件用户而言,extender 属性同 Name 、Top 和


Left 属性一样,是用户控件的一部分。 实际上 extender 属性是由控件所属的容器对象提
供的。UserControl 的 Extender 对象使得控件设计器能够从控件内部访问这些属性。
Extender 对象的只读的 Name 属性返回容器(或用户)赋予控件的特定实例的名字。
用这个名字(例如,ShapeLabel1)作为 Caption 属性初值来模仿 Label 控件的行为。
提示 如果控件要模仿一个提供类似功能的控件,那么用它会更加直观。
当为控件创建 Name 属性会发生什么事情?将能够从控件内部访问它,但用户所能看
见的 Name 属性只是 Extender 对象的 Name 属性。
这就引入了一个控件再现的主题:容器能决定控件的大部分行为和外观。 容器确定控
件的 Name,以及保持相对容器坐标关系的 Top 和 Left 属性。“建立 ActiveX 控件”会
再次提出主题。
最 后 : 为 什 么 要 把 这 些 代 码 放 在 InitProperties 事 件 中 ? 为 什 么 不 使 用
Initialize 事件呢?如同所见,每当控件实例被创建时均调用 Initialize,它是频繁引
发的。而 InitProperties 是仅当用户把控件放入容器时才被引发。此时设置控件实例的初
值较为合适。
此 外 当 Initialize 事 件 引 发 时 , UserControl 对 象 的 Extender 和
AmbientProperties 对象尚且不能使用。 “建立 ActiveX 控件”中的“理解控件的存活期
和关键事件”部分将讨论 Initialize 事件的恰当用法。
5 要保存 Caption 属性值,可把下列代码添加到 UserControl_WriteProperties 事件
过程中:
Private Sub UserControl_WriteProperties(PropBag As _
PropertyBag)
Debug.Print "WriteProperties"
PropBag.WriteProperty "Caption", Caption, _
Extender.Name
End Sub

PropertyBag 意如其名,是一个保存属性值的口袋。该口袋由容器提供。用户不必了解
它的工作原理,也不必了解数据在何处以及是怎样保存的。 所做的全部事情就是放入值和
取出值。
WriteProperty 方法的第一个参数是属性名,它将作为检索键使用。 应使用属性名作
为这个参数,因为它将出现在 .frm 文本文件中(在 Visual Basic 中,其它容器可能使
用别的文件名来保存工程数据),而且对于该控件的用户是可见的。
第二个参数是值。 属性值作为一个 Variant 被保存。
第三个参数很特别,是一个缺省值。 保存属性值时为什么要提供一个缺省值呢? 在保
存该值之前,WriteProperty 方法要用此缺省值和属性值作比较。 若二者相同,则该属性
值就不必保存,因为当控件重新加载时会自动装入此缺省值。 这样就避免了使 .frm 文件
与数百个缺省条目混杂,对用户来说是十分有利的!
6 将下列代码放入 ReadProperties 事件中,可用来为 Caption 属性检索持久值。
Private Sub UserControl_ReadProperties(PropBag As _
PropertyBag)
Debug.Print "ReadProperties"
Caption = PropBag.ReadProperty("Caption", _
Extender.Name)
End Sub
ReadProperty 方法的第二个参数作为缺省值的使用是当如果没有保存任何值,如果用
户已从文本文件删除了该属性,或者如果从未改变过这个缺省值,自然也就从未通过
WriteProperty 保存过它的时候。
7 确保 ShapeLabel 的设计器在前面,然后按下“关闭”按钮或 CTRL+F4 以关闭窗口,
使控件进入运行模式。 ShapeLabel 控件的标题会发生改变从而得以匹配两个实例的缺省名
字 ShapeLabel1 和 ShapeLabel2。
使用“属性”窗口改变 Form1 上的两个 ShapeLabel 控件的“标题”属性,然后单击
Form1 设计器的“关闭”按钮。 在“工程资源管理器”窗口双击“Form1”重新打开 Form1
设计器。
从“立即”窗口的消息中可以看见控件已经被撤消和重建,但“标题”属性值已被保
存及检索。
8 按 下 CTRL+F5 键 以 运 行 TestCtlDemo , 即 工 程 组 的 Startup 工 程 , 并 观 察
ShapeLabel 控件在运行时期的行为。
9 单击 Form1 的“关闭”按钮以返回到设计模式。
§7 为 ShapeLabel 控件添加一个属性页
使用属性过程所创建的一些简单属性将自动显示在 Visual Basic 的属性窗口中。 也可以
使控件和属性页相连接,属性页以另一种格式显示控件的各种属性。
与控件连接的每一个属性页都成为选项卡化的属性对话框上的一个选项卡。 Visual Basic
处理选项卡化对话框所说明的页面的所有细节,并管理“确定”、“取消”和“应用”等按
钮。 用户必须做的全部事情就是设计将用于设置属性值的控件。
当一组属性以复杂的方式相互作用时,正如 Visual Basic 包含的 Toolbar 控件的情况,
属性页就十分有用。 对于将在各国发布的控件来说属性页也很有用,因为针对不同语言可
将标题本地化。 属性页也使控件能够和没有 Properties 窗口的开发工具一起使用。
向工程添加属性页
1 在“工程资源管理器”窗口单击 ControlDemo 以打开控件工程。在“工程”菜单上单
击“添加属性页”以打开“添加属性页”对话框。双击“属性页”图标,以向工程添加属性
页。
2 在“属性”窗口双击 Name 属性,并把属性页的名称变成 SLGeneral。双击 Caption
属性并把标题变成“通用”。
在使用标题时,这个标题就是出现在属性页选项卡上的标题。为什么要命名页
SLGeneral 而不是通用?在一个工程中可以有几个控件,而每一个控件可以有一个通用页。
这就是 ShapeLabel 控件的通用页。
3 在“文件”菜单上单击“保存工程组”来保存工程组。象下表那样显示属性页的名称。
将自动提供已指出的扩展名。
文件 文件名 扩展
属性页 ControlDemo_SLGeneral .pag

属性页中象位图之类的二进制信息都被保存在名称相同的二进制文件中,该文件的扩
展名为 .pgx。
除了设计器的标题栏显示的是属性页的“标题”属性而不是以“名称”属性,属性页
设计器看上去很像控件设计器。
为设计 ShapeLabel 控件的通用属性页
1 把 Label 控件放入该属性页,并把该 label 的 Caption 属性设置为 Caption 这个
字。
2 在该 label 下面放一个 TextBox 控件,并赋予它以下属性值:
属性 值
名字 txtCaption
文本 <空>

按照这种方式把属性描述选项卡放在文本框之上,使得为其它语言进行控件部件的本
地化更加容易,“标题”这个字所在之处可能更长或更短。 “建立 ActiveX 控件”将讨论
控件本地化的细节。
3. 双击“属性页”以打开代码窗口。 在 Events 的下拉表中选择 SelectionChanged 事
件并且添加下列代码:
Private Sub PropertyPage_SelectionChanged()
'在当前选择的控件列表中
'显示第一个控件的标题。
txtCaption.Text = SelectedControls(0).Caption
End Sub
本事件的目的是从 ShapeLabel 控件或当前所选择的那些控件中取得已存在的属性值。
这样做是正确的,可能有多个 ShapeLabel 控件被选。多重选择对控件用户来说是重要的事
情,但这意味着要多做一些工作。
无论何时打开属性页均接收一个 SelectionChanged 事件。 选择控件列表改变时也接
收这个事件。 这是必须的,因为“属性页”对话框为非模式对话框,当对话框打开时用户
可能选择其他的一些控件。
必须在按属性逐个进行的基础上决定如何处理多重选择。 例如,如果属性页显示的是
SelectedControls 集合中第一个控件的 Width 属性,即 SelectedControls(0),如以上
代码所示,它就能很容易的把所有选择控件的宽度改变为那个值。
从另一方面而言,把窗体中所有 ShapeLabel 控件的标题设置成相同值的操作并没有
太大的用处,那样的话如果 SelectedControls 集合的 Count 属性大于一时则与 Caption
属性有关的逻辑处理将会使 txtCaption 无效。
然而这个过程不作逻辑处理。为了说明起见,将允许属性页设置多重标题。以后若想让
上面描述的行为生效,可把下列代码行添加到 PropertyPage_SelectionChanged 事件过程
中:
'请先不要这样做!
If SelectedControls.Count > 1 Then
txtCaption.Enabled = False
Else
txtCaption.Enabled = True
End If
4 为了对当前选择的所有控件设置属性值,把下列代码添加到 ApplyChanges 事件中:
Private Sub PropertyPage_ApplyChanges()
'在选择一个以上控件类的情况下,
'使用一般性对象变量。
Dim objControl As Variant
For Each objControl In SelectedControls
objControl.Caption = txtCaption.Text
Next
End Sub
单击“属性页”对话框的“应用”或“确定”按钮,或者切换到其它选项卡时,属性
页将接收 ApplyChanges 事件。
怎样得知 SelectedControls 中的各个控件是否具有 Caption 属性呢?作为控件部件
的设计器来说,要确定哪些属性页与任一给定的控件相连接。 如果所有当前选择的控件的
Property Pages 清单中都具有某一页,则该属性页出现。 最容易做的事就是确保分配给每
个控件的那些页不显示该控件所不具有的属性。
倘若希望一些控件使用一个通用属性页,其中一些控件又不具有该页出现的所有属性
时,可以给 ApplyChanges 事件添加代码,以进行控件类型的检测并提供适当的属性值。
作为一种替代,也可使用 On Error 语句捕获和忽略来自不具有该属性控件的一些错误。
仅需要考虑自己部件中的那些控件,因为不在自己部件中的那些控件决不会使用本部
件的属性页。
“创建 ActiveX 控件的属性页”将会很详细地讨论属性页的布局和赋值。
5 为了在 Caption 属性改变时使“属性页”对话框的“应用”按钮有效,把下列代码添
加到 txtCaption 文本框的 Change 事件中:
Private Sub txtCaption_Change()
' 属性页的改变了的
' 属性控制 Property Pages
' 对话框的“应用”按钮。
Changed = True
End Sub
6 在“工程”窗口中双击 SLGeneral ,使属性页设计器在前面。单击设计器的关闭按钮
或按下 CTRL+F4 以关闭设计器并使该页进入运行模式。 像 UserControl 对象一样,
PropertyPage 对象仅当工程组的其余部分处于设计模式时才能运行。
将属性页和 ShapeLabel 控件相连接
1 在“工程资源管理器”窗口双击“ShapeLabel”以打开设计器。
2 在“属性”窗口双击 PropertyPages 属性以显示“连接属性页”对话框。
Connect Property Pages 对话框可用于将多个属性页与一个控件相连接、并可为控件
安排“连接属性页”对话框中各选项卡的显示顺序。
运行时也能连接属性页。 这将在“创建 ActiveX 控件的属性页”中讨论。
3 复选“SLGeneral”后单击“确定”。
4 使 ShapeLabel 设 计 器 前 置 , 然 后 单 击 其 “ 关 闭 ” 按 钮 或 按 下 CTRL+F4 以 使
ShapeLabel 控件进入运行模式。
5 在“工程资源管理器”窗口双击“Form1”以打开其设计器。
6 在 Form1 上任一个 ShapeLabel 的控件上单击右键以显示上下文菜单,并单击“属性
”以显示“属性页”对话框。
7 在“通用”选项卡上的“标题”框中用一个新值代替当前标题。 进行这项工作后,“
应用”按钮处于有效状态。 单击“应用”按钮以改变该控件的标题。
注意 按下“确定”键也可改变该标题,但那样会关闭“属性页”对话框。对话框应
保持打开状态以便进行下一步。
8 保持按下 CTRL 键的同时单击 Form1 上的第二个 ShapeLabel 控件,从而选择两个
ShapeLabels。 改变标题并单击“应用”按钮使两个标题设置成相同的值。
可能希望试一试把诸如命令按钮之类的其它控件添加到 Form1 中,并且观察在“属性
页”对话框上作不同复选的效果。
9 当试验完成之后单击“确定”以关闭“属性页”对话框。
§8 为 ShapeLabel 控件添加事件
区分清 UserControl 对象(或者它所包含的控件)接收的事件与控件引发的事件这一点非
常重要。控件所接收的那些事件提供了做某些感兴趣事情的一些机会,而控件引发的那些事
件则为使用该控件的开发者提供了做某些感兴趣事情的一些机会。
有许多可能引起 ShapeLabel 控件用户感兴趣的事件。 Visual Basic 的 Label 控件引发
一个 Click 事件,而 ShapeLabel 正是一个高级的选项卡,因此下列过程将添加一个
Click 事件。 为了使该事件更有意思,仅当用户单击椭圆背景时才引发。
在控件中加入特定事件的重要原因是出于与相同类型的其它控件兼容。 引发何种事件的其
它选择标准可参见“建立 ActiveX 控件”中的“在控件中产生事件”部分。
为 ShapeLabel 控件添加 Click 事件
1 在“工程资源管理器”窗口单击“ShapeLabel”,选择它后按下 F7 键或单击“工程
资源管理器”窗口工具栏的“代码”按钮来打开“代码”窗口。
2 在“对象”框选择“通用”。 在“过程”框选择“声明”以定位到代码模块的顶部。
添加下列代码:
Option Explicit
' 声明一个不带参数的公共 Click 事件。
Public Event Click()
3 在“对象”框选择“ lblCaption”。 在“过程”框为这个选项卡控件选择 Click
event。 把下列代码添加到 lblCaption_Click 事件过程中:
Private Sub lblCaption_Click()
' 无论何时在此选项卡上单击均
' 引发 Click 事件。
RaiseEvent Click
End Sub
仅 当用 户单 击子 控件 lblCaption 时 ,上 述代 码才 引发 Click 事件 。若 能够 在
ShapeLabel 的椭圆背景的任意处单击,那么看上去显得更自然,所以下一步所示的是单击
彩色椭圆时如何引发 Click 事件。
4 在“对象”框选择 UserControl。在“过程”框选择 UserControls'MouseUp 事件。把
下列代码添加到 UserControl_MouseUp 事件过程中:
Private Sub UserControl_MouseUp(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
' 仅当被单击色点的颜色和
' Shape 控件的颜色匹配时才引发
' 一个 Click 事件。 ' 忽略椭圆以外
' 的单击。
If Point(X, Y) = shpBack.FillColor Then
RaiseEvent Click
End If
End Sub

确定一个事件在特定的位置是否会发生称之为击点检测。
或许会希望把击点检测代码放在 shpBack_Click 事件过程中,因为 shpBack 总是要
改变大小以便覆盖 ShapeLabel 控件的整个表面。 然而 Shape 控件不会接收 Click 事件。
而由包含 Shape 对象的容器来接收 Click 事件,就本例来说是 UserControl 对象。
“建立 ActiveX 控件”中的“绘制控件”部分讨论关于创建非规则形状控件时透明背
景的使用。
5 在“工程资源管理器”窗口单击“Form1”以选择它,然后按下 F7 键或单击“工程资
源管理器”窗口工具栏的“代码”按钮来打开“代码”窗口。
6 在“对象”框选择一个添加到 Form1 中的 ShapeLabel 控件。 在“过程”框选择
Click 事件。
注意 如果 Click 事件没有出现,则应确定 ShapeLabel 设计器关闭。

把下列代码添加到 ShapeLabel1_Click 事件过程中:


Private Sub ShapeLabel1_Click()
MsgBox "Thanks for clicking! My caption is: " _
& ShapeLabel1.Caption
End Sub

注意 如果所选的 ShapeLabel 的命名不是 ShapeLabel1 时,那么输入以上代码时


应当使用相应的名字。

可单击 Procedure 框上的箭头,查看 ShapeLabel 控件的所有事件。除了 Click 事件


之外,还有四个事件:DragDrop,DragOver,GotFocus 和 LostFocus 作为 Click 事件的
补充,它们由 Form1 容器自动提供。
7 在工具栏单击“启动”按钮或按下 CTRL+F5 键运行 TestCtlDemo。尝试单击窗体和
ShapeLabel 控件的各种位置,以验证只有在椭圆背景内单击时才会引发 Click 事件。
8 在 ShapeLabel 的 click 事件的击点检测中有一个微妙错误。要查看这个错误,当鼠
标指针在红色椭圆的下半部时按下鼠标键。 保持鼠标键按下,小心地移动鼠标指针,直至
箭头的尖端指在 ShapeLabels 标题的白色正文上时再释放鼠标键。 消息框不会出现!
lblCaption_Click 事件过程不能执行,其原因是 MouseDown 事件在 UserControl 之
上出现。 因此当 MouseUp 事件发生时,它会被 UserControl 接收,甚至鼠标已经完全移
出了 Form1 时亦如此。
MouseUp 事件中的击点检测代码是当鼠标键在由 lblCaption 的透明背景所显示的红
色背景上释放时工作,而当鼠标键在正文的白色前景颜色上释放时,击点检测代码不工作。
(如果在 ShapeLabel 以外释放鼠标键,则 Point 函数返回 -1,因此在某些随机的红色
位置上释放鼠标键不会引发 Click 事件。)
改正这个错误的对象留给读者作为练习。(提示: 把击点检测移 UserControl 的
Click 事件没有用处,因为当 MouseUp 事件处在不 MouseDown 的对象上时,Click 事件
不会引发。)
§9 编译 ControlDemo 部件
一旦创建了包含一个或多个 UserControl 对象的 ActiveX 控件工程时,就可以将其编译
成 .ocx 文件并在其它应用程序中使用那些控件。下列各过程示范了这些步骤。
编译 ControlDemo 工程
1 如果 TestCtlDemo 工程仍在运行模式中,单击 Form1 上的“关闭”按钮以返回设计
模式。
2 在“工程资源管理器”窗口单击“ControlDemo”以选择该工程。
3 在“文件”菜单上单击“生成 ControlDemo.ocx”以便打开“生成工程”对话框。 单
击“确定”以创建 ocx 文件。
4 在“文件”菜单上单击“删除工程”以便从工程组中删除 ControlDemo,从而使
Visual Basic 采用编译的二进制部件(.ocx 文件)代替该工程。
Visual Basic 会显示一个警告消息,因为 TestCtlDemo 工程包含对 ControlDemo 的
一个引用。单击“是”最终删除 ControlDemo。
当 从 工 程 组 删 除 了 ControlDemo 时 , Visual Basic 在 窗 口 注 册 中 寻 找
ControlDemo.ocx 。 如 果 存 在 .ocx 文 件 , Visual Basic 便 自 动 更 新 设 置 在 添 加
TestCtlDemo 工程的过程中的引用。
要切换回用工程代替二进制部件状态,可在“文件”菜单上单击“添加工程”并且将
ControlDemo 工程再添加到回工程组中。
5 按下 F5 键运行使用 .ocx 文件的 TestCtlDemo。
当 ControlDemo 正在由源代码运行时,不能从其它应用程序或者从另一个 Visual Basic
程序访问 ShapeLabel 控件。 这是因为 ActiveX 控件部件必须在进程中运行。 一旦编译成
一个 .ocx 部件,便可以从其它应用程序来测试它。
在另一个 Visual Basic 中使用 ControlDemo.ocx
1 打开一个 Visual Basic 的新实例。 在“新建工程”对话框中双击 Standard EXE 图
标以打开一个 .exe 工程。
2 在“工程”菜单上单击“部件”以打开“部件” 对话框。在 Controls 的选项卡上,
复选“ActiveX 控件创建演示”后再单击“确定”。
ShapeLabel 的图标出现在工具框中。在可以把一些 ShapeLabel 控件添加到默认窗体
中,并使用“属性”窗口设置它们的属性。也可以在 ShapeLabel 的实例上单击右键,从上
下文菜单中选择“属性”以便用属性页来编辑控件的属性。
3 按下 F5 键运行该工程。
就可以编译这个工程并运行其 .exe。

§10 重述创建控件的步骤
为了以最自然的顺序介绍新概念,本章的过程并没有遵循创建新控件正常的步骤顺序。
当创建一个新控件时一般应遵循的步骤是:
1. 确定控件将要提供的功能。
2. 设计控件的外观。
3. 设计控件的接口,即属性、方法和控件将遗弃的事件。
4. 创建由控件工程和测试工程组成的工程组。
5. 通过把控件和或代码添加到 UserControl 对象中来实现控件的外观。
6. 实现控件的接口和功能。
7. 在添加每一个接口元素或功能时,都要为测试工程增加一些功能,以便测试所添加的
新功能。
8. 设计和实现控件的属性页。
9. 编译控件部件(.ocx 文件)并用各种可能的应用程序对它进行测试。

除了以上方法,还可用 VB 6 提供的“ ActiveX 控件界面向导”来创建

ActiveX 控件。由于篇幅关系,具体步骤见授课时例子。

.第十一 章 ActiveX 文档
本章将介绍激活 Web 文档的一种动人的方法,即是把 Visual Basic 应用程序作为 Web 文档,
那就是 ActiveX 文档;如果 Visual Basic 应用程序不被包装成 ActiveX 文档,则无法在 Web
页面上显示。

§1 通过 Wizard 把 Visual Basic 应用程序变成 ActiveX 文档


本节将把一个使用 ActiveX Document Migration Wizard 将如下图所示的一个独立的
Visual Basic 应用程序变成一个 ActiveX 文档。

1. 将欲变成 ActiveX 文档的 Visual Basic 应用程序的项目放入新文件夹,然后打开。

2. 选择 Add-Ins ActiveX Document Migration Wizard,打开向导程序。


3. 点击 Next 跳过 Introduction 页面,在 Form Selection 页面选择一个 Form,如下图;

4. 单击上图中的 Next 钮,在 Option 页面选择 Comment out invalid code( 指出无效代码 ),再
单击 Next 钮。
5. 在 Finish 页面选择是否看 Summary Report,后单击 Finish 钮,就完成了。
需要特别指出的是,ActiveX Document 可以看成是一个文档,所以只有一页,即只能
由一个窗体的应用程序转变,稍后会讲如何处理多个 ActiveX Document。而且应用程序中若
有对窗体对象的引用都应换成对象 UserDocument, 否则会报错!还有应去掉应用程序中的
End 语句。
生成了 ActiveX 文档后就可以测试它了,选择 FileMake project1.exe ,Visual Basic 产
生一个作为服务器程序的 EXE 文件,ActiveX 容器与这个 EXE 文件相连处理 ActiveX 文档,
而且 Visual Basic 产生一个扩展名为 vbd 的文件,它是必须在 Internet Explorer 中打开的文件。
在 Visual Basic 中运行项目,再用 Internet Explorer 打开扩展名为 vbd 的文件,如下图:

可见该程序在 Internet Explorer 中运行起来,它的窗体部分在 Internet Explorer 的页面部


分显示,而它的菜单与 Internet Explorer 的菜单合并在一起。

§2 处理多个 ActiveX 文档
ActiveX 文档处理多个文档的方式类似与 Internet Explorer 处理超链接的方式,是从一
个文档跳到另一文档。要在多个 ActiveX 文档之间移动,可使用 HyperLink 对象,这是
UserDocument 对象的一个属性。 HyperLink 对象提供了 NavigateTo 方法,接受目标文档的
URL 变元,例如要从一个 ActiveX 文档中跳到北邮的主页,可调用下列方法:
UserDocument.Hyperlink.NavigateTo http://bupt.edu.cn
同样要显示另一 ActiveX 文档,调用同一方法:
UserDocument.Hyperlink.NavigateTo “nextdoc.vbd”
同样可以用 GoBack 和 GoForward 方法在历史清单中移动,如要返回前一访问的文档,可
用 HyperLink 对象的 GoBack 方法:
UserDocument.Hyperlink. GoBack

§3 手工创建 ActiveX 文档
1、新建一个 ActiveX 文档.EXE,打开 UserDocument 设计器。
2、在 UserDocument1 中放置控件。
3、打开“文件”菜单,选择“生成 Project1.exe”生成 Project1.exe 文件,VB 系统自动
在同一目录下生成 UserDocument1.vbd。
由于篇幅,具体请看范例 internet.vbd.

.第十二 章 用 对象链 接与嵌 入( OLE)扩 展 Visual Basic


OLE 使得 Visual Basic 应用程序能访问 Windows 环境中其他应用程序的功能。前面所用
的控件都是内置在 Visual Basic 中的,这些内置对象的出现在编辑器的工具栏中,可以把它
们放到窗体上。但 Windows 环境中的有些对象不是 Visual Basic 所独有的,未放在 Visual
Basic 中,而是由其他应用程序提供的,但可以在应用程序中使用这些对象。
Word 文档就属于这种对象,可以将 Word 文档放在应用程序中,而不需要对其文件内
容及组织方式有太多的了解。需要编辑 Word 文档时,可以暂时借用 Word 的菜单和工具条,
将其显示在应用程序中;随后用户在应用程序中就象在用 Word 一样编辑文档。
要在 Visual Basic 中加入 OLE 功能,必须用 OLE 控件,以便将其他应用程序中的对象
插入程序中。一次只能在 OLE 容器控件中放入一个对象,但统一窗体上可以含有多个 OLE
容器控件,各有自己的对象。

§1 设计时链接与嵌入

1、 用拖放法嵌入对象
用拖放法嵌入对象的具体步骤如下:
1.开始一个新的 VB 项目,并把 OLE 容器控件放在窗体上。
2.在 Insert Object 对话框中,单击 Cancel 钮,以便后面放置 OLE 对象。
3.在 OLE 容器控件的 Properties 窗口中,将 SizeMode 属性变为 1-Stretch(对于可缩
放图 形 ) 或 2-AutoSize( 对 于不 宜缩 放的 文本 和图 形 ) ,以 调整 对象 或尺 寸。
SizeMode 属性取值及含义如下表:
数值 说明
Clip 对象按实际大小,大于 OLE 容器控件的部分被剪切掉
Stretch 对象图形调整成 OLE 容器控件的大小,对象的缩放可能会使图形扭曲
AutoSize OLE 容器控件缩放以显示整个对象
Zoom 对象图形尽量调整成 OLE 容器控件的大小,但保持原有比例

4.接着启动支持 OLE 的应用程序,并打开文件。本例通过拖放原应用程序的文档


到 OLE 容器控件,以实现在 OLE 容器控件中嵌入 Microsoft Word 文档。
5.在屏幕上同时显示 Visual Basic 和 Word 时(或用 Alt+Tab 切换),拖动文档或
其一部分到空 OLE 容器控件中。

6.拖动对象时,指针箭头下出现一个长方形,将其放到 OLE 容器控件中,于是


Word 文档出现在 OLE 容器控件中,如上图所示。

2、 OLE 容器控件对象的常用属性

Class 属性:产生对象的应用程序名,也是嵌入文档的类型。

SourceDoc:数据或引用的数据,即存入对象的文件名。

SourceItem:选作嵌入的文档部分(全文档时为空)。

OLETypeAllowed: 源文档是链接还是嵌入到 OLE 容器控件中,这就取决于这个


属性,它的具体取值如下:
数值 常量 说明
0 VbOLELinked 链接,OLE 容器控件只能包含链接对象
1 VbOLEEmbedded 嵌入,OLE 容器控件只能包含嵌入对象
2 VbOLEEither LE 容器控件可包含链接或嵌入对象

3、 用 Insert Object 对话框实现链接

用 Insert Object 对话框实现链接步骤的如下:


1. 开始一个新的 VB 项目,并把 OLE 容器控件放在窗体上。
2. 在 Insert Object (插入对象)对话框中,选择 Creat from File(由文件创建)选
项并选定 Link(链接)复选框。如下图中:

3.点击浏览按钮,找到所需文件。

4、 保存和获取对象

由于嵌入对象中的数据并不自动保存,要保存嵌入对象及服务器应用程序所做的
修改,可用 SaveToFile 方法:
OLE1. SaveToFile filenumber
Filenumber 对应二进制方式下打开的文件。
要装入存放成数据文件的对象,可用 ReadFromFile 方法。其语法如下:
OLE1.ReadFromFile filenumber

5、 现场编辑

现场编辑也叫现场激活,它是 Visual Basic 中嵌入对象的增强功能。最简单


的方法就是双击对象,这时应用程序的菜单和工具条可代替 OLE 容器控件的菜单
和工具条。

§2 运行时链接与嵌入
本节通过一个实例介绍运行时实现链接与嵌入。该例子有两个窗体,界面如下;

左边为主窗口,右边窗口为点按主窗口中的 Insert object... 钮后出现的,右边窗口的作用是


为动态嵌入的 OLE 容器控件设置 SizeMode 属性和 OLETypeAllowed 属性,即而装入 Insert
Object (插入对象)对话框。
下面先设计主窗口。

1、 主窗口的设计:
1. 开始一个新的 VB 项目,并把 OLE 容器控件放在窗体上。
2. 在 Insert Object 对话框中,单击 Cancel 钮,以便后面放置 OLE 对象,并按上面左
图调整 OLE 控件的大小。
3. 并按上面左图依次添加三个按钮,Caption 属性分别为 insert object... 、object info.. 、
close 。
4. 先给标为 insert object...的按钮添加代码:
Private Sub Command1_Click()
frmtype.Show
End Sub
Frmtype 为上图右边窗体的名字。再给标为 object info..的按钮添加代码:
Private Sub Command2_Click()
Dim sourcetext As String
Dim msg As String
Dim typetext As String
sourcetext = "The object's source file is " & oledisplay.SourceDoc
typetext = " The type of object is " & oledisplay.Class
msg = sourcetext + vbCrLf + typetext
MsgBox msg, vbInformation, "object information"
End Sub
该段代码是为了显示当前 OLE 控件的 SourceDoc 属性和 Class 属性。当然当 OLE 控件
为空时该按钮无效。
再给标为 close 的按钮添加代码:
Private Sub Command3_Click()
Dim quit As String
quit = MsgBox("Are you sure to want to quit?", vbYesNo + vbQuestion)
If quit = vbYes Then
End
End If
End Sub

2、 Frmtype 窗口的设计:

1.按 上图右边窗体设计其界面,其中四个 Option 按钮名字从上往下依次为 Option1


到 Option4。

2.OLE 容器控件的属性设置代码如下:
If Option1.Value = True Then
Form1.oledisplay.SizeMode = 1 'sizeMode=1---Stretch
Else
Form1.oledisplay.SizeMode = 2 '2---Autosize
End If
If Option3.Value = True Then
Form1.oledisplay.OLETypeAllowed = 1 '1--embedded
Else
Form1.oledisplay.OLETypeAllowed = 0 '0--linked
End If

3.装入 Insert Object (插入对象)对话框,可使用下面代码:


Form1.oledisplay.InsertObjDlg

4.要恢复标为 object info..的按钮有效,须用如下代码:


If Form1.oledisplay.Class <> "" Then
Form1.Command2.Enabled = True
End If

鉴于节约篇幅,不在罗列全部具体代码。读者可查看授课时提供的 DynOLE

实例。

第十三 章 使用 资源文 件

当我们的 Visual Basic 应用程序有可能适用于整个人类时,我们应该考虑为我们的应用


程序生成不同语言的版本。这种国际化的想法也许会使我们成为亿万富翁,然而这也是个不
易实现的目标,世界上有千奇百怪的语言。
程序员把不同语言的字符串看成是应用程序可利用的不同的资源,他们还把声音、图画、
菜单、光标等等都看成资源,在运行时可以根据不同的条件选择性的使用。C\C++的程序员
看来使用资源文件已经有一段时间了。这样我们就可以把为一种或多种外语重建一个应用程
序的任务简化为编辑一个 ASCII 资源文件的简单任务。资源文件的优点还有:图形图象作为
资源加载比从外部文件加载要快,多个图象更易于操作。下面我们来制作一个资源文件的实
例。

§1 建立资源文件
一、通过任何一个文本编辑器(如 Notepad)建立一个 RC 文件开始。打开 Notepad 后
输入下面这段文本。
//Moon.rc - Resource file
//rc /fo moon32.res moon.rc

//Icons
2 ICON "C:\\VB\\ICONS\\ELEMENTS\\MOON01.ICO"
3 ICON "C:\\VB\\ICONS\\ELEMENTS\\MOON02.ICO"
4 ICON "C:\\VB\\ICONS\\ELEMENTS\\MOON03.ICO"
5 ICON "C:\\VB\\ICONS\\ELEMENTS\\MOON04.ICO"
6 ICON "C:\\VB\\ICONS\\ELEMENTS\\MOON05.ICO"
7 ICON "C:\\VB\\ICONS\\ELEMENTS\\MOON06.ICO"
8 ICON "C:\\VB\\ICONS\\ELEMENTS\\MOON07.ICO"
9 ICON "C:\\VB\\ICONS\\ELEMENTS\\MOON08.ICO"

//Strings
STRINGTABLE
BEGIN
2 "月亮的相位"
3 "输入日期:"
4 "刷新相位"
12 "新月"
13 "月盈,四分之一"
14 "月盈,二分之一"
15 "月盈,四分之三"
16 "满月"
17 "月亏,四分之三"
18 "月亏,二分之一"
19 "月亏,四分之一"
END

STRINGTABLE
BEGIN
22 "Approximate Phase of the Moon"
23 "Enter a date:"
24 "Phase"
32 "New"
33 "Waxing, one quarter"
34 "Waxing, half"
35 "Waxing, three quarters"
36 "Full"
37 "Waning, three quarters"
38 "Waning, half"
39 "Waning, one quarter"
END
请注意下面的几个问题:
1, 以双斜杠开头的是注释行,在编译时将其忽略。
2, 没有使用资源号码 1,因为 Visual Basic 将这个号码用于应用程序内部储存的图标。
3, 图标的路径中用的反斜杠是双写的,“这是一种对我们不得不使用的 C 语言的嘲弄
”。
4, 上面清单假设 Visual Basic 6.0 安装在 c:\vb\子目录下,否则就找不到所需的图标了。
5, 字符串在资源文件中是以一个或多个字符串表定义的,它以 STRINGTABLE 声明
开始,在 BEGIN 和 END 中定义。
6, 把文件储存为 Moon.rc。
2、 编译 RC 文件
编译 RC 文件需要一个叫 rc.exe 的编译程序,这个编译程序通常在 VB6\wizards\上有,
如没有,也可利用 Visual C++的 rc.exe 了。Visual C++的 rc.exe 通常在 C:\MSDEV\BIN\子
目录下,当然,你也可自己找。
1, 进入 MS-DOS 方式,进入 C:\MSDEV\BIN\子目录。
2, 键入命令如下:
C:\MSDEV\BIN>rc /fo \..\moon32.res \..\moon.rc,
其中\..\代表 Moon.rc 的路径。这个命令的意思是:“把\..\moon.rc 文件编译成资源文件
\..\moon32.res。”/fo 命令行参数的意思是编译时换一个名字。
3, 关闭 MS-DOS 方式。
如果你按我说的步骤进行,那么应该是会编译成功的。现在我们已经有了所需的资源文
件了。

§2 在应用程序中使用资源文件
本程序需要两个窗体,它既演示了使用资源文件使程序国际化的简单方法,又演示了
资源文件中的资源是如何使用的。
1、 生成界面
对象 属性 设置值
Form1 Name frmCover
Caption "Approximate Phase of the Moon -- 月亮的相位"
Icon C:\VB\ICONS\ELEMENTS\MOON06.ICO
Frame1 Caption "Please select a language, 请选择一种语言:"
Command1 Name cmdChinese
Caption "中文"
Command2 Name cmdEnglish
Caption "English"
Image1 Picture FLGCHN.ICO(这是我自己做的中国国旗的图标)
Image2 Picture C:\VB\ICONS\FLAGS\FLGUK.ICO
Form2 Name frmMoon
Icon C:\VB\ICONS\ELEMENTS\MOON04.ICO
Command1 Name cmdPhase
Text1 Name txtDate
Label1 Name lblString
Image1 Name imgMoon
Label1 Name lblDate

2、 将资源文件加入到项目中
从工程(P)菜单中选择 添加文件(A)项(或右击工程资源管理器中的工程,选添加)
在 Add File 对话框中找到刚才制作的资源文件 Moon32.res,按打开按钮就可以将资源文件
加入到项目中来。每一个 Visual Basic 项目只可以加入一个资源文件。
3、 编写代码
1, 从 Insert 菜单中选择 Module 项。
2, 在新增加的 Module 中加入下面的代码:
Option Explicit

Public i As Byte
声明全局变量 i 用于表明用户选择了哪一种语言。
3, 在 frmCover 的代码窗口里加入下面代码:
Option Explicit

Private Sub cmdChinese_Click()


i=0
frmMoon.Show
Unload frmCover
End Sub
Private Sub cmdEnglish_Click()
i = 20
frmMoon.Show
Unload frmCover
End Sub
4, 在 frmMoon 的代码窗口里加入下面代码:
Option Explicit

Private Sub cmdPhase_Click()


Dim Phase
Dim ResNum As Byte

Phase = CDbl(CVDate(txtDate.Text))
Phase = Phase / 29.530589 + 0.9291176
Phase = Phase - Int(Phase)
ResNum = 2 + Int(Phase * 8 + 0.5)
If ResNum = 10 Then ResNum = 2
imgMoon.Picture = LoadResPicture(ResNum, vbResIcon)
lblString.Caption = LoadResString(ResNum + i + 10)
End Sub
Private Sub Form_Load()
Me.Caption = LoadResString(2 + i)
lblDate.Caption = LoadResString(3 + i)
cmdPhase.Caption = LoadResString(4 + i)
txtDate.Text = Format(Date, "mm/dd/yyyy")
cmdPhase_Click
End Sub
可以看到加载资源到程序中,使用了 LoadResPicture、LoadResString 方法。这一组的
函数还有 LoadResData 函数。现在双语教学软件很流行,你可以知道那些程序员是如何做
的了。

第十四 章 用 Visual Basic建立动 态链接 库( DLL)

§1 什么是动态链接库
许多程序员使用 Visual Basic 来生成用户界面,用另一种语言来生成代数运算,以使程
序效果更好。这是因为 Visual Basic 在大量数字运算时速度不高。但是,你不能指望在
Visual Basic 的代码窗口输入 C++代码,你只能输入 Visual Basic 代码。所以,你必须用另
一种编译器编写你的 C++代码,并储存在 DLL 的特定文件里。然后,编写 Visual Basic 代
码告诉 Visual Basic 如何使用放在 DLL 中的代码。
使用 DLL 的三个原因是:
1, 速度。
2, 用更恰当的语言解决问题。
3, 可重用性。
事实上,Windows 的 API 就是 DLL。DLL 就象一个黑盒子,你只需使用它而不用关心它
是如何实现的。还有,使用 DLL 是有一定风险的,比如使用 Windows 的 API,可能会使你
的计算机崩溃。

§2 用 Visual Basic 生成 DLL


这简直另人惊讶,但对 Visual Basic 程序员来说,这又另人兴奋。说实在的, Visual
Basic 的 DLL 比其它语言生成的 DLL 速度要慢,但有三个原因使 Visual Basic 程序员喜欢
使用 Visual Basic 的 DLL。一是 Visual Basic 很好用,很容易;二是你不需要学另一门语言
或买另一种编译器;三是 Visual Basic 程序员讨厌别人说 Visual Basic 是玩具语言,所以
他们要制作自己的 DLL 而不用 C\C++程序员编的 DLL。
Visual Basic 采用 OLE 服务器来实现编制 DLL 的任务,这种方式建立的 DLL 是真正的
DLL,完成它时具有扩展名 DLL。OLE 服务器 DLL 与以前的 Windows 传统 DLL 不同,我们
在 Visual Basic 中建立一个在 DLL 中定义的对象来访问它,然后用此对象的属性、方法工作,
而不是使用 Declare 语句声明 DLL 内定义的函数。同样,其它语言也是通过 OLE 接口来访
问 Visual Basic DLL 的。
1、 生成代码模块 DllMathBas.Bas。由于 OLE 服务器项目必须由一个 Sub Main 过程而
不是一个窗体作为起始点,而 Sub Main 过程又必须放在一个代码模块中,所以我
们要生成这个代码模块。Sub Main 过程用于存放初始化代码。
1, 从 Insert 菜单中选择 Module 项,保存为 DllMathBas.Bas
2, 在 DllMathBas.Bas 中加入下面的代码:
Option Explicit

Sub Main()
‘No initialization required
End Sub
在这个 DLL 的例子里我们不需要初始化的代码。
2、 生成类模块 DllMath.Cls
1, 从 Insert 菜单中选择 Class Module 项,保存为 DllMath.Cls
2, 在 DllMath.Cls 中加入下面的代码:
Option Explicit

Public Num
Public Den

Public Sub Add(Num2, Den2)


Num = Num * Den2 + Den * Num2
Den = Den * Den2
Reduce
End Sub
Public Sub Sbt(Num2, Den2)
Num = Num * Den2 - Den * Num2
Den = Den * Den2
Reduce
End Sub
Public Sub Mul(Num2, Den2)
Num = Num * Num2
Den = Den * Den2
Reduce
End Sub
Public Sub Div(Num2, Den2)
Mul Den2, Num2
End Sub
Private Sub Reduce()
Dim s, t, u

s = Num
t = Den
If t = 0 Then Exit Sub
Do
u = (s \ t) * t
u=s-u
s=t
t=u
Loop While u > 0
Num = Num \ s
Den = Den \ s
End Sub
3, 设置类模块的属性
属性 设置值
Instancing 2 - Createable Multiuse
Name Fraction
Public True

三、项目设置
1, 从 工程(P)菜单中选择 属性 项。
2, 选中 通用 标签。
3, 把 Startup form 设置为 Sub Main。
4, 把 Project Name 设置为 Math。
5, 把 StartMode 设置为 OLE Server。
6, 把 Application Description 设置为 Fraction Math。
7, 单击确定键。
8, 选中 Form1,从 File 菜单中选择 Remove File 项,因为这个 DLL 不需要任何窗体。
4、 把项目编译为 DLL 文件
1, 从 File 菜单中选择 Make OLE DLL File 项。
2, 输入 DLL 的名字 DllMath。
3, 单击确定键。
现在我们就生成了我们的 Visual Basic DLL 文件,下面介绍在 Visual Basic 程序中运用
Visual Basic DLL 的方法。

§3 在 Visual Basic 应用程序中使用 Visual Basic DLL


1、 生成界面

对象 属性 设置值
Form1 Caption "Fraction Math"
Command1 Name cmdAdd
Caption "加"
Command2 Name cmdSubtract
Caption "减"
Command3 Name cmdMultiply
Caption "乘"
Command4 Name cmdDivide
Caption "除"
Text1 Name txtN1
Text2 Name txtD1
Text3 Name txtN2
Text4 Name txtD2
Text5 Name txtN3
Text6 Name txtD3
Label1 Caption “=”
Label2 Caption “?”
Line1 BorderWidth 3
Line2 BorderWidth 3
Line3 BorderWidth 3

2、 编写代码
在窗体下加入下面的代码:
Option Explicit

Public Frac As New Math.Fraction

Private Sub cmdAdd_Click()


Frac.Num = txtN1.Text
Frac.Den = txtD1.Text
Frac.Add txtN2.Text, txtD2.Text
txtN3.Text = Frac.Num
txtD3.Text = Frac.Den
Label1(0).Caption = "+"
End Sub
Private Sub cmdDivide_Click()
Frac.Num = txtN1.Text
Frac.Den = txtD1.Text
Frac.Div txtN2.Text, txtD2.Text
txtN3.Text = Frac.Num
txtD3.Text = Frac.Den
Label1(0).Caption = "/"
End Sub
Private Sub cmdMultiply_Click()
Frac.Num = txtN1.Text
Frac.Den = txtD1.Text
Frac.Mul txtN2.Text, txtD2.Text
txtN3.Text = Frac.Num
txtD3.Text = Frac.Den
Label1(0).Caption = "*"
End Sub
Private Sub cmdSubtract_Click()
Frac.Num = txtN1.Text
Frac.Den = txtD1.Text
Frac.Sbt txtN2.Text, txtD2.Text
txtN3.Text = Frac.Num
txtD3.Text = Frac.Den
Label1(0).Caption = "-"
End Sub
此程序不适用于负数。
3、 引用 Math DLL
1, 从 工程(P) 菜单中选择 引用(N) 项。
2, 单击 Browse 键。
3, 找到刚才生成的 DllMath.dll,并打开它。
4, 你可以在 Available References 列表的最下面找到 Fraction Math ,并且发现在它
旁边已经打了叉表明已经引用了它。
现在这个使用 Visual Basic DLL 的应用程序已经完成了,你已经可以制作自己的 DLL
了。你可以对身边的正在学 C、C++、Delphi 的朋友说:“需要动态链接库吗?要不要我帮你
用 Visual Basic 做一个?”

第十五 章 用 Winsock控件 进行 Internet通信

Internet 的复杂性主要来自于各种各样的通过 Internet 交换信息的应用程序,包括电


子邮件、新闻和 WWW。但 Internet 本身却具是有良好定义的和可靠的通信协议的数字网络。
在这个基础上 Windows 95 和 Windows NT 为 Internet 提供了诸如 Winsock 等标准接口。
而 Visual Basic 则通过 Winsock ActiveX 控件为 Winsock 提供了标准接口。Winsock 的目的
非常简单:为两个或多个 Internet 节点建立连接并使之交换数据。下面我们以一个简单的
应用程序来看看这个过程。

§1 Winsock 服务器
本工程用 TCP 协议为客户端和服务器端建立连接。对实际的 Internet 应用程序而言。可
能需要两个独立的应用程序。但现在为简单起见,我们在一个应用程序中,为客户端和服务
器端建立两个不同的窗体。
我们需要下表所列的控件。
名称 类型 属性 值
lblIPAddress Label Caption “”
lblStatus Label Caption “”
sktTCPChatServe Winsock Protocol 0-
r sckTCPProtocol
txtDataReceived TextBox Text “”
txtDataToSend TextBox Text “”

1,倾听 Winsock 连接
Internet 上每个服务器应用程序都通过 IP 地址和端口号两个数字来标识。服务器正是
通过这两个数字来倾听连接请求。每个 Internet 节点,即有特定 IP 地址的计算机,都可运
行多个服务器,只要这些服务器倾听的端口号不同。
在程序中,我们将 Winsock 控件的 LocalPort 设为 1600。由于 IP 地址由服务器运行的
计算机确定,因而无需设定。调用 Listen 方法,服务器便开始监听 Internet 的连接请求,
这样就激活了服务器程序。
2,建立 Winsock 连接
当 客 户 端 向 合 适 的 IP 地 址 和 端 口 号 发 送 连 接 请 求 时 , Winsock 控 件 便 会 产 生
ConnectionRequest 事件。在 ConnectionRequest 事件中调用 Accept 方法,并将所接收的
RequestID 作为事件过程的参数,就可以在服务器和客户端之间建立连接。
3,交换数据
使用 Winsock 控件的 SendData 方法,就可以向客户端发送数据。Winsock 控件收到客户
端的数据时,先调用 DataArrival 事件过程,然后,再通过 GetData 方法从通信缓冲区中
获得数据。
下面是服务器窗体的代码:

Option Explicit
Private Sub Form_Click()
Print sktTCPChatServer.LocalIP
End Sub

Private Sub Form_Load()


frmClient.Show
sktTCPChatServer.LocalPort = 1600 ' Set the local port.
sktTCPChatServer.Listen ' Use the Listen method.
lblIPAddress.Caption = sktTCPChatServer.LocalIP
lblStatus.Caption = "Host Name: " & sktTCPChatServer.LocalHostName
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)


'Dim ArrayIndex As Integer

Unload frmClient
End Sub

Private Sub sktTCPChatServer_Close()


lblStatus.Caption = "Disconnecting from " &
sktTCPChatServer.RemoteHostIP

' Return to listening state.


sktTCPChatServer.Close
sktTCPChatServer.LocalPort = 1600
sktTCPChatServer.Listen
End Sub

Private Sub sktTCPChatServer_ConnectionRequest(ByVal requestID As Long)


Dim Dummy As String

If sktTCPChatServer.State <> sckClosed Then


sktTCPChatServer.Close
End If
sktTCPChatServer.Accept requestID
lblStatus.Caption = "Connecting " & sktTCPChatServer.RemoteHostIP
End Sub

Private Sub sktTCPChatServer_DataArrival(ByVal bytesTotal As Long)


Dim DataReceived As String

sktTCPChatServer.GetData DataReceived, vbString


If CStr(DataReceived) = "QUIT" Then
sktTCPChatServer_Close
Else
txtDataReceived.Text = DataReceived
End If
End Sub

Private Sub txtDataToSend_Change()


sktTCPChatServer.SendData txtDataToSend.Text
End Sub

§2 Winsock 客户端
对客户端而言,先创建类似于服务器的窗体,下表列出了客户端所用的六个控件。
名称 类型 属性 值
cmdConnect CommandButton Caption “连接”
cmdCloseConnect CommandButton Caption “关闭连接”
lblStatus Label Caption “”
sktTCPChatClien Winsock Protocol 0-
t sckTCPProtocol
txtDataReceived TextBox MultiLine True
txtDataToSend TextBox MultiLine True

1,连接到服务器上
客户端和服务器的主要区别在于建立连接的方式不同。服务器通过倾听建立连接,而客
户端则是用 Winsock 控件的 Connect 方法以及 RemoteHost 和 RemotePort 来发送连接请求。
本程 序中 ,因 为服 务器 和客 户端 运行 在同 一台 机器 上, 所以 将 RemoteHost 的值 设为
Winsock 控件所检测到的 LocalIP。在客户端,通过单击一个按钮来发送连接请求。
2,关闭连接
关闭连接的按钮执行的时候,并不需要调用 Winsock 控件的 Close 方法。而是发送字符
串“QUIT”,以便让服务器调用它的 Close 方法来实际断开连接。建立连接和断开连接的顺
序会影响 Winsock 应用程序的可用性和可靠性。
3,交换数据
客户端使用与服务器相同方法来交换数据。调用 SendData 方法向服务器发送数据,在
DataArrival 事件过程中调用 Winsock 控件的 GetData 方法来获取服务器传过来的数据。
客户端的代码是:
Option Explicit

Private Sub cmdCloseConnection_Click()


lblStatus.Caption = "Closing Connection"
' Don't terminate the connection like this:
' sktTCPChatClient.Close
sktTCPChatClient.SendData "QUIT"
End Sub

Private Sub cmdConnect_Click()


If sktTCPChatClient.State <> sckClosed Then
sktTCPChatClient.Close
End If
With sktTCPChatClient
.RemoteHost = sktTCPChatClient.LocalIP
.RemotePort = 1600
End With
sktTCPChatClient.Connect
End Sub

Private Sub Form_Load()


lblStatus.Caption = "Local IP Address: " & sktTCPChatClient.LocalIP
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)


sktTCPChatClient.Close
End Sub

Private Sub sktTCPChatClient_Close()


sktTCPChatClient.Close
Do
lblStatus.Caption = "Status: " & _
sktTCPChatClient.State
DoEvents
Loop Until sktTCPChatClient.State = sckClosed
End Sub

Private Sub sktTCPChatClient_Connect()


If sktTCPChatClient.State = sckConnected Then
lblStatus.Caption = "Connection Successful at Remote IP " &
sktTCPChatClient.RemoteHostIP
End If
End Sub

Private Sub sktTCPChatClient_DataArrival(ByVal bytesTotal As Long)


Dim vtData As Variant

sktTCPChatClient.GetData vtData, vbString


txtReceived.Text = vtData
End Sub

Private Sub txtDataToSend_Change()


sktTCPChatClient.SendData txtDataToSend.Text
End Sub
949494949494949494949494949494

.第十六 章 Web 浏览 控件
本章将介绍将 Web 技术应用在 Visual Basic 应用程序中。Web 技术是超文本模型,通过
单击超链接与应用程序交互是对 VB 编程人员的用户接口设计工具的有力补充。
可以用两个对象将 Web 技术与超链接文档加进 Visual Basic 应用程序中: WebBrowser
控件和 InternetExplorer 对象。WebBrowser 控件是个 ActiveX 控件,可以将 Internet 浏览功能
加到应用程序中,在 Visual Basic 窗体上显示 Web 文档。InternetExplorer 对象是 OLE 式的自
动化对象,可以在应用程序中控制 Microsoft Internet Explorer。

§1 WebBrowser 控件和 InternetExplorer 对象简介

一、WebBrowser 控件、
简单的说,WebBrowser 控件就是 Internet Explorer 的窗口。任何可以在 Internet Explorer
中显示的文档,也可以在 WebBrowser 控件中显示。由于 WebBrowser 控件是个 ActiveX 控件,
可以放在任何 Visual Basic 窗体中。但使用 WebBrowser 控件之前,必须把它加入工具栏,步
骤如下:
1.右键单击工具栏,从菜单中选择 Components 命令,打开 Components 对话框。
2.选择 Microsoft Internet Controls, 然后单击单击 Ok 钮,于是在工具栏中加入了一个
新的图标。
WebBrowser 控件放在窗体上时,它是一个无边框的矩形,可以用任何方式缩放。要在
WebBrowser 控件中显示 Web 文档,使用 Navigate 方法。还可以用 GoBack 和 GoForward 方
法在已经显示的 URL 表中前后移动,WebBrowser 控件中会自动维护访问过的 URL 表。
它的 LocationName 属性返回当前页面标题,LocationURL 属性返回当前页面的 URL。

二、InternetExplorer 对象
InternetExplorer 对象可在应用程序中启动一个 Internet Explorer 实例,并自动地用 OLE
对它进行操作。InternetExplorer 对象在具有 WebBrowser 控件所具有的属性和方法的基础上,
还有所增加。
要在应用程序中引用 InternetExplorer 对象,首先要加进 InternetExplorer 对象的引用,
步骤如下:
1.开始一个新项目,类型为 Standard EXE.
2.选择 ProjectReferences 命令,打开 References 对话框。
3.选定 icrosoft Internet Controls,然后单击单击 Ok 钮。
此时虽然看不见新图标,但若打开 Object Browser,则可看见 InternetExplorer 对象已经
加入到项目表中。
要生成 InternetExplorer 对象的实例,可用如下语句:
Dim IE As New InternetExplorer
以后我们就可以使用它了,象下面一个例子来说,我们通过下图所示的一个窗体控制
Internet Explorer , 在 下 拉 列 表 中 选 择 一 个 地 址 后 单 击 Go there! 按 钮 , 即 可 使 Internet

Explorer 浏览指定的站点,如下图:

当然这个 IE 窗口已经通过下面代码隐藏了工具条和菜单条。
IE.ToolBar = False
IE.MenuBar = False

§2 WebBrowser 控件和 InternetExplorer 对象的方法


本节介绍二者的几个常用方法:
1. GoBack 和 GoForward 这两个方法在历史表中向前或向后移动一个项目,由
WebBrowser 控件和 InternetExplorer 对象的方法自动维护,但若要移到最近一个
URL 之后,或移到第一个 URL 之前,均会产生错误,必须加入错误处理代码。
2. GoHome 和 GoSearch GoHome 方法转移到当前设置的启始页, GoSearch 方法也
是转移到 Internet Option 对话框指定的页面。
3. Navigate 这个方法转移到 URL 或打开 HTML 文件,它的语法如下:
Navigate(URL As String, [Flags], [TargetFrameName], [PostData], [Headers])
除了第一个变元以外的其他变元都是可选的。 URL 变元指定显示资源的 URL ;
Flags 变元是个常数,它的值及其含义如下:
常量 数值 说明
NavOpenInNewWindow 1 在新窗口中打开资源或文件
NavNoHistory 2 不把资源或文件名加进历史表
NavNoReadFromChche 4 本次转移不从磁盘缓冲区读数据
NavNoWriteToCache 8 本次转移结果不写入磁盘缓冲区

TargetFrameName 变元是显示文档的帧名。PostData 变元是 HTTP POST 传送期间发


送到服务器的字符串。 POST 用与发送从 HTML 窗体中获取数据,若这个参数未指
定,则 Navigate 方法发出一个 HTTP GET 传输,这个参数在 URL 不是 HTTP URL
时省略。
4. Refresh 这个方法重新装入当前显示的页面。
5. Refresh2 这个方法类似与 ReFresh,但可以指定刷新级别,其语法如下:
WebBrowser1.Refresh level
Level 变元的取值如下:
常量 数值 说明
REFRESH_NORMAL 0 完成快速刷新
REFRESH_IFEXPIRED 1 页面到期时完成快速刷新
REFRESH_COMPLETELY 3 完成完全刷新

6. Stop 这个方法取消等待转移或下载操作,停止播放背景声音或动画等多媒体元素。

§3 WebBrowser 控件和 InternetExplorer 对象的事件


WebBrowser 控件和 InternetExplorer 对象的事件在用户用它们浏览移动到另一 URL 时触
发,它们还监视每次下载的进程。
1. BeforeNavigate2 这个事件在将要、转移到另一 URL 时发生,它的语法是
Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As
Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel
As Boolean)
URL 变元是指示目标 URL;Flags 是保留变元;TargetFrameName 变元是显示指定
文档的帧名。应用程序可以设置 Cancel 变元取消转移过程。如果将它设置为 True,
则不启动浏览过程。
2. NavigateComplete 这个事件在成功地转移到新位置后发生。有些资源可能还在下载,
但至少已经收到部分文档。该过程可用 Stop 方法中断。它的语法如下:
Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
3. DownloadBegin 这个事件发生在下载操作子初,在 BeforeNavigate2 事件之后触发,
应用程序显示“忙信息”或改变指针形状。它的语法如下:
Sub WebBrowser1_DownloadBegin()
4.DownloadComplete 这个事件发生在下载操作完成,终止或失败之时。它的语法如
下:
Sub WebBrowser1_DownloadComplete()
5.ProgressChange 这个事件用于跟踪下载操作的过程,它被定期触发,指示应用程
序进程。它的语法如下:
Sub WebBrowser1_ProgressChange(ByVal Progress As Long, ByVal ProgressMax
As Long)
其 中 两 个 变 元 都 是 长 整 型 , Progress 变 元 是 目 前 已 下 载 的 数 据 总 量 , 而
ProgressMax 变元是将要下载的数据总量。
为节省篇幅,这些事件的使用例子见授课时的例子。
附录 1

VB6 可开发的应用程序如下表:
程序类型名称 说明
标准 EXE 程序 (Standard EXE)是典型的应用程序,VB
以前的版本也可开发。
ActiveX EXE 和 ActiveX DLL 程序 只在专业版和企业版中才有。ActiveX 控件是
支持 OLE 的自动化服务器程序。这两种程序
在功能上是一致的,只是包装不同。ActiveX
EXE 程序包装成可执行文件,AcitveX DLL
程序包装成动态链接库。
ActiveX 控件 只在专业版和企业版中才有。主要用于开发
人员自定义的 ActiveX 控件。
VB 应用程序向导 使用它可以在开发环境中直接建立新的应用
程序框架。在开发自己的程序时,可以使用
这个工具,并参考它所提供的应用程序原始
类型.
数据工程 为编程人员提供开发数据报表应用程序的框
架。自动打开数据环境设计器和数据报告设
计器。
IIS 应用程序 专业版和企业版新添。可使用 VB 代码书写服
务器方的 Internet 应用程序,用来响应来自
浏览器的用户需求。
外接程序 可创建自己的 VB 外接程序,并在开发环境
中自动打开连接设计器。
AcitveX 文档 EXE 和 ActiveX 文档 DLL 程序 ActiveX 文档实际上是可以在支持超链接环
境中运行的 VB 应用程序。简单说即 Web 浏
览器。如:IE
DHTML 应用程序 专业版和企业版新添。它允许编程人员编写
响应 HTML 页面上动作的 VB 代码,并且还
需要将处理过程传递到服务器上。
VB 企业版控件 只在企业版中才有,用于开发企业版应用控
件。

Vous aimerez peut-être aussi