Programming and Application(编程与应用)


Content(目录)




Linux


MySQL
Office















 
PCNow 30-Day Free Trial, Remote PC Access
 
Logo_234x60

第五讲 多文档界面(MDI)应用程序的创建
DELPHI程序设计讲座(五)

多文档界面(MDI)应用程序的创建

董占山
(中国农科院棉花所,河南安阳,455112)

本讲重点介绍多文档界面应用程序的开发方法,并选择性地介绍了Dialogs和Win95组件页上的组件以及右键弹出菜单的设计方法。

1.相关组件页概述

本讲提供的样例程序主要用到了Windows的标准对话框、富格式文本编辑组件,分别在Dialogs和Win95组件页上。

1.1 Dialogs组件页

Dialogs组件页上的组件是一类很常用的组件,它们封装了Windows 系统的标准对话框,使在DELPHI中使用这些Windows 标准对话框变得简单易行。该组件页包括了8个对话组件,见 表1所示。本讲将使用并讲解OpenDialog和SaveDialog 两个组件。

表1. Dialogs组件页上的组件

图标 名称 功能
OpenDialog 打开文件对话窗口
SaveDialog 保存文件对话窗口
FontDialog 设定字体对话窗口
ColorDialog 设定颜色对话窗口
PrintDialog 打印对话窗口
PrinterSetupDialog 设定打印机属性对话窗口
SearchDialog 查找对话窗口
ReplaceDialog 查找并替换对话窗口

1.2 Win95组件页

Win95组件页上的组件是针对Windows 95的界面风格设计的,包括几个十分常用的组件,如多页控制、状态栏、进度条、增减按钮等组件,详见 表2所示。本讲将用到富格式文本编辑组件。

>表2 Win95组件页上的组件

图标 名称 功能
TabControl 设计可单击标签控制
PageControl 用来设计多页对话框
> TreeView 设计树形选项列表
ListView 设计可以用多种方式显示的选项列表
ImageList 创建一个可容纳多个同尺寸的图象列表
HeaderControl 设计标题(头)
RichEdit 富格式文本编辑控制
StatusBar 状态栏
TrackBar 跟踪栏
ProgressBar 处理进度条
UpDown 增减按钮
HotKey 设计快捷键

2   创建一个MDI应用程序

Delphi 2.0提供了完善的窗体和程序设计模板,对复杂的窗体和程序,使用模板可以显著地提高应用程序的开发效率。下面以开发一个具有MDI 界面的文本编辑器为例,介绍如何使用程序设计模板。

图1   创建新项目对话窗口

(1) 单击“File/New”,打开“New Items”对话窗口,切换到“Projects”对话页,如 图1 所示;

(2) 选中“MDI Application”图标,单击〖OK〗按钮,弹出选择文件夹对话窗口,如 图2 所示;

(3) 在目录名编辑框中直接输入一个目录名,如果目录不存在,Delphi 会按指定的名称创建一个目录;

(4) 单击〖OK〗按钮,系统自动创建主窗体和子窗体及其相关的PASCAL 单元等,新创建的主窗体如 图3所示。

图2   设定新项目所在目录对话窗口

图  新创建的缺省MDI主窗体

如果你打开代码编辑窗口,可以看到DELPHI 已经为多数菜单选项、加速按钮创建了必要的事件处理程序。下面以这个MDI程序的框架为基础,一步一步创建一个简单的富格式文本编辑器。

3   改造主窗体

Delphi创建的MDI程序框架的主窗体已经包括了许多内容,有主菜单、菜单选项及其事件处理程序、工具栏及加速按钮、状态栏、一个打开对话组件,这些内容对我们创建MDI 界面的文本编辑器都是必须的。下面我们分几个部分讲解如何完善主窗体。

3.1     向工具栏添加加速按钮

在工具栏上已有6个加速按钮,自左至右分别是打开、保存、剪切、复制、粘贴、关闭。对一般编辑器的工具栏来讲,还应当有一个创建新文档的加速按钮。下面以向工具栏添加一个创建新文档的新建按钮为例介绍如何创建加速按钮。

加速按钮组件在附加组件页(Additional )上,在组件板上选取加速按钮后,将鼠标移到主菜单下面的Panel组件上,在打开按钮的左边单击,放置一个空白的加速按钮,调整各个按钮的位置,使Panel 组件上的7个加速按钮合理布置。新创建的SpeedButton 的属性见 表3。

表3   SpeedButton的创建属性

属性名 取值
Height 31
Hint New|
Name NewBtn
Width 31

到现在为止,这个加速按钮还是一个白板,需要给它赋予一个图象,方法如下:

(1) 双击“Glyph”属性的右半部,弹出类似 图4 的窗口;

图4   图片编辑窗口

(2) 单击〖Load〗按钮,弹出一个打开对话窗口,将文件目录指向“Delphi 2.0\Images\Buttons”,在这个目录下DELPHI提供了许多Bitmap 图象文件,选中“FileNew.bmp”;

(3) 单击〖确定〗按钮将图片装载到图片编辑窗口;

(4) 单击图片编辑窗口的〖OK〗按钮完成。

现在你可以看到这个加速按钮已经拥有了漂亮的外观。这个按钮的功能和主菜单中的“New ”选项一致,所以,将这个加速按钮的OnClick事件处理程序指向FileNewItemClick 即可。方法很简单,单击Object Inspector窗口的“Events ”标签,切换到设定事件处理程序的对话页,单击OnClick的右编辑框中的下箭头钮,弹出一个下拉列表框,选中“FileNewItemClick ”即可。

3.2   为窗体增加右键弹出菜单

为了在编辑窗口中可以使用右键弹出菜单,在主窗体中增加一个PopupMenu 组件,其属性均使用系统创建时的缺省值,使用菜单设计对话窗口,向其中增添3个菜单选项,其名称和属性和事件处理程序见 表4 。

表4   主窗体PopMenu1菜单选项的创建属性

标题(Caption) 标识名称(Name) 事件处理程序(OnClick)
Cu&t CutItem1 CutItemClick
&Copy CopyItem1 CopyItemClick
&Paste PasteItem1 PasteItemClick

3.3   添加保存对话组件

对文档窗口中的文本进行修改之后,为了能够将修改好的文本保存到磁盘文件中,必须给文档命名并指定路径,这些任务可以由保存对话组件完成,为此需向主窗体添加一个保存对话组件SaveDialog 。把它添加到主窗体后,按 表5进行属性设置。

表5  SaveDialog组件设计属性

属性名 取值
FileEditStyle fsComboBox
Filter 富格式文本 (*.rtf)|*.rtf|文本文件 (*.txt)|*.txt|所有文件|*.*
Name SaveDialog
Title 保存

4    文本编辑窗体的设计

单击“View/Project Manager ”菜单选项,弹出项目管理窗口,选中ChildWin列表项,单击〖View Form〗按钮,打开MDI子窗体,这是设计文本编辑窗口的起点。

4.1    向窗体添加编辑组件

为了使子窗体能够完成富格式文本编辑功能,需要向窗体添加一个位于Win95 组件页上的RichEdit编辑组件,其属性设置见 style='mso-field-code:"REF _Ref398903614 \\* MERGEFORMAT"'>表6 。再双击Object Inspector窗口中的Lines 属性的右半部,进入串编辑窗口,将其中的内容清空,单击〖OK〗按钮返回。

表6  RichEdit组件的设计属性

属性名 取值
Align alClient
Name Editor
PopupMenu MainForm.PopupMenu1
ScrollBars ssVertical
Wordwrap TRUE

4.2    完善文本编辑窗体

DELPHI已经为MDIChild子窗体设置了FormClose 事件处理程序,但是当子窗口关闭前,需要检查一下其上的文本是否已经改变,如果改变了并且没有保存,弹出提示窗口,让用户确认是否保存文本。通过FormCloseQuery 事件处理程序可以达到这个目的。

在设计FormCloseQuery事件处理程序之前,还需要在TMDIChild 类声明的Public部分添加与此文本编辑窗口相关联的文件名串变量:

PathName: string;

FormCloseQuery事件处理程序如下:

procedure TMDIChild.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
Const
  SWarningText = 'Save changes to %s?';
begin
  if Editor.Modified then
  begin
    case MessageDlg(Format(SWarningText,[PathName]),mtConfirmation,
      [mbYes,mbNo,mbCancel],0) of
      idYes     : MainForm.FileSaveItemClick(Self);
      idCancel : CanClose := False;
    end;
  end;
end;

在这个事件处理程序中,调用了主窗体中的FileSaveItemClick 事件处理程序,所以在单元中要声明使用主窗体单元Main;另外,Format 是Object Pascal的一个系统函数,在SysUtils 中定义,MessageDlg是在Dialogs 单元中定义的一个窗口函数,所以在这个单元的实现部分,应当添加一条使用单元的声明语句:

uses Main, SysUtils, Dialogs

5    进一步完善主窗体

文本编辑窗体设计完成后,下一步的工作是进一步完善主窗体的事件处理程序,以实现对文本编辑窗体的操纵,来完成文档的打开、编辑、保存等功能。首先在实现部分的开头加上:

Uses MDIChild;

5.1    编辑功能的实现

要实现文本的编辑功能,主要是设计Edit 菜单中各个功能选项的OnClick事件处理程序。下面是Cut 、Copy和Paste三个菜单选项的OnClick 事件处理程序。这个菜单的所有操作均是对活动文档子窗口而言的。

procedure TMainForm.CutItemClick(Sender: TObject);
begin
  if ActiveMDIChild <> nil then
    TMDIChild(ActiveMDIChild).Editor.CutToClipboard;
end;
procedure TMainForm.CopyItemClick(Sender: TObject);
begin
  if ActiveMDIChild <> nil then
    TMDIChild(ActiveMDIChild).Editor.CopyToClipboard;
end;
procedure TMainForm.PasteItemClick(Sender: TObject);
begin
  if ActiveMDIChild <> nil then
    TMDIChild(ActiveMDIChild).Editor.PasteFromClipboard;
end;

5.2    实现编辑菜单的动态感知功能

如果当前文档中选定了文本,那么可以使用Cut 和Copy选项,否则,应当禁止使用;如果剪贴板上有文本存在,可以使用Paste 选项,否则,应禁止使用。为了在打开编辑窗口时,能够动态地设定菜单选项的可用状态,为Edit 菜单创建一个OnClick事件处理程序,以完成这项功能。同时,也要把PopupMenu1 的OnClick事件处理入口指向它。

procedure TMainForm.Edit1Click(Sender: TObject);
Var
   HasSelection : Boolean;
begin
  PasteItem.Enabled := Clipboard.HasFormat(CF_TEXT);
  PasteItem1.Enabled := PasteItem.Enabled;
  HasSelection := False;
  if ActiveMDIChild <> nil then
    HasSelection := TMDIChild(ActiveMDIChild).Editor.SelLength > 0;
  CutItem.Enabled := HasSelection;
  CopyITem.Enabled := HasSelection;
  CutItem1.Enabled := HasSelection;
  CopyITem1.Enabled := HasSelection;
end;

在这段程序中,为了检查剪贴板上是否有文本存在,使用了Clipboard 函数,这个函数的定义在Clipbrd单元中,所以在本单元的实现部分的uses 语句中加上Clipbrd单元。

5.3    文件的打开和保存功能的实现

为了在创建一个新文档时,给文件起一个默认的名字,用来标记文档子窗口,在单元的实现部分添加一个字符串类型常量:

Const

  DefaultFileName : String = 'NONAME';

文件菜单的新建(New)选项的OnClick 事件处理程序如下:

procedure TMainForm.FileNewItemClick(Sender: TObject);
var
  Child: TMDIChild;
  Name : string;
begin
  Name := DefaultFileName + IntToStr(MDIChildCount + 1);
  Child := TMDIChild.Create(Application);
  Child.Caption := Name;
  Child.PathName := Name;
end;
对DELPHI自动创建的CreateMDIChid 私有方法进行必要的修改,将它用于创建一个文档子窗口并打开指定的文档填充文本编辑器。
procedure TMainForm.CreateMDIChild(const Name: string);
var
  Child: TMDIChild;
begin
  Child := TMDIChild.Create(Application);
  Child.Caption := ExtractFileName(Name);
  Child.PathName := Name;
  with Child.Editor do begin
    Lines.LoadFromFile(Child.PathName);
    SelStart := 0;
    Modified := False;
  end;
end;

DELPHI自动创建的“Save”和“Save as”菜单项的OnClick事件处理程序为空,需要设计者完成具体功能。本例中二者的OnClick 事件处理程序如下:

procedure TMainForm.FileSaveItemClick(Sender: TObject);
begin
  if ActiveMDIChild <> nil then
    with TMDIChild(ActiveMDIChild) do begin
      if pos(DefaultFileName,PathName) <> 0 then
        FileSaveAsItemClick(Sender)
      else begin
        Editor.Lines.SaveToFile(PathName);
        Editor.Modified := False;
      end;
  style="mso-spacerun: yes">   end;
end;
procedure TMainForm.FileSaveAsItemClick(Sender: TObject);
begin
  if ActiveMDIChild <> nil then
    with TMDIChild(ActiveMDIChild) do begin
      SaveDialog.FileName := PathName;
      if SaveDialog.Execute then begin
        PathName := SaveDialog.FileName;
        Caption := ExtractFileName(PathName);
        FileSaveItemClick(Sender);
      end;
    end;
end;

至此,一个初级多文档界面的文本编辑器已经设计好了,如果打入程序时没有键入错误,单击[F9] 键就可以编译并运行它。这个文本编辑器比Windows提供的Notepad 还要高级一些。由此可知:对DELPHI来讲,设计一个实用的MDI 程序是相当简单的。

©董占山Zhanshan Dong

Post comments(留言)

Name(名字):

Comment(内容):


由Google提供

SunfineData Products|U's Bargain Network|Contact Me(与我联系)
© 1998-, 董占山, 版权所有, 欢迎转载文章链接。
转载文章和软件请注明出处(http://articles.sunfinedata.com/)。