登陆注册
36209800000023

第23章 多文档界面程序设计

本章要点

多文档界面程序的概念

多文档界面的结构

多文档界面程序的设计

多文档界面的菜单

使用多文档界面模板

Windows应用程序按其文档结构可以划分为单文档界面应用程序和多文档界面应用程序。

单文档界面(SingleDocumentInterface,SDI)应用程序,就是应用程序在同一时刻只能打开一个窗口,即只能处理一个文档,若想打开另一个文档或新建一个文档,原窗口必须关闭。如Windows中的记事本就是一个单文档界面应用程序。

多文档界面(MultipleDocumentInterface,MDI)应用程序,就是应用程序可以同时拥有多个子窗口,即能同时处理多个文档,多个窗口之间可以互相切换。如MicrosoftWord就是一个多文档应用程序。多文档界面应用程序便于各窗口之间交换数据。

本章介绍多文档界面应用程序的设计。

9.1多文档界面的结构

在多文档界面应用程序中,应用程序本身使用一个窗口,称为主窗口;打开的每个文档使用一个窗口,称为子窗口。

9.1.1主窗口

多文档界面应用程序中,只能有一个主窗口。

这个主窗口看上去和普通应用程序的主窗口没有什么区别,同样有标题栏、菜单栏、缩放边框、控制菜单和最大化、最小化按钮。不同的是,它的用户区不是用于程序的输出,而是用于子窗口的显示。

创建多文档界面应用程序主窗口的过程和创建普通主窗口基本一样,但是主窗体的FormStyle属性要设置为fsMDIForm。

9.1.2子窗口

多文档界面应用程序的子窗口看上去和普通窗口一样,不同的是它们没有菜单,它们使用主窗口的菜单。

多文档界面应用程序运行时,可以同时显示多个子窗口,但每一时刻只能有一个子窗口被激活,而且所有的子窗口都显示在主窗口的边界内,子窗口最小化后的图标也在主窗口的边界内。

创建多文档界面应用程序子窗口的过程和创建普通主窗口也基本一样,但是子窗体的FormStyle属性要设置为fsMDIChild。

9.2多文档界面应用程序的设计

9.2.1多文档界面应用程序设计举例

下面通过一个实例说明多文档界面应用程序的设计过程。

例9-1设计一个多文档界面应用程序。

(1)执行【File】→【New】→【Application】菜单命令,创建新的应用程序,新建一个默认窗体Form1,作为多文档界面应用程序的主窗体。

(2)设置主窗体的属性,如表9-1所示。

(5)在主窗体中放置MainMenu组件,启动主菜单设计器,设计主窗体的菜单,如图9-1所示。

(6)选择事件、编写事件处理代码。

按功能要求,单击主窗口的【窗口】→【新建】菜单命令,应创建子窗口。【新建】菜单命令设置Name属性值为“NWindowsNew”,选择事件OnClick,并编写事件处理代码。

MainForm单元文件的部分代码如下:

这里需要说明的是:

定义了一个变量counter,用来为子窗口计数,每创建一个子窗口,counter加1,子窗口标题编号加1;创建子窗口,要调用子窗体单元文件,所以要在文件的implementation部分加入usesunit2一句;Inc(counter)是实现counter+1的系统函数。

(7)保存单元文件unit1、unit2和项目文件project1。

(8)运行程序,结果如图9-2所示。

然后执行【窗口】→【新建】菜单命令,每执行一次,创建一个子窗口,子窗口的标题依次为MDI子窗口1、MDI子窗口2等,如图9-3所示。

分析程序运行结果可以发现,程序开始运行、执行【窗口】→【新建】菜单命令之前就已经创建了一个子窗口,如图9-2所示。为什么?

执行【Project】→【ViewSource】菜单命令,打开项目文件Project1,如下所示:

可以看出,程序开始运行就执行了语句Application.CreateForm(TChildForm,ChildForm),创建了一个子窗口。要解决这个问题,执行【Project】→【Options】菜单命令,打开【ProjectOptions】对话框,如图9-4所示。

由图9-4可见,【Auto-createforms】列表框中列出MainForm和ChildForm两个窗口,应把ChildForm去掉。方法是:选择它,单击【>】按钮,将它移到【Availableforms】列表框中,然后单击【OK】按钮,关闭对话框。这时再看项目文件,发现Application.CreateForm(TChildForm,ChildForm)语句不见了。保存文件,运行程序,结果如图9-5所示,符合要求。

9.2.2多文档界面应用程序子窗口的控制

为使多文档界面应用程序更加完善,还要增加一些对子窗口进行控制的功能。

1.窗口菜单

大多数MDI程序主窗口某一主菜单项下都有一个下拉菜单,显示当前打开的所有子窗口的列表,并且标记出当前激活的子窗口,如图9-6所示即为MicrosoftWord中【窗口】主菜单项的下拉菜单,其中列出当前打开的子窗口有3个:10调试、11多媒体和9多文档,9多文档为当前激活子窗口,这个子窗口列表也称“窗口菜单”。使用窗口菜单,用户可以在各个子窗口之间快速切换。

建立窗口菜单,只要将主窗体的WindowsMenu属性设置为带有窗口菜单的主菜单项的Name属性值,那么程序运行时,该主菜单项的下拉菜单中就会显示窗口菜单。

如在上面的例题中,若要求在【窗口】主菜单项中显示窗口菜单,则将主窗体的WindowsMenu属性设置为【窗口】主菜单项的Name属性值,如“NWindows”。这时再运行程序,创建了子窗口后,【窗口】主菜单项下就会显示窗口菜单,如图9-7所示。

每个菜单栏中,只能创建一个窗口菜单。

2.MDI菜单

在多文档界面应用程序中,通常还应有控制子窗口显示方式的菜单命令,称为“MDI菜单”。这些菜单命令一般有【层叠】、【平铺】、【上一个子窗口】、【下一个子窗口】等。增加了MDI菜单的主窗口如图9-8所示。

1)【层叠】菜单命令

执行【层叠】菜单命令,各子窗口从主窗口左上角开始层叠式斜向排列,如图9-5所示。

【层叠】菜单命令,是调用Cascade方法实现的,菜单命令的代码段为:

2)【平铺】菜单命令

执行【平铺】菜单命令,各子窗口水平或者垂直并列放置。因此,【平铺】菜单命令,又可有两个子菜单命令:【水平】和【垂直】。

【平铺】菜单命令,是调用Tile方法实现的。为区分水平和垂直,先用TileMode设置平铺模式。

假设【水平】菜单命令的Name属性值为NwinTileHori,则该菜单命令的处理代码段为:

执行【平铺】→【水平】菜单命令后,各子窗口显示方式如图9-9所示。

假设【垂直】菜单命令的Name属性值为NwinTileVert,则该菜单命令的处理代码段为:

procedureTMainForm.NwinTileVertClick(Sender:Tobject);

执行【平铺】→【垂直】菜单命令后,各子窗口显示方式如图9-10所示。

3)【下一个子窗口】菜单命令

执行【下一个子窗口】菜单命令,可将激活子窗口改为当前子窗口的下一个子窗口。

【下一个子窗口】菜单命令,是调用Next方法实现的,假设【下一个子窗口】菜单命令的Name属性值为NwindowsNext,则该菜单命令的处理代码段为:

4)【上一个子窗口】菜单命令

执行【上一个子窗口】菜单命令,可将激活子窗口改为当前子窗口的上一个子窗口。

【上一个子窗口】菜单命令,是调用Previous方法实现的,假设【上一个子窗口】菜单命令的Name属性值为NwindowsPrevious,则该菜单命令的处理代码段为:

当然,切换当前激活子窗口也可以通过窗口菜单,或者在窗口中直接用鼠标单击要激活的子窗口来实现。

3.关闭子窗口

多文档界面应用程序运行后,单击子窗口右上角的关闭窗口按钮,并不能将子窗口关闭,而只能将子窗口最小化,并放置在主窗口的左下角。若想真正实现子窗口的关闭,还必须为子窗体添加OnClose事件,编写相应的处理代码,其代码段为:

程序运行创建子窗口,单击子窗口关闭按钮,弹出消息框,询问是否关闭子窗口,单击【Yes】按钮,子窗口关闭。

9.3多文档界面中子窗口的菜单设计

在多文档界面应用程序中,只有主窗口有菜单栏,子窗口不显示自己的菜单栏,子窗口使用的菜单项放在主窗口菜单栏中。就是说,主窗口中有的菜单项是对子窗口进行操作的,而对主窗口不起作用。因此,这些菜单项只能用子窗口的菜单设计器进行设计,然后通过一定的手段加入到主窗口的菜单栏中。

9.3.1菜单合并

菜单合并是指将子窗口的主菜单项插入到主窗口的菜单栏中。子窗口创建前,显示的只是主窗口的主菜单项;而子窗口创建后,显示的是主窗口和子窗口所有的主菜单项。如图9-2所示的MDI程序中,假设【编辑】菜单项是子窗口的主菜单项,这就是菜单的合并。菜单的合并是通过菜单项的GroupIndex属性实现的。

为实现这一目的,上面程序的设计要做如下改动:

(1)在主窗体的菜单设计中,将菜单项【编辑】删除,并将【文件】菜单项的GroupIndex属性值设置为1,将【工具】菜单项的GroupIndex属性值设置为3;(2)在子窗体中加入MainMenu组件,打开主菜单设计器,设置【编辑】菜单项,并将该菜单项的GroupIndex属性值设置为2;(3)保存文件,运行程序,显示主窗口如图9-11所示,可见菜单栏中没有了【编辑】

主菜单项,因为该主菜单项是对子窗口的,现没有子窗口,所以不显示【编辑】主菜单项是符合要求的。

执行【窗口】→【新建】菜单命令,创建第一个子窗口,这时程序界面如图9-12所示,显然针对子窗口的【编辑】主菜单项显示出来了。

9.3.2菜单覆盖

菜单覆盖是指用子窗口的主菜单项去覆盖主窗口的主菜单项。如图9-2所示的MDI程序中,假设【编辑】菜单项是主窗口和子窗口都有的主菜单项,子窗口创建前,【编辑】主菜单项是主窗口的;子窗口创建后,【编辑】主菜单项是子窗口的,这就是菜单的覆盖。菜单的覆盖也是通过菜单的GroupIndex属性实现的。

为实现这一目的,上面程序的设计要做如下改动。

(1)在主窗体的菜单设计中,主菜单项保持不变,将【文件】菜单项的GroupIndex属性值设置为1,将【编辑】菜单项的GroupIndex属性值设置为2,将【工具】菜单项的GroupIndex属性值设置为3等。

(2)在子窗体中加入MainMenu组件,打开主菜单设计器,设置【编辑】主菜单项,并将该主菜单项的GroupIndex属性值也设置为2。若要覆盖其他主窗体的主菜单项,则这里的GroupIndex属性值设置为被覆盖的主窗口的主菜单项的GroupIndex属性值。

(3)保存文件,运行程序,显示主窗口如图9-13所示,这时的【编辑】主菜单项是主窗口的。

执行【窗口】→【新建】菜单命令,创建第一个子窗口,程序窗口显示如图9-14所示,表面看起来菜单栏没有什么变化,但这时的【编辑】主菜单项已是子窗口的了。当然菜单项覆盖并不要求同名。

9.4使用MDI模板

从前面的介绍中可以看到,MDI应用程序的设计并不困难,但是却比较烦琐。为方便用户进行MDI应用程序设计,Delphi提供了预先设计好的MDI模板。

9.4.1打开MDI模板

打开MDI模板,要执行如下操作:

(1)执行【File】→【New】→【Other】菜单命令,打开【NewItems】对话框,选择【Projects】

选项卡,如图9-15所示。

(2)选择【MDIApplication】图标,然后单击【OK】按钮,弹出【SelectDirectory】对话框,如图9-16所示。

(3)在对话框的【Directories】列表框中选择Delphi安装目录下的Bin子目录,然后单击【OK】按钮,打开MDI模板,如图9-17所示。

由图9-17可见,该模板的主窗口中有6个组件,一个MainMenu组件并利用这个组件设计好了主窗口的菜单栏,一个OpenDialog组件,一个ActionList组件,一个ImageList组件,一个ToolBar组件,一个StatusBar组件。用户还可以根据需要,向窗体添加其他的组件。

ActionList组件:动作列表组件,位于组件模板的【Standard】选项卡中,用于集中管理程序中各种动作的,通过它可以简化代码编写,提高编程效率。

ImageList组件:图像列表组件,位于组件模板的【Win32】选项卡中,用来设置菜单项前面的位图。

ToolBar组件:工具栏组件,位于组件模板的【Win32】选项卡中,用来设计窗口工具栏。

StatusBar组件:状态栏组件,位于组件模板的【Win32】选项卡中,用来设计窗口中显示程序运行状态的状态栏。

执行【View】→【Forms】菜单命令,打开【ViewForms】对话框,利用对话框打开模板的子窗体,如图9-18所示,用户可根据自己的需要设计子窗体。

9.4.2MDI模板程序代码

在MDI模板中,已经为部分菜单命令编写了程序代码。激活代码编辑器窗口,可以看到主窗体单元文件中几个事件的处理代码如下:

用户可以根据需要,设计自己的程序代码。

习题9

1.什么是多文档界面程序?它与单文档界面程序有什么区别?在多文档界面程序中,主窗口和子窗口是什么关系?

2.设计多文档界面程序的要点是什么?这和多窗体程序的设计有什么异同?

3.如何建立窗口菜单、MDI菜单?

4.如何实现子窗口菜单的合并和覆盖?

同类推荐
  • 从平凡到神奇

    从平凡到神奇

    本书结合多年的开店经验,全面地讲解了在淘宝网开设店铺的相关知识,为准备在淘宝网创业的卖家及刚刚创建店铺的店主,提供全面的开店和经营方面的指导。本书按照淘宝开店的流程安排内容,侧重每个步骤中的实际技巧。本书分3个部分:如何在淘宝开店、如何开好店、如何做强做大店铺。前3章介绍了在淘宝网开设店铺的基础知识,指导读者在开设店铺前做好准备工作,以及建立起自己的店铺,并且完成店铺的第一笔交易;第4章至第7章主要介绍了网店装修和推广的方法,以及网店的物流经验和技巧;第8章着重介绍了将网店做大做强的方法,帮助卖家在开店和经营中树立品牌意识,做大做强自己的店铺。
  • 悟道:一位IT高管20年的职场心经

    悟道:一位IT高管20年的职场心经

    本书是一位有20多年职场经验的IT企业高管撰写的一系列有关职场悟道的短文集成,讲述的是在企业里如何修炼自己,如何摆平自己的心态,怎样做到“世事洞明”和“人情练达”,如何“搞定老板”,怎样做到工作和生活平衡等诸多话题,涉及到跳槽、转行、升迁、环境、沟通、老板、下属、老外等等。每一篇都以作者的亲身经历或者身边的故事说明道理,语言简洁流畅,妙趣横生,更有不少经典片段和发人深省的职场警句,读起来就像是一个睿智幽默的老朋友坐在你面前娓娓道来。
  • 组态软件控制技术

    组态软件控制技术

    监控组态软件是完成数据采集与过程控制的专用软件,它以计算机为基本工具,为实施数据采集、过程监控、生产控制提供了基础平台和开发环境。本书从应用角度出发,详细介绍了组态软件应用程序的开发过程。对窗口界面编辑、动画链接、实时和历史趋势、安全机制、I/O设备连接,以及生产应用等内容都做了非常详细的介绍。MCGS是优秀的监控组态软件之一,它功能强大、使用方便,可以非常容易地实现监视、控制、管理的各项功能,并可提供软、硬件的全部接口,方便、快速地进行系统集成,构成不同需求的数据采集与监控系统。本书可作为高等学校计算机应用、自动控制、电子技术、机电技术专业的教材,同时还可作为相关专业工程技术人员的自学用书。
  • 纵横于天地之间——互联网络技术

    纵横于天地之间——互联网络技术

    本书告诉你:不管你是谁,只要生活在当前的时代,你一定知道电话,知道电脑,知道上网……知道许许多多关于电子、关于计算机、关于网络的话题,这就是网络时代。网络的话题可多了:它是怎么来的?什么是“蜘蛛网”?网络的过去和现在,上网的方法,如何使用网络,互联网的安全,网络有“陷阱”吗?网络有“瘾”吗?网络文化和未来又是怎样的?到书中去找答案吧!
  • 公开时刻

    公开时刻

    本书从传播者分析,内容分析,媒介分析受众与效果分析,传播环境与传播控制分析等几大方面把汶川地震作为重大传播案例,阐释汶川地震的传播学遗产。对政府部门和新闻媒体在危机公关方面做出正面评价。
热门推荐
  • 漫威归来

    漫威归来

    穿越漫威十几年之后,李海洋又重新回到了自己的世界,不但重新回来了,他重新回到了2010年,他的高中年代,于是李海洋从这一刻开始,走上了成为科技大佬的道路。
  • 君宠君妃傻妃要逆天

    君宠君妃傻妃要逆天

    她,21世纪的绝顶杀手,可是在晚上熬夜看电视的时候突然穿越了,神马情况,竟然穿越到了一个废材傻公主的身上,而且还同名同姓,最倒霉的事是,皇上要赐婚,为什么她要一穿越就嫁人啊,哥哥,哥哥你在哪?一道道真相的大门就要打开,她的身世之谜有多么离奇,父亲母亲又是谁?她和哥哥真的是孤儿吗?
  • 都市大主

    都市大主

    【每日准时更新一日两章,还请推荐票走一走】精彩内容在九章往后,敬请期待。一则平凡的小故事改编,融合进现实社会的残酷,弱肉强食的生存法则!涵盖:龙,凤,仙,妖,鬼,兽,元素族!王壮背负着杀人犯的罪名踏上寻找真相的征途,不想却陷入一场巨大的阴谋中,历经无数磨难,步步踏入绝望而无生的境地,且看如何顽强的活下来。
  • 纨绔兵王

    纨绔兵王

    开开餐馆,捡捡漏,赌赌石头,顺便踩踩各种傻逼二代打打小怪兽。看一个集二世祖、兵王、精锐中的精锐、美食家等诸多称号于一体的一个矛盾的人如何成就自己别样的精彩人生。
  • 异种之灾

    异种之灾

    一场突如其来的陨石雨席卷世界。恐怖的异种肆虐地球。面临死亡,人性爆发。为了生存,人们宁愿放弃自由,躲在高墙建筑的基地之中。为了活着,一块食物疯狂抢夺,只为了没有希望的明天。绝望在蔓延,死亡仍在继续……
  • 我和你爱的人

    我和你爱的人

    睁开眼来,这个世界到底是真是假又有谁能说得清。
  • tfboys之tf灵异异能社

    tfboys之tf灵异异能社

    这是我的第二部小说。我不会写的很恐怖的,见谅!
  • 工业系神豪

    工业系神豪

    秦孤一觉醒来发现女朋友不认识自己了,亲人一个个摇身一变竟然成了军政商界的大佬,朋友们一个个鲤鱼跃龙门都成了官二代富二代...叮!工业系统更新完毕...神豪?呵呵,其实我是一代工业霸主!
  • 窥听者

    窥听者

    当你可以窥听到他人心里所想时,是不是会不再感到社交上的恐惧,并能轻而易举地与自己喜欢或是重视的人打好关系,投其所好。我想,有这样一种能力的话,只要不是个傻子,事业与爱情肯定样样不会少。可当你过度依赖并习以为常时,某一天它突然消失了,你又该如何?但,这仅仅只是个开始。如果你一觉醒来发现自己的窥听能力消失了,并且发现周围所有人好似都有了窥听他人的能力,唯独自己没有,你,又该作何反响呢?
  • 渴望激情

    渴望激情

    摄影师尹初石和妻子王一多年生活在一种平静或许也平淡的婚姻中,步入中年却找到了新的感情寄托。当他们在各自情人怀中体会爱的激情时,日常生活中的责任,婚姻的韧性,人性中的占有欲,男人的理性、女人的敏感,所有这一切都变成了爱情的对立。一个爱上另外女人但同时不想伤害妻子的丈夫,他的善良把情人伤到最后;一个被自我牺牲鼓舞的妻子,最后得到的是丈夫的背影。