DELPHI程序设计讲座(六)
多页对话窗口的设计和应用
董占山
(中国农科院棉花所,河南安阳,455112)
本讲主要介绍用DELPHI创建具有多个页面的动态对话窗口的设计方法,并讲解多页控制组件、列表框、文件列表框、目录列表框、驱动器组合框、位图按钮的定制。
1 相关组件页概述
本讲所设计的多页对话窗口,涉及到的组件主要分布在Standard、System、Additional、Win95等组件页上,主要用到多页控制(PageControl)、位图按钮、列表框等。其中Standard和Win95前面已经讲过了,下面介绍System和Additional对话页。
1.1 System组件页
System组件页上的组件都与Windows的系统事件相关,主要有定时器、绘图板、与文件相关的组件、与媒体、OLE和DDE相关的组件等,见表1所示。
表1 System组件页上的组件
|
图标
|
名称
|
功能
|
|

|
Timer
|
定时器,在特定的时间启动一段处理程序
|
|

|
PaintBox
|
绘图板,用来在窗体中绘图
|
|

|
FileListBox
|
文件列表框,显示当前目录下的所有文件
|
|

|
DirectoryListBox
|
目录列表框,浏览目录或改变当前目录
|
|

|
DriveComboBox
|
驱动器组合框,改变当前驱动器
|
|

|
FilterComboBox
|
过滤器组合框,用来筛选文件
|
|

|
MediaPlayer
|
媒体播放器,用来处理媒体文件
|
|

|
OleContainer
|
OLE载体,允许与应用程序之外的对象接口
|
|

|
DdeClientConv
|
DDE客户对话,用来创建一个DDE客户
|
|

|
DdeClientItem
|
DDE客户项目,用来保存被交换的数据
|
|

|
DdeServerConv
|
DDE服务器对话,用来创建一个DDE服务器
|
|

|
DdeServerItem
|
DDE服务器项目,用来保存被交换的数据
|
1.2 Additional组件页
Additional组件页是对Standard组件页的补充,表2列出了各个组件的名称和功能。
表2 Additional组件页上组件
|
图标
|
名称
|
功能
|
|

|
BitBtn
|
位图按钮,允许在按钮上同时显示图形和文本
|
|

|
SpeedButton
|
加速按钮,用来设计工具栏
|
|

|
MaskEdit
|
带有掩模的编辑框
|
|

|
StringGrid
|
字符串网格,以网格形式显示字符串数据
|
|

|
DrawGrid
|
绘图网格,以网格形式显示图形和文本
|
|

|
Image
|
图像,显示一幅图片
|
|

|
Shape
|
形状,在窗体上绘制几何图形
|
|

|
Bevel
|
斜边,在窗体上设计具有凸凹特征的线或框
|
|

|
ScrollBox
|
滚动框,设计带有滚动条的框
|
2 文档压缩程序ARJ.EXE的Windows外壳设计
|

图1 ARJ的Windows外壳
|
ARJ是一个DOS应用程序,用来对各种文件进行压缩,它有大量的命令和开关选项,对不熟悉的用户,必须通过查阅手册和程序的帮助信息并通过大量实践才能熟练使用。由于ARJ必须以DOS命令行方式工作,所以在Windows下不能直接使用它。为了能够在Windows下灵活地操纵ARJ,进行文档压缩,作者用DELPHI编写了一个多页对话窗口,来构造ARJ的命令行参数,并调用Windows API函数,直接调用ARJ.EXE,以进行文档压缩,免去了切换到DOS命令行状态手工打入命令的过程,只需要从不同的列表框中选取命令、开关选项、待压缩文件等。
2.1 组件及其属性
图1是设计完成的文档压缩程序ARJ的Windows外壳程序的界面,它由一个多页控制、4个位图按钮和一个编辑框组件组成,表3列出了它们的主要创建属性。
表3 有关组件的主要属性
|
组件名
|
属性名
|
取值
|
|
Form
|
AtiveControl
|
CloseBitBtn
|
|
|
BorderIcons
|
[biSystemMenu,biMinimize]
|
|
|
BorderStyle
|
bsSingle
|
|
|
Caption
|
ARJ文档压缩程序的Windows外壳
|
|
|
Name
|
WinArjForm
|
|
|
Position
|
poDefault
|
|
第一个BitBtn
|
Caption
|
确定
|
|
|
Kind
|
bkOk
|
|
|
Name
|
okBitBtn
|
|
第二个BitBtn
|
Caption
|
取消
|
|
|
Kind
|
bkCancel
|
|
|
Name
|
CancelBitBtn
|
|
第三个BitBtn
|
Caption
|
关闭
|
|
|
Kind
|
bkClose
|
|
|
Name
|
CloseBitBtn
|
|
第四个BitBtn
|
Caption
|
添加
|
|
|
Kind
|
bkCustom
|
|
|
Name
|
AddBitBtn
|
|
|
Glyph
|
(装载Borland
2.0\Images\Buttons文件夹下的Insert.BMP)
|
|
Edit
|
Name
|
CommandLineEdit
|
|
|
Text
|
(清除其中的内容)
|
|
PageControl
|
Align
|
alClient
|
|
|
Name
|
PageControl1
|
2.2 多页控制的页设计
多页控制组件是多页对话窗口设计的关键所在,本例划分ARJ命令、开关选项、附加选项、压缩文件等4个页面,在有限的界面内容纳了尽可能多的界面元素,简化了操作。要创建一个新的页面或在页面之间进行切换,可以使用快捷菜单来完成。当多页控制选中时,单击鼠标右键,弹出一个快捷菜单,菜单最顶上的3项分别是:创建新页(New Page)、下一个页面(Next Page)、上一个页面(Previous Page)。表4列出了4个页面上各个组件的创建属性。
表4 页面及其所含组件的创建属性
|
页面名称
|
组件名
|
属性名
|
取值
|
|
|
TabSheet
|
Caption
|
命令
|
|
|
|
Name
|
CommandTabSheet
|
|
命令
|
ListBox
|
ExtendedSelect
|
False
|
|
|
|
Name
|
CommandListBox
|
|
|
TabSheet
|
Caption
|
开关选项
|
|
|
|
Name
|
SwitchTabSheet
|
|
开关选项
|
ListBox
|
ExtendedSelect
|
False
|
|
|
|
Name
|
SwitchListBox
|
|
|
Tabsheet
|
Caption
|
附加选项
|
|
|
|
Name
|
ShiftSwitchTabSheet
|
|
附加选项
|
ListBox
|
ExtendedSelect
|
False
|
|
|
|
Name
|
ShiftSwitchListBox
|
|
|
TabSheet
|
Caption
|
压缩文件
|
|
|
|
Name
|
SelectFileTabSheet
|
|
压缩文件
|
Label
|
Caption
|
文件:
|
|
|
|
Name
|
Label1
|
|
压缩文件
|
Label
|
Name
|
Label2
|
|
压缩文件
|
Label
|
Caption
|
驱动器:
|
|
|
|
Name
|
Label3
|
|
压缩文件
|
Label
|
Caption
|
压缩文档名:
|
|
|
|
Name
|
Label4
|
|
压缩文件
|
Edit
|
Name
|
FilenameEdit
|
|
|
|
Text
|
*.*
|
|
压缩文件
|
FileListBox
|
FileType
|
[ftReadOnly,ftArchive,ftNormal]
|
|
|
|
Mask
|
*.*
|
|
|
|
MultiSelect
|
True
|
|
|
|
Name
|
FileListBox1
|
|
压缩文件
|
DirectoryListBox
|
DirLabel
|
Label2
|
|
|
|
FileList
|
FileListBox1
|
|
|
|
Name
|
DirectoryListBox1
|
|
压缩文件
|
DriveComboBox
|
DirList
|
DirectoryListBox1
|
|
|
|
Name
|
DriveComboBox1
|
|
|
|
TextCase
|
tcUpperCase
|
|
压缩文件
|
Edit
|
Name
|
ArjNameEdit
|
为了节约篇幅,每个组件的位置和大小均未列出,读者可以参照图1所示的示意窗体合理安排各个组件的位置并调整其大小,使窗口既实用又美观。
2.3 为列表框预设选项
在命令、开关选项、附加选项三个页面上分别分布着一个列表框,由于ARJ的命令和各种选项是固定的,因此可以将ARJ的这些命令或选项预先赋予列表框的Items属性,从而达到简化编程的目的。设定Items类型的属性是通过一个字符串列表编辑器进行的。选中列表框组件,单击Object
Inspector中Items属性右边的
按钮,弹出字符串列表编辑器。(如果你认为这个编辑器不够灵活,可以单击“Code
Editor...”按钮,切换到代码编辑器中进行编辑。)编辑完毕,单击〖Ok〗按钮即可。
3 Windows
API函数的使用
DELPHI为许多Windows
API函数提供了接口单元,通过这些单元,使得DELPHI程序可以直接调用Windows API函数,以得到灵活控制Windows的目的。本讲的WinArj程序使用了ShellAPI中的ShellExecute函数,以实现在该程序中启动ARJ.EXE程序的目的。下面简要介绍ShellAPI单元和ShellExecute函数。
ShellAPI单元使一个Windows应用程序可以组织、启动或其他方法控制别的应用程序。ShellExecute函数能够打开或者打印一个指定的文件,也就是说这个文件可以是可执行文件也可以是文档文件,其定义如下:
function ShellExecute(hWnd: HWND; Operation, FileName,
Parameters,
Directory:
PChar; ShowCmd: Integer): HINST;
其中,hWnd是一个HWND(LongInt)类型的句柄(数),代表父窗口;Operation、FileName、Parameters、Directory都是Pchar类型的参数,Operation可以取“Open”或“Print”,Parameters指命令行参数,Directory指工作目录;ShowCmd为一个Integer类型的参数,其取值请参阅联机帮助。如果FileName指定一个文本文件,ShowCmd应当为零。
若要在一个单元中使用Windows
API函数,必须在这个单元中用Uses语句说明包含API函数的系统单元,否则DELPHI会给出编译错误。比如在该程序中使用了ShellExecute函数,必须在单元的实现部分的开始加上一条Uses语句:
Uses ShellAPI;
4 程序的运行版本
通过上述工作,窗体及其所含组件的创建属性已经设计好了,下一步是为各个组件编制事件处理程序,使这些组件有机地结合起来,协同工作,完成构造ARJ命令行参数的工作。
4.1 列表框的处理
命令、开关选项、附加选项3个页面上的列表框都是单选列表框,当选中某一列表项,只要双击该选项就可以将该项添加到命令行编辑框中。完成这项功能的OnDblClick事件处理程序如下:
procedure TWinArjForm.CommandListBoxDblClick(Sender:
TObject);
begin
with CommandListBox,CommandLineEdit do
if ItemIndex <> -1 then begin
Text := Items.Strings[ItemIndex][1];
UpdatePageControl;
end;
end;
procedure
TWinArjForm.SwitchListBoxDblClick(Sender: TObject);
begin
with SwitchListBox,CommandLineEdit do
if ItemIndex <> -1 then
Text := Text + ' -' +
SwitchString(Items.Strings[ItemIndex]);
end;
procedure
TWinArjForm.ShiftSwitchListBoxDblClick(Sender: TObject);
begin
with ShiftSwitchListBox,CommandLineEdit do
if ItemIndex <> -1 then
Text := Text + ' -' +
SwitchString(Items.Strings[ItemIndex]);
end;
由于开关选项和附加选项的列表项不规则,所以需要对选项字符串进行分析,截取其中有效的部分,所以在TWinArjForm类的Private部分添加一个私有方法声明:
function SwitchString(SrcStr : string) : string;
在单元的实现部分对函数定义如下:
function
TWinArjForm.SwitchString(SrcStr : string) : string;
var
i : integer; TempStr : string;
begin
if SrcStr <> '' then begin
i := 1;
repeat
if SrcStr[i] = ' ' then inc(i);
until SrcStr[i] <> ' ';
TempStr := '';
repeat
TempStr := TempStr + SrcStr[i];
inc(i);
until SrcStr[i] = ':';
end;
SwitchString := TempStr;
end;
4.2 多页动态对话窗口的实现
要实现多页动态对话窗口,就需要根据当前程序执行的状态更改程序的界面,为了实现这一功能,在TWinArjForm类的Private部分添加一个私有方法声明:
procedure UpdatePageControl;
在单元的实现部分完成该方法的具体定义:
procedure
TWinArjForm.UpdatePageControl;
begin
with CommandTabSheet do begin
Visible := not Visible;
TabVisible := not TabVisible;
SwitchTabSheet.Visible := not Visible;
SwitchTabSheet.TabVisible := not TabVisible;
if Visible then begin
PageControl1.ActivePage :=
CommandTabSheet;
CommandLineEdit.Text := '';
end
else
PageControl1.ActivePage :=
SwitchTabSheet;
ShiftSwitchTabSheet.Visible := not Visible;
SelectFileTabSheet.Visible := not Visible;
ShiftSwitchTabSheet.TabVisible := not
TabVisible;
SelectFileTabSheet.TabVisible := not TabVisible;
OkBitBtn.Enabled := not Visible;
end;
end;
4.3 按钮的OnClick事件处理
4个按钮的OnClick事件处理程序,除了OkBitBtn的稍微有些