第 5章 菜单、工具栏和多文档的设计
内容提要
? Delphi7的菜单界面设计
? 菜单的属性设置和功能代码
? 工具栏的创建
? 状态栏的创建
? 多文档 MDI程序的创建
5.1 Delphi 7 的菜单界面设计
菜单是方便用户和应用程序交互的一种方式 。 Delphi 7 提供了一个进行
菜单设计的便捷工具 Menu Designer, 通过这个菜单设计工具可方便的
进行菜单设计 。
应用程序的菜单有两种形式,MainMenu是一般的 Windows用户界面必须
的部件, 它显示在固定的位置, 一般用键盘和鼠标左键来激活菜单的功
能项; PopupMenu是弹出式菜单, 一般以鼠标的右键或其它快捷键来激
活菜单, 菜单的位置是在屏幕上, 浮动, 的, 根据鼠标的当前位置确定 。
我们将 MainMenu和 PopupMenu统称为菜单 。 MainMenu和 PopupMenu都
存在于 Delphi 7 集成开发环境的组件面板的 Standard 页面上 。
创建菜单时, 首先要在窗体中放置一个菜单对象 。 然后调入 Menu
Designer进行菜单的 详细设定 。 用两种方式可以进入 Menu Designer,
?选中菜单部件, 点动属性中 Items省略按钮 。
?在菜单部件上双击左键, 就会出现 Menu Designer。
5.1.1 主菜单 TMainMenu的设计
TmainMenu 组件封装了菜单栏及其菜单项 。 要设计窗体的主菜单, 只
需从组件面板的 Standard 页中将该组件拖动到窗体上 。 然后双击该组
件, 在弹出的菜单编辑对话框中编辑即可 。 Menu Designer 的设计界面
如下图 所示 。
5.1.2 弹出式菜单 TPopupMenu的设计
TPopupMenu 组件为右击组件时显示的弹出式菜单组件。
PopupMenu在使用 Menu Designer设计菜单 时是完全相同的。
只不过菜单是用鼠标的右键激活的。弹出式菜单在一定的
窗口范围内激活,所以必须将窗口和弹出式菜单联系起来。
在设计完 PopupMenu后,须在 Name属性中为它命名,然后
把这个名称赋给窗体的 PopupMenu属性。 PopupMenu 组件
的常用属性列表如下,
( 1) Alignment,指定用户右击时 TpopupMenu 组件出现
的位置, 即弹出式菜单出现在鼠标指针的左侧, 右侧还是
中央 。 该属性默认为 paLeft, 即菜单的左上角显示在指针
位置 。
( 2) AutoPopup,为真 ( True) 时, 用户右击以此组件为弹出
式菜单的组件时, 该组件自动弹出;否则应在程序中使用
Popup 方法控制弹出式菜单的显示 。
( 3) HelpContex,指定弹出式菜单的上下文 ID, 由于 Help
系统中的每个界面都有一个惟一的上下文 ID, 所以使用该属
性可以建立弹出式菜单与帮助界面之间的关联 。
( 4) MenuAnimation,指定 TpopupMenu 菜单的显示方式 。
( 5) PopupComPonent,最后一个使用该组件的组件。
( 6) PopupPoint,指定弹出式菜单出现的位置,其值由 Popup
方法设置。
( 7) TrackButton,指定当弹出式菜单与工具栏按钮关联时
激活弹出式菜单的鼠标键。
5.1.3 为菜单设定加速键和热键组成
?设定加速键的方法为:只需在为菜单项的 Caption 属性输入名称时, 将
,&”放到需要指定为加速键的字母前面, 该字母将被用下划线显示, 运行
时, 按, Alt+加速键字母, 可以激活该菜单条 。 为前面图 5-2 所示的例子设
置加速键, 如图 5-4 所示 。
?设定热键的方法是:在对象加查器 ( Object Inspector) 中, 设置该菜单项
的 ShortCut属性 。 单击该属性值可弹出下拉菜单, 为它选定一个热键组合即
可 。 在运行时, 通过, Ctrl+热键字母, 来激活菜单条 。 加速键和热键并不矛
盾, 用户可以同时指定它们 。 再为图 5-4 所示的例子设置热键, 如图 5-5 所
示 。
5.1.4 多级菜单和菜单位置的调整
创建多级菜单对于管理复杂的菜单命令结构非常有用 。 Delphi的多级菜单风
格是下级菜单列在它上层菜单的边上, 如图 5-6 所示 。
创建多级菜单的方法是:把加亮条移到它的上层菜单条上, 按 Ctrl+右行键,
将弹出子菜单, 按照前面所述的方法进行创建多级子菜单 。 一般限制在三
级之内比较合适 。
5.2 菜单的属性设置和功能代码
通过菜单设计器 ( Menu Designer) 设计的菜单仅仅是一个程序界面,
还不具有任何功能, 要想让菜单具有实际功能必须给相应的菜单项
连接功能代码 。
为了给菜单项连接功能代码,可以双击菜单项,或在特定菜单项的
Events 页上双击它响应的事件的值段,Delphi 7 将引导进入代码编
辑器,光标停在事件对应的事件处理过程中,此时就可以通过程序
来设置菜单项的属性或编写其它功能的代码。
5.2.1 设置菜单项的有效和无效
在实际的应用程序中, 由于各种原因需要对菜单项的有效和无效进行动态
设置 。 比如当前的系统剪贴板中没有数据可以粘贴, 【 粘贴 】 菜单项就应
该是变灰的禁用状态 。
菜单项( MenuItem)的 Enabled 属性表示该菜单项是否被禁用。当
Enabled 属性为真( True)时,该菜单项可以响应事件,即可用状态;将
Enabled 属性设置为假( False)时,则表示该菜单项当前不能响应事件,
颜色也变成灰色,即禁用状态。
5.2.2 菜单项的复选标记
所谓复选标记, 是指当用户选中某菜单项时, 系统会在菜单
项前面设置标记 。 比如 Windows 98 窗口中 【 查看 】 菜单下的
有关工具栏各菜单项, 其中已显示的工具栏菜单项前面有勾
号, 而还没有调出的工具栏所对应的菜单项前面就没有勾号 。
下面我们设计任意一个菜单项, 使其能通过改变 Checked 属
性来控制是否显示状态栏 。 设置该菜单项的 Name 属性为
MenuBar, Caption 属性为, 工具栏,, 并添加一个状态栏组
件, 其 Name 属性为 StatusBar1 。 完成这样的功能代码如下,
Procedure TForm1.MenuBarClick (Sender, Tobject);
Begin
If (MenuBar.Checked) Then
Begin
MenuBar.Checked,= False ; //使 MenuBar 菜单项设置为无标记
StatusBar1.Visible,= False ; //使 StatuesBar1 组件隐藏
End
Else
Begin
MenuBar.Checked,= True ; //使 MenuBar 菜单项设置为有标记
StatusBar1.Visible,= True ; //使 StatuesBar1 组件显示
End;
End;
5.2.3 菜单项的单选标记
设置单选菜单项的方法为:首先将相关的菜单项作为一组,
即使它们的 GroupIndex 属性设置为相同的值;然后将其中
的每一个菜单项的 RadioItem 属性设置为 True 。 这样就可以
形成一组单选菜单项 。
参见 P159。
5.2.4 动态菜单的设计
应用程序更多的时候要求菜单能够动态的变化, 这包括
可以改变一个窗口的主菜单, 可以改变某菜单下的菜单
项, 也可以合并菜单等等 。
实现动态菜单的方法有很多种, 要根据具体情况选择适
当的实现手段 。
( 1) 一般针对菜单变化比较大的, 我们可以事先设计
好不同的菜单, 到需要改变窗口菜单时, 只需将不同名
称的 MainMenu 组件的名称赋给窗口的 Menu 属性即可 。
( 2) 如果是较原来的菜单增加或删除某菜单项的, 我
们可以事先把所有的菜单项都设计好, 然后根据需要使
某些菜单项可见, 而使另一些菜单项不可见 。 方法是通
过设置菜单项的 Visible 属性实现 。
5.2.4 动态菜单的设计
( 3) 如果仅仅是改变菜单项上的显示标题, 只需将一
个新的标题赋给菜单项的 Caption 属性即可以实现 。
( 4) 如果在菜单设计阶段并不知道需要添加的菜单项
是什么, 或者实际要求是应用程序的使用者去创建的,
可以利用菜单项的 Insert 和 Remove 方法进行添加和删
除菜单项 。
( 5)可以设计多个菜单,再通过 AutoMerge 属性对相
应的菜单进行融合,也可以将融合的菜单分离开来。融
合菜单时要设置菜单项的 GroupIndex 属性,融合的结
果将按 GroupIndex 属性值的大小进行排列。在程序中
也可通过 Merge 和 UnMerge 方法来融合和取消融合。
如 MainMenu1.Merge(MainMenu2);或
MainMenu1.UnMerge(MainMenu2)。
事实上, 更多的时候是依据开发者的习惯, 可以综合灵
活运用 。
5.2.5 菜单的提示
菜单显示的提示一般出现在状态栏上 。
在菜单条任一项的值段按 F1,可以查阅在线帮助, 在
帮助 的正 文中 找到 OnHint并查阅它 的例 程, 将
DisplayHint等方法的例程 Copy到您的程序中 。 然后,
在菜单条的 Hint属性中加入提示正文, 运行时当用户
将鼠标移到菜单项时, 在窗体的底部状态行中会出现
Hint属性中的提示信息 。
新建一个项目, 在窗体上添加一个 StatusBar 组件,
并把它的 ShowHint 属性和 SimplePanel 属性同时
设置为真 ( True) ;在添加 MainMenu 组件, 并对其
上的菜单项的 Hint 属性设置相应的提示信息 。 参见
图 5-11。
5.2.5 菜单的提示
5.3 工具栏的创建
Delphi 7 提供了一个 ToolBar 组件用来设计工具栏 。 该组件存
在于 Delphi 7 集成开发环境的组件面板的 Win32 标签页上 。
ToolBar 组件上可以放置很多快捷按钮 ( Tool Button) 以及其
它控件, 能够将它们按行排列并自动调整它们的大小和位置 。
?给 ToolBar 组件添加 ToolButton 工具按钮的方法:首先选中
ToolBar 组件, 然后右击鼠标, 在弹出的菜单中点选 New
Button 菜单项即可将一个 ToolButton 添加到工具栏上 。 按照此
方法, 可以从左到右排列顺序添加需要的按钮数目 。 但此时的
工具按钮上还没有图标, 还需要为每个工具按钮配置图标 。
?给工具按钮配置图标的方法为:首先从可视化组件面板的
Win32 标签页上下拉一个 ImageList 组件到相应的窗体上, 然
后选择 ToolBar 组件, 设置其 Images 属性为 ImageList 组件的
名称 。
ImageList 组件是一个图像的列表, 通过它的索引引用表中的
图像 。 添加到窗体上的 ImageList 组件还需要添加图像文件,
只需双击该组件调出 ImageList Editor 对话框, 再单击其上的
Add 按钮, 从弹出的打开文件对话框中选择准备好的位图文
件名称并打开就可将这个图像文件添加到 ImageList 的图像文
件列表中 。
ToolBar 组件常用的属性和事件如下,
( 1) Align 属性:默认为 alTop, 所以 ToolBar 组件默认停靠
在窗体的最上边, 并且宽度会自动适应窗体宽度的改变 。
( 2) AutoSize 属性:工具栏的大小是否自动匹配 。
( 3) Caption 属性:工具栏的标题, 当其浮动时可显示的标
题名称 。
( 4) DockSite 属性:是否可以作为停靠的对象。
( 5) OnDragDrop 事件:当组件被拖动时触发该事件。
( 6) OnDragOver 事件:当另一个组件拖过这个组件时触发该事件。
( 7) OnDockDrop 事件:当组件拖到 Dock Site 组件上面,释放鼠标左
键时触发该事件。
( 8) OnDockOver 事件:当组件拖到 Dock Site 组件上时触发该事件。
( 9) OnUnDockOn 事件:当组件拖离 Dock Site 组件时触发该事件。
( 10) OnEndDrag 事件:当组件拖动结束,或者取消拖动或者放下组件
时触发该事件。
( 11) GetSiteInfo 事件:通过该事件可取得 Dock Site 组件的一些信息。
5.4 状态栏的创建
在应用程序中, 通常在窗体的最下方放置状态栏,
这样可以提示现在的操作命令或显示其它有用的
帮助信息 。
5.4.1 TStatusBar组件
在 Delphi 7 中, StatusBar 组件是显示状态栏的组件, 它位于 Delphi 7 的
集成开发环境的组件面板的 Win32 标签页上 。
StatusBar 组件其实是一行多个并列的 Panel, 每个 Panel 都是
TStatusPanel 对象 。 当选中 StatusBar 组件后, 可单击鼠标右键, 可以通
过弹出的菜单命令 【 Panels Editor… 】 打开状态栏编辑器, 在这里可以添
加和删除状态栏中的 Panel 。
StatusBar 常用的属性介绍如下,
( 1) Align 属性:默认为 alBottom, 所以 StatusBar 组件默认停靠在窗
体的最下边, 并且宽度会自动适应窗体宽度的改变 。
( 2) AutoHint 属性:当取值为真 ( True) 时, 鼠标移动到菜单项或其它
组件上时, 在状态栏显示相关的组件对象的 Hint 提示信息 。
( 3) Hint 属性:状态栏自身的提示信息 。
( 4) ShowHint 属性:当取值为真 ( True) 时, 鼠标移动到状态栏上显示
自身的 Hint 提示信息 。
( 5) SimplePanel 属性:该属性决定时否允许 StatusBar 显示单一或者多
个 Panel, 当 SimplePanel 属性取值为真 ( True) 时, StatusBar 只含有单
一的 Panel 。 当 SimplePanel 属性取值为假 ( False) 时, StatusBar 将为
Panels 属性中的每一项显示一个分隔的 Panel
( 5) SimplePanel 属性:该属性决定时否允许 StatusBar 显示单一
或者多个 Panel,当 SimplePanel 属性取值为真( True)时,
StatusBar 只含有单一的 Panel 。当 SimplePanel 属性取值为假
( False)时,StatusBar 将为 Panels 属性中的每一项显示一个分隔
的 Panel
( 6) SimpleText 属性:当 SimplePanel 属性取值为真 ( True) 时,
单一的 Panel 显示的文本可以通过 SimpleText 属性获得 。
( 7) Panels 属性:通过点击其后的值段, 可调出状态栏编辑器 。
5.4.2 状态栏创建实例
我们创建一个小的实例, 看一下状态栏的使用 。 这个例子把状态栏
分为两个 Panel,但都只显示简单的文本信息 。 实例创建过程如下,
( 1) 通过 Delphi 7 的菜单命令创建一个新的项目 。 同时, 添加状态栏
组件 StatusBar, 使之保留原来的 Align 属性值 alBottom, 即默认
停靠在窗体的底部 。
( 2) 设置 StatusBar 组件的 Name 属性值为 StatusBar1 ;同时
SimplePanel 的属性值为假 ( False) 。
( 3) 设置 StatusBar 组件的 Panels 属性, 单击其后的, …,按钮, 并在
弹出的状态栏编辑器中添加两个 Panel 。
( 4) 程序要实现当鼠标在窗体 Form1 上移动时在状态条上显示当前
的鼠标位置, 所以需要响应窗体 Form1 对象的 OnMouseMove 事件;
为了在状态条的另一部分显示固定信息, 同时还响应了窗体 Form1
对象的 OnCreate事件 。
事件的处理程序清单代码如下,
procedure TForm1.FormMouseMove(Sender,TObject; Shift,
TShiftState; X,Y,Integer);
Var
MyString, String ;
begin
MyString,= '当前鼠标的位置为 (' ;
MyString,= MyString + IntToStr(X) ;
MyString,= MyString + ',' ;
MyString,= MyString + IntToStr(Y) ;
MyString,= MyString + ')' ;
//在 Panel0 上显示对应的鼠标在窗体上的位置信息
StatusBar1.Panels[0].Text,= MyString ;
end;
procedure TForm1.FormCreate(Sender,TObject);
begin
Form1.Caption,= '状态栏示例 ' ;
//在 Panel1 上显示固定的文本信息
StatusBar1.Panels[1].Text,= '制作状态栏 ' ;
end;
运行程序,并且在窗体上移动鼠标,可发现状态栏上的显示变化。程
序运行界面如图 5-14 所示。
5.5 多文档 MDI程序的创建
在 Windows 应用程序中, 每个窗体 Form 都可
以实现为单文档界面应用程序 ( SDI,Single
Document Interface ) 或者多文档界面程序
( MDI, Multiple Doccument Interface ) 程序 。
SDI 应用程序包含单一的文档视图, 而 MDI 应
用程序是一种在应用程序中同时可打开两个或
更多文件的界面形式 。 例如在 Word字处理和电
子表格应用程序中经常使用, 用户可在多个文
件中方便地进行切换 。
5.5.1 MDI窗体及其属性
MDI 应用程序一般具有主菜单, 能够统一对所有的子窗
体操作 。 最常用的就是能够使用层叠 ( Cascade) 格式
或者平铺 ( Tile) 格式等排列方法来放置所有的窗体,
当主窗体最小化的时候, 所有的窗体都将最小化 。
创建 MDI应用程序的基本步骤如下,
? 创建主窗口
? 创建子窗口
? 创建主窗口菜单
5.5.2 利用模板创建 MDI应用程序
使用 Delphi 的 MDI 应用程序模板创建标准的 MDI 应用程序 。
创建步骤如下,
( 1) 单击 【 File】 |【 New】 |【 Others】, 在弹出 New Items 对话框,
选择 Projects 标签页, 再选中其中的 MDI Application 模板, 单击
【 Ok】 按钮 。
( 2) 在单击 【 Ok】 按钮后, 会 出现 【 Select Directory】 对话框, 。
选择相应的目录, 单击 【 Ok】 按钮 。
( 3) 这时, 一个 MDI 应用程序已经建立, 如图 5-17 所示 。 用户
可选择相应的对象查看其属性 。
运行该程序, 点击 3次 【 新建 】 按钮, 则新建了 3 个文档窗口, 如
图 5-18 所示 。 再点击菜单栏或工具栏上的其它命令按钮, 会发现
它已经是一个有了一定功能的程序了, 可以建立很多子窗体和打
开文件, 以及排列窗体等 。
图 5-17 MDI 窗口 图 5-18 多文档程序运行界面