第10章多重窗体程序设计与环境应用10.1多重窗体应用程序10.1.1窗体的类型在VisualBasic中,窗体的类型有两种:单文档界面的窗体(SingleDocumentInterface,SDI)和多文档界面的窗体(MultipleDocumentInterface,MDI)。单文档界面的窗体指的是所有的窗体都是平等的,相互之间没有容纳与被容纳的关系,前面所用的窗体都是单文档界面的窗体;多文档界面的窗体指的是窗体与窗体之间具有容纳与被容纳的关系,用于容纳其他窗体的窗体称为MDI窗体或者父窗体,被MDI窗体所容纳的窗体称为MDI窗体的子窗体。多重窗体应用程序指的是一个VisualBasic的应用程序由多个单文档界面的窗体组成,每个单文档界面的窗体有自己的用户界面和代码,完成不同的功能。10.1.2与多重窗体程序设计有关的语句和方法1.加载窗体与卸载窗体加载窗体指的是将窗体载入内存,而卸载窗体指的是将窗体从内存中清除。在VisualBasic中,加载窗体与卸载窗体的语句分别是:Load语句和Unload语句。Load语句的语法格式如下:Load窗体名注意:Load语句仅仅是将窗体载入内存,窗体并不能显示出来。Unload语句的语法格式如下:Unload窗体名2.显示窗体与隐藏窗体当窗体被加载后,并不会自动显示,要显示窗体,可以使用窗体的Show方法,Show方法的语法格式如下:[窗体名.]Show[窗体模式]如果省略窗体名,则显示当前窗体;窗体模式用于指定窗体的显示状态,有两个值:vbModeless(或0)表示非模式窗体、vbModal(或1)表示模式窗体,如果窗体模式缺省,相当于0。模式窗体必须被关闭、隐藏或者卸载以后,才能切换到其他的窗体,而非模式窗体即使不关闭,也可以在不同的窗体之间切换。Show方法可以显示已经载入内存的窗体,如果窗体没有被载入内存,Show方法自动将窗体载入内存然后再显示出来。如果要隐藏窗体但不卸载窗体,可以使用Hide方法,Hide方法的语法格式如下:[窗体名.]Hide注意:使用Hide方法隐藏窗体后,窗体仍然在内存中,随时可以显示。显示窗体与隐藏窗体可以用Show方法和Hide方法,也可以使用Visible属性,当窗体的Visible属性值为True时,显示窗体;当窗体的Visible属性值为False时,隐藏窗体。10.1.3在工程中添加窗体或标准模块在VisualBasic中,添加窗体的方法有三种:通过“工程”菜单的“添加窗体”命令,或者通过“标准”工具栏中的“添加窗体”按钮,或者在“工程资源管理器”中右击,在快捷菜单中单击“添加”→“添加窗体”命令,在“添加窗体”对话框中,双击“窗体”图标,或单击“窗体”图标再单击“打开”按钮,如图10-1所示,也可以添加现存的窗体。在VisualBasic中,添加标准模块的方法也有三种:通过“工程”菜单的“添加模块”命令,或者通过“标准”工具栏中的“添加模块”按钮,或者在“工程资源管理器”中右击,在快捷菜单中单击“添加”→“添加模块”命令,在“添加模块”对话框中,双击“模块”图标,或单击“模块”图标再单击“打开”按钮,如图10-2所示,也可以添加现存的模块。10.1.4在工程中移除窗体或标准模块在VisualBasic中,移除窗体的方法有两种:(1)在“工程资源管理器”中单击要移除的窗体,再通过“工程”菜单的“移除窗体名”或“移除窗体文件名.frm”命令。如果窗体未保存,则“移除”后是“窗体名”;如果窗体已经保存为文件,则“移除”后是“窗体文件名”,如图10-3所示;(2)在“工程资源管理器”中右击要移除的窗体,在快捷菜单中,选择“移除窗体名”或“移除窗体文件名.frm”命令。在VisualBasic中,移除标准模块的方法也有两种:(1)在“工程资源管理器”中单击要移除的标准模块,再通过“工程”菜单的“移除标准模块名”或“移除标准模块文件名.bas”命令。如果标准模块未保存,则“移除”后是“标准模块名”;如果标准模块已经保存为文件,则“移除”后是“标准模块文件名”,如图10-4所示;(2)在“工程资源管理器”中右击要移除的标准模块,在快捷菜单中,选择“移除标准模块名”或“移除标准模块文件名.bas”命令。注意:窗体或标准模块被移除后,如果窗体或标准模块已经保存为文件,仅仅是去掉了窗体或标准模块在工程文件中的引用,并没有将窗体文件或标准模块文件删除。如果已经做过修改的窗体或标准模块,则提示是否保存;如果是新添加的窗体,则直接移除。10.1.5启动窗体启动窗体是执行VisualBasic应用程序时,首先执行并被显示出来的窗体。默认情况下,新建一个工程时最先创建的窗体即为启动窗体,其他的窗体也可以设置为启动窗体,将其他的窗体设置为启动窗体的方法有两种:(1)通过“工程”菜单中的“工程1属性”命令,在“工程属性”对话框中的“启动对象”下拉列表框中,选择将要作为启动的窗体,单击“确定”按钮,如图10-5所示;(2)在“工程资源管理器”中右击“工程1”,在快捷菜单中,单击“工程1属性”命令,在“工程属性”对话框中的“启动对象”下拉列表框中,选择将要作为启动的窗体,单击“确定”按钮。10.1.6SubMain过程SubMain过程是VisualBasic中惟一可以作为启动对象的过程。在SubMain过程中,一般实现对全局级变量的初始化,根据用户的选择决定加载哪一个窗体等功能。SubMain过程只能放在标准模块中,而且在一个应用程序中,最多只能有一个SubMain过程;SubMain过程不会自动成为启动对象,必须进行设置,设置方法与将窗体设为启动对象的方法类似。10.1.7不同窗体之间数据的访问复杂的应用程序一般包含多个窗体,不同窗体之间经常需要进行数据交换,实现不同窗体之间数据访问的方法,主要有如下两类:(1)通过引用不同窗体的控件属性在当前窗体中引用其他窗体中某个控件的属性值,其语法格式如下:其他窗体名.控件名.属性名(2)通过全局级变量实现不同窗体之间数据的引用全局级变量的作用域是整个应用程序的所有模块,通过定义全局级变量可以实现不同窗体之间数据的交换。【例10-1】用户注册、登录应用系统的多重窗体应用程序。新建一个工程,其中包含一个标准模块和三个窗体模块:登录窗体模块或登录对话框(选择“工程”菜单中的“添加窗体”命令,在“添加窗体”对话框中,双击“登录对话框”图标)、用户注册窗体模块和应用程序主窗体模块,这三个窗体分别如图10-6、图10-7、图10-8所示。在标准模块的通用声明段定义了一个全局级变量username,用于存放用户名,在整个应用程序的所有模块中都可以使用这个用户名;还定义了SubMain过程,并将SubMain过程设为启动对象。程序运行后,用MsgBox()函数提示“新用户请先注册,您是新用户吗?”,让用户选择是新用户还是老用户,新用户则显示注册窗体,老用户则显示登录窗体,用户注册或登录后,用户名存放到全局级变量username中,然后,显示应用程序的主窗体,应用程序主窗体的程序代码、菜单等省略。10.1.8保存多重窗体应用程序保存多重窗体应用程序的方法与保存单窗体应用程序的方法类似,但由于多重窗体应用程序,在一个工程中包含了多个窗体和标准模块,因此,一个应用程序将保存为多个窗体文件、多个标准模块文件和一个工程文件,这些文件被分别保存后,在“工程资源管理器”中,将显示每一个窗体的窗体名(窗体Name属性的值)和窗体文件名(保存到外存中的文件名)以及每一个标准模块的标准模块名(标准模块Name属性的值)和标准模块文件名(保存到外存中的文件名),如图10-9所示。在“工程资源管理器”中,可以选择任何一个窗体或标准模块进行修改或者另存为其他文件名等操作,也可以设置启动对象。10.1.9打开多重窗体应用程序在VisualBasic中,打开一个应用程序一般都是通过工程文件打开,但是,当一个工程中只有一个窗体时,可以只保存窗体文件,而不保存工程文件,双击打开窗体文件时,VisualBasic将自动创建一个工程,然后即可执行该窗体;对于多重窗体应用程序,在一个工程中包含了多个窗体和标准模块,因此,打开一个多重窗体应用程序时,必须首先打开多重窗体应用程序的工程文件,才能完整地执行。10.1.10编译与运行多重窗体应用程序编译与运行多重窗体应用程序的方法与单窗体应用程序类似,默认情况下,编译后生成的可执行文件的文件名就是工程文件名,可执行文件所在的路径就是工程文件所在的路径,用户可以根据需要选择不同的路径和文件名,但是多重窗体应用程序可以指定某个窗体或SubMain过程等作为启动对象。【例10-2】加、减法算术练习的多重窗体应用程序。新建一个工程,其中包含一个标准模块和三个窗体模块:应用程序主窗体模块、加法练习窗体模块和减法练习窗体模块,这三个窗体分别如图10-10、图10-11、图10-12所示。在标准模块中定义了一个全局级过程statistic,用于统计加法练习或减法练习中答对的题数和答错的题数,并通过形参返回给调用过程的实参;应用程序主窗体模块主要用于显示所有做过的加、减法算术练习的题目以及加、减法算术练习的结果和总题数;加法练习窗体模块自动产生0~99之间的两个随机整数的加法算式,并显示在标签Label1中,在文本框Text1中,输入答案后按下回车键,系统将给出答对或答错的判断结果,同时自动产生下一题,并将回答过的题目显示在列表框中;单击“返回”命令按钮可以返回到主窗体,并将列表框中的练习题目加入到主窗体列表框中,然后,调用statistic过程统计所做练习的结果。减法练习窗体模块的功能与加法练习窗体模块类似。10.2多文档界面在一个多文档界面应用程序中,MDI窗体(父窗体)只能有一个,但MDI窗体的子窗体可以有多个,所有的子窗体只能显示在MDI窗体的工作区域内,子窗体可以在MDI窗体内移动位置,但不能移到MDI窗体之外,当子窗体最小化时,并不是显示在任务栏中,而是排列在MDI窗体的下方;当MDI窗体改变位置时,所有的子窗体也跟着改变;当MDI窗体最小化时,所有的子窗体都看不见;当关闭MDI窗体时,所有子窗体也随之关闭;MDI窗体和子窗体都可以有各自的菜单,当加载子窗体时,子窗体的菜单将覆盖MDI窗体的菜单。1.多文档界面的创建多文档界面应用程序需要一个MDI窗体、一个或多个MDI窗体的子窗体。一般情况下,先创建一个MDI窗体和一个子窗体,其他的子窗体在程序运行时动态创建。添加MDI窗体的方法与添加单文档界面窗体的方法类似,有三种:通过“工程”菜单的“添加MDI窗体”命令,或者通过“标准”工具栏中的“添加MDI窗体”按钮,或者在“工程资源管理器”中右击。添加子窗体的方法:先添加单文档界面窗体,再将其MDIChild属性值设为True。2.MDI窗体的常用属性(1)ActiveForm属性返回具有焦点或者最后被激活的子窗体。(2)ActiveControl属性返回子窗体上具有焦点的控件。3.MDI窗体的常用方法Arrange方法用于重排MDI窗体中的子窗体或图标,其语法格式如下:[MDI窗体名.]Arrange排列方式其中,如果是当前MDI窗体可以省略MDI窗体名;排列方式的取值见表10-1。常数值描述vbCascade0层叠所有非最小化MDI子窗体vbTileHorizontal1水平平铺所有非最小化MDI子窗体vbTileVertical2垂直平铺所有非最小化MDI子窗体vbArrangeIcons3重排最小化MDI子窗体的图标【例10-3】MDI窗体应用程序。新建一个工程,其中包含一个MDI窗体和一个子窗体,MDI窗体的主菜单项有:“文件”(包括“新建”和“关闭”子菜单项,这两个菜单项组成菜单控件数组,数组名为file)和“窗口”(包括“层叠子窗体”、“水平平铺子窗体”、“垂直平铺子窗体”和“重排图标”子菜单项,这四个菜单项组成菜单控件数组,数组名为arrge),如图10-13所示。10.3闲