1、菜单、对话框及多重窗体,VB 程序设计,制作:赖锦德,提出问题,大家在以前就已接触和学习过不少应用程序,比如Office中的文字处理程序Word、表格处理程序Excel等,已经使用过这些程序中强大的菜单功能,它们是如何进行设计的呢?我们自己能否设计类似的菜单呢?,本章主要内容:,1:菜单 2:对话框 3:多重窗体 4:VB工程结构,两种菜单类型:下拉式菜单、弹出式菜单,1 菜单组成,主菜单(标题)包含若干个菜单项,它放置在菜单的最顶层, 它可以下拉出下一级菜单(子菜单),菜单命令对应一个程序模块,执行命令后子菜单自动消失,子菜单包含子菜单标题和菜单命令,分隔条可对子菜单进行分组,菜单命令对应一
2、个程序模块,执行命令后子菜单自动消失,分隔条可对子菜单进行分组,1:菜单控件菜单项(主菜单项或子菜单项)也称为菜单控件菜单项具有其属性、事件、方法通过“菜单编辑器”完成设计,2:菜单编辑器使设计菜单栏的窗体成为当前窗体执行“工具”菜单的“菜单编辑器”命令(或单击标准工具栏的“菜单编辑器”按钮,或从窗体快捷菜单中选择“菜单编辑器”命令),打开“菜单编辑器”窗口,3:菜单编辑器结构属性区 输入或修改菜单项,设置菜单项属性编辑区 对输入的菜单项进行编辑操作菜单列表区 显示菜单项的分级列表,2 菜单编辑器,我们利用菜单编辑器设计每个菜单项,其实每个菜单项都是一个对象,它们都有自己的属性、事件、方法。,
3、名称:Name属性设置菜单控件的名字以便在代码中访问它 设计菜单时必须输入此项!,标题:Caption属性设置菜单项中显示的文字若该属性为连字符(-),则显示为隔离条可定义访问键(在一字母前加&符号),快捷键:顶级菜单不能使用快捷键!,索引:若将菜单控件定义为数组,则Index属性确定数组控件的位置,Checked,Enabled,Visible,当具有菜单的窗体包含另一个具有菜单的对象时,该属性协调二者的位置 0-None 1-Left 2-Middle 3-Right,决定菜单项是否显示缺省值True,设置菜单项的左端是否带复选标记缺省值False,决定菜单项是否响应事件缺省值True,完
4、成上述设计,单击确定按钮,即可看到菜单结构,要实现菜单功能,需要编写菜单项的事件代码,【例1 】设计一个具有算术运算(+、-、/ )及清除功能的菜单。从键盘上输入两个数,利用菜单命令求出它们和、差、积或商,并显示出来。,菜 单 设 计,编写程序代码,菜单的事件过程以菜单项区分,可以把每个菜单项看成是一个控件。菜单设计完成后,只要单击某个菜单项,即可定义该菜单项的事件过程。,【例2 】设计菜单界面如下图所示,下拉菜单中的子菜单项用于对文本框设置字体、字号、文字颜色和效果。其中,效果菜单下的各菜单项具有复选功能,设运行初始时各项前面没有符号,与文本框初始状态一致,Text1,菜单编辑器设置如下:,
5、菜 单 列 表 区,续上表:,菜 单 列 表 区,菜 单 列 表 区,菜 单 列 表 区,菜单项事件代码设计如下:,“字体”菜单下的菜单项设计成一个控件数组AA1,共享以下事件过程:Private Sub AA1_Click(Index As Integer)Text1.Font = AA1(Index).CaptionEnd Sub,“字号”菜单下的菜单项设计成一个控件数组BB1,共享以下事件过程:Private Sub BB1_Click(Index As Integer)Text1.FontSize = Val(BB1(Index).Caption)End Sub,“颜色”菜单下的各菜单
6、项为独立的菜单控件,因此应分 别在其单击事件过程中编写代码,各事件过程如下:Private Sub CC1_Click()Text1.ForeColor = vbRedEnd SubPrivate Sub CC2_Click()Text1.ForeColor = vbGreenEnd SubPrivate Sub CC3_Click()Text1.ForeColor = vbBlueEnd Sub,“效果”菜单下的各菜单项具有复选功能,每次单击时切换成另一种状态。因此要判断当前菜单项的Checked属性,各事件过程如下:,Private Sub DD1_Click() 删除线If DD1.Ch
7、ecked = True ThenText1.FontStrikethru = FalseDD1.Checked = FalseElseText1.FontStrikethru = TrueDD1.Checked = TrueEnd If End Sub,Private Sub DD2_Click() 下划线If DD2.Checked = True ThenText1.FontUnderline = False DD2.Checked = False ElseText1.FontUnderline = TrueDD2.Checked = TrueEnd If End Sub,Private
8、Sub DD3_Click() 粗体If DD3.Checked = True ThenText1.FontBold = FalseDD3.Checked = FalseElseText1.FontBold = TrueDD3.Checked = TrueEnd If End SubPrivate Sub DD4_Click() 斜体If DD4.Checked = True ThenText1.FontItalic = FalseDD4.Checked = FalseElseText1.FontItalic = TrueDD4.Checked = TrueEnd If End Sub,2:方
9、法PopupMenu的格式: .PopupMenu ,flags,x,y,boldcommandflags 指定菜单的位置和行为,祥见P171表10-2、10-3x 菜单的x坐标,缺省则为鼠标坐标y 菜单的y坐标,缺省则为鼠标坐标boldcommand 指定要显示为黑体的菜单项控件名称,二、弹出式菜单 独立于菜单栏直接显示在窗体上,也称作上下文菜单、快捷菜单、右键菜单,1:弹出式菜单的设计在菜单编辑器中按下拉式菜单的设计方法,并将其顶级菜单设置为不可见在对象的MouseDown事件过程中编写代码,用以下的PopupMenu方法显示弹出式菜单,MouseDown事件:Sub Form_Mouse
10、Down(Button As Integer, Shift As Integer,X As Single, Y As Single)(发生在窗体上的事件过程),(1) Button参数,B0=1:按下左键; Button为1(001B) B1=1:按下右键; Button为2(010B) B2=1:按下中键。 Button为4(100B),(2) Shift参数,B2=1按下Alt键; B1=1按下Ctrl键;B0=1按下Shift键,返回一个整数,在 Button 参数指定的按钮被按下或者被释放的情况下,该整数相应于 SHIFT,CTRL,和 ALT 键的状态。某键被按下使得一个二进制位被设
11、置。shift 参数是具有相应于 SHIFT 键(位 0),CTRL 键(位 1),以及 ALT 键(位 2)最少二进制位的一个位字段。这些位的值分别等于 1,2,和 4。,B2=1按下Alt键; B1=1按下Ctrl键;B0=1按下Shift键,(2) Shift参数,【例3 】在例2的基础上设计窗体和文本框的弹出式菜单,如下图所示:,菜单编辑器设置如下:,文本框的MouseDown事件代码设计如下: Private Sub Text1_MouseDown (Button As Integer, Shift As Integer, X As Single, Y As Single)If Bu
12、tton = 2 ThenPopupMenu EE, 0 Or 0End If End Sub,窗体的MouseDown事件代码设计如下: Private Sub Form_MouseDown (Button As Integer, ShiftAs Integer, X As Single, Y As Single)If Button = 2 ThenPopupMenu FF,8 Or 0, , ,FF3 End If End Sub,菜单项事件代码设计如下:,保存窗体的初始颜色:Dim Fcolor As LongPrivate Sub Form_Load()Fcolor = Form1.B
13、ackColor &H8000000F默认色End Sub,文本框快捷菜单:Private Sub EE1_Click()Text1.FontSize = Text1.FontSize + 1 增加1磅 End SubPrivate Sub EE2_Click()Text1.FontSize = Text1.FontSize 1 减少1磅 End SubPrivate Sub EE3_Click() 锁定If EE3.Caption = “锁定“ ThenEE3.Caption = “取消锁定“ : Text1.Locked = True ElseEE3.Caption = “锁定“ : Te
14、xt1.Locked = False End IfEnd Sub,窗体快捷菜单: Private Sub FF1_Click()Form1.BackColor = vbRed 红色背景 End SubPrivate Sub FF2_Click()Form1.BackColor = vbGreen 绿色背景End SubPrivate Sub FF3_Click()Form1.BackColor = Fcolor 默认背景 End Sub,常见错误及难点分析,1.窗体菜单名、顶层菜单与菜单项的区别通常出现在菜单栏上的菜单对象称为菜单名,菜单名以下拉列表形式包含的内容为菜单项。菜单项可以包括菜单命
15、令、分隔条和子菜单标题。当菜单名没有菜单项时,为“顶层菜单”,可直接对应一个应用程序。 菜单名、顶层菜单不能定义快捷菜单, 而菜单项可以有快捷键。 当菜单包含有热键字母(菜单标题中“&”后的字母)时窗体,按Alt+热键字母可选择窗体顶部菜单栏中的菜单项,当子菜单打开时,按热键字母选择子菜单中的。如果子菜单没有打开时,按热键字母无法选择其中的菜单项。 尽管所有的菜单项都能响应Click事件,但是菜单栏中的菜单名通常不需要编写事件过程。,区别,常见错误及难点分析,2 使用Load语旬加载窗体,窗体不显示Load语句将窗体装入内存并设置窗体的Visible属性为False(无论在设计时如何设置Vis
16、ible属性),此时可以引用窗体中的控件及各种属性。为了使窗体可见,在用Load语句后,再将窗体的Visible属性设置为True,或使用Show方法加载窗体。,3在因体加载过程中使用 SetFocus方法出现“无效的过程调用或参数”错误焦点只能移到可视的窗体或控件上。在窗体的Load事件完成前窗体或窗体上的控件是不可视的,所以不能在 Form_ Load事件中把焦点移到正在加载的窗体上,也不能在Load事件内使用SetFocus方法将焦点移至窗体上的控件。此外,也不能把焦点移到Enabled或Vsible属性被设置为False的窗体或控件。如果已在设计时将Enabled或Visible属性设
17、置为False,必须在使用SetFocus方法前将Enabled或Visible属性设置为True。,在首次用Load语句将窗体(假定该窗体在内存中还没有创建)调人内存之时依次发生Initialize和Load事件。Initialize是在窗体创建时发生的事件。在窗体的整个生命周期中, Initialize 事件只触发一次。用户可以将一个窗体装入内存或从内存中删除很多次,但窗体的建立只有一次。也就是说,在用Load语句将窗体装入内存时会触发Load事件,但并不一定触发Initialize事件 窗体的Activate事件仅当窗体成为活动窗口时才发生。,在窗体从内存中卸载时依次发生 QueryUn
18、load和 Unload事件。QueryUnload事件可提供造成窗体卸载的原因(单击“关闭”按钮/程序中执行Unload语句/在应用程序中关闭/在Windows中的关闭)。如果在QueryUnLoad事件中把QueryUnload的参数Cancel设置为True,就会忽略Unload语句,从而不卸载窗体。所以QueryUnload提供了取消关闭窗体的机会,同时也允许在需要时从代码中关闭窗体。,使用End语句来结束程序,窗体不会接收到 QueryUnload事件,常见错误及难点分析,4与窗体有关的事件,是一种特殊类型的窗体对象 主要用于用户和应用程序的交互 建立对话框的方法三种 使用预定义对话
19、框,如函数 InputBox、MsgBox 自定义对话框 使用CommonDialog控件创建通用对话框,3 对话框,添加窗体:使用“工程/添加窗体”命令 将窗体定义成对话框风格,不能移动、最大或最小化 在对话框上添加按钮,如“确定”与“取消”按钮 在对话框上添加其它控件 在适当的位置编写显示对话框的代码 显示模式对话框(打开时焦点不可切换): 窗体名.Show vbModal (或窗体名.Show 1) 显示无模式对话框: 窗体名.Show vbModeless (或窗体名.Show 0) 编写从对话框退出的代码 例如 Unload Form2 或 Form2.Hide,3.1 自定义对话框
20、,【例4】设计对话框Form2如下图所示。当输入某文件所在的路径及名称后,单击“确定”按钮按所选择的运行方式运行该文件,单击“取消”按钮取消本次操作,返回窗体Form1中。如果输入文件名错误,将给出警告并返回该对话框,在窗体Form1 的“运行”菜单项(设菜单控件名为SRun)的Click事件过程中显示对话框,代码如下:Private Sub SRun_Click()Form2.Show 1 显示模式对话框End Sub,在主窗体Form1的菜单有一“运行”菜单项,运行时单击“运行”打开模式对话框Form2,对话框Form2代码设计如下:,Private Sub Command1_Click(
21、)On Error GoTo ErrorHandler 设置错误陷阱。如果出现错误,转到ErrorHandler处执行 FName = Trim(Text1.Text)If Option1.Value = True Then a = Shell(FName, 1)正常方式并拥有焦点If Option2.Value = True Then a = Shell(FName, 3)最大化方式并拥有焦点If Option3.Value = True Then a = Shell(FName, 2)最小化方式并拥有焦点Exit Sub ErrorHandler:MsgBox “不能运行该程序“, , “
22、注意“Resume Next 从产生错误的语句之后开始运行 End Sub,Private Sub Command2_Click()Unload Me End Sub,通用对话框 通用对话框可置于窗体的任意位置,运行时不显示 设置通用对话框控件的“属性页”,使用通用对话框控件(CommonDialog) 创建! 使用“工程/部件/控件”命令添加对话框控件!,在代码中使用以下方法打开对话框 ShowOpen:显示“打开文件”对话框 ShowSave:显示“文件存储”对话框 ShowColor:显示“颜色”对话框 ShowFont:显示“字体”对话框 ShowPrinter:显示“打印”对话框 S
23、howHelp:显示“帮助”对话框 示例:commondialog1.showopen,【例5】使用打开文件对话框,在运行时打开一幅图像,“打开/另存为”对话框的属性页设置如下:,“装入图像”按钮代码设计如下:,Private Sub Command1_Click()On Error GoTo ErrHandler出错时转到ErrorHandler处执行CommonDialog1.ShowOpen 将通用对话框显示为打开文件对话框 Image1.Picture=LoadPicture(CommonDialog1.FileName)Exit SubErrHandler: Exit Sub End
24、 Sub,【例6】设计如图所示的界面,运行时单击“背景色”按钮打开颜色对话框,在对话框中选择的颜色用于设置文本框的背景颜色,单击“字体”按钮打开字体对话框,在对话框中选择字体、效果及颜色,用于设置文本框文字的字体、效果及颜色,“颜色”对话框的属性页设置如下:,“颜色”、“字体”对话框的属性页设置如下:,“背景色”按钮Command1的Click事件过程如下: Private Sub Command1_Click()CommonDialog1.ShowColor将通用对话框显示为颜色对话框 Text1.BackColor = CommonDialog1.Color End Sub,“字体”按钮C
25、ommand2的Click事件过程如下: Private Sub Command2_Click()CommonDialog1.ShowFont将通用对话框显示为字体对话框 Text1.Font = CommonDialog1.FontNameText1.FontBold = CommonDialog1.FontBoldText1.FontItalic = CommonDialog1.FontItalicText1.FontStrikethru = CommonDialog1.FontStrikethruText1.FontUnderline = CommonDialog1.FontUnderl
26、ineText1.ForeColor = CommonDialog1.ColorText1.FontSize = CommonDialog1.FontSize End Sub,1在程序中对通用对话框的属性设置不起作用在程序中对通用对话框的属件设置必须注意语句的先后顺序,属性设置语句必须放在打开对话框语句前,否则在程序中对通用对话框的属性设置在本次使用中不起作用。,例:下面的程序代码由于先打开对话框,再进行属性设置,在第一次执行本段代码时,无法过滤文件,Showopen语句后面的属性设置语句对下一次执行Showopen有效。CommonDialoglShowOpenCommonDialoglFi
27、leName *Bmp CommonDialoglInitDirC:WindowsCommonDialoglFilter Pictures(*Bmp) *Bmp All Files(*.*) *.* CommonDialogl FilterIndex1,常见错误及难点分析,常见错误及难点分析,2设置通用对话框的CancelError属性为True发生错误当通用对话框的CancelError属性设置为True时,无论何时选择“取消”按钮,均产生32755(cdlCancel)号错误。Visual Basic通过系统对象 Err来记录程序运行期间所发生的错误。Err对象的 Number属性记录错误
28、号,Description属性保存有关错误的说明。例如,当在CancelError 属性为True的通用对话框中选择“取消”按钮时,产生一个错误,ErrNumber被设置为32755,Description属性被设置为“选择取消 ”。如果不对错误进行处理,Visual Basic将显示出错误消息并停止程序运行。为防止由于错误造成停止程序运行的问题,可以使用 On Error语句捕获错误,然后根据捕获的错误进行处理。,On Ermr Resume Next 忽略发生错误的命令行,执行下一句命令On Ermr GoTo语句标号 当发生错误时转向执行标号所指定的命令行对于捕获到的错误号,可用分支语句
29、处理。,以下程序说明当在颜色对话框内选取“取消”按钮时,CommonDialogl.ShowColor语句产生32755号错误。On Error语句在捕获到错误后,转向执行标号 ErrorHandler所指定的命令行,在标签Label1上显示“放弃操作”,并忽略产生错误的那一行命令与标号之间的所有语句。Private Sub Commandl Click()On Error GoTo ErrorHaandler 错误捕获语句CommonDialogl.CancelError=True 使选取“取消”按钮时能对出错误做响应CommonDialogl.ShowColorTextl.ForeColo
30、r=CommonDialoglColor 设置颜色Exit Sub 无错误时正常退出本过程,常用的 On Ermr语句形式有:,3在使用Commonlnalog控件控制字体选择时出现错误这是由于没有设置CommonDialog控件的Flags属性,或属性值不正确。通常设置该值为H103,表示屏幕字体、打印机字体两者皆有之,并在字体对话框中出现删除线、下划线、 颜色等元素。,以下为错误处理的语句ErrorHandler:语句标号,错误处理语句开始If Err.Number=32755 Then Labell.Caption=“放弃操作”End Sub,VB中允许应用程序有多个窗体,每个窗体有自己
31、的代码和不同的操作,从而实现复杂的功能。,一:多重窗体有关语句1:Load :将窗体载入内存,但并不显示2:UnLoad :将窗体从内存中消除3: .Show 模式:显示窗体。模式=0(非模态)或1(模态),默认模式为0。4: .Hide:隐藏窗体(并不从内存中消除),4 多重窗体,二、多重窗体设计,多重窗体设计与单重窗体设计一致,大致可分为三步: 建立界面 编写代码 运行程序指定启动窗体:在“工程/工程属性/通用”中可以根据需要指定应用程序的启动窗体。,【例7】多重窗体应用程序 窗体1的代码 Private Sub Command1_Click() Load Form2Form1.HideF
32、orm2.ShowForm2.Text1.Text = UCase(Form1.Text1) End Sub Private Sub Command2_Click() Load Form3Form1.HideForm3.ShowForm3.Text1.Text = LCase(Form1.Text1) End Sub Private Sub Command3_Click()End End Sub,窗体2的代码: Private Sub Command1_Click()Form1.ShowForm2.HideEnd Sub Private Sub Form_Activate()Text1.Tex
33、t=Ucase(Form1.Text1.Text) End Sub,窗体3的代码: Private Sub Command1_Click()Form1.ShowForm3.Hide End SubPrivate Sub Form_Activate()Text1.Text=Lcase(Form1.Text1.Text) End Sub,三、VB工程结构,工程文件(.vbp)列出了在创建该工程时所建立的所有文件的相关信息。 窗体文件(.frm, .frx)包括有窗体、窗体上的对象及窗体上的事件响应代码。 标准模块文件(.bas)包含有可被任何窗体或对象调用的过程程序代码,标准模块VB中主要有三种模
34、块: 标准模块:由全局变量声明、模块层声明及通用过程等组成,所以也叫全局模块或总模块。 窗体模块:每个窗体都有一个对应的窗体模块,通常包括声明、通用过程及事件过程三部分。 Sub Main过程:通常设置为启动对象,主要用于应用程序的初始化工作;该过程必须建立在标准模块中,一个程序中可以有多个标准模块,但最多只能有一个Sub Main模块。,5 综合应用,【例8】设计一个计算学生平均分和总分的多窗体应用程序。界面如下:,Form1主窗体FrmMaint Private Sub cmdEnd_Click()End End SubPrivate Sub cmdInput_Click()frmInpu
35、t.ShowfrmMain.Hide End SubPrivate Sub cmdOutput_Click()frmOutput.ShowfrmMain.Hide End Sub,Form2:数据输入窗体FrmInput Private Sub cmdReturn_Click()sMath = Val(Text1)sChinese = Val(Text2)sChemistry = Val(Text3)sEnglish = Val(Text4)sPhysics = Val(Text5)frmInput.HidefrmMain.Show End Sub,Form3:数据输出窗体FrmOutputP
36、rivate Sub Command1_Click()frmOutput.HidefrmMain.Show End SubPrivate Sub Form_Activate()stotal = sMath + sChinese + sChemistry + sEnglish + sPhysicstxtAverage = stotal / 5txtTotal = stotal End SubPrivate Sub Form_Load()stotal = sMath + sChinese + sChemistry + sEnglish + sPhysicstxtAverage = stotal / 5txtTotal = stotal End Sub,总结,