zoukankan      html  css  js  c++  java
  • 一个简单的MDI示范程序(Delphi)

    最为一个巩固之前有关窗体和对象的有关知识,下面就建立一个简单的MDI示范程序,这个程序的功能是打开和保存图形文件(包括位图、图标等),为了完成这个任务,我们有一个大概的计划,计划内容如下:

    (1)建立主窗体(一个MDI父窗体),包括菜单。

    (2)为【File | Open…】 和【File | Save…】菜单选项编写代码。

    (3)为Windows菜单上的Cascade、Tile和Arrange All选项编写代码。

    (4)建立MDI子窗体。

    (5)建立一个About对话框。

    (6)然后再回忆和欣赏一下这段工作。

    时间就是金钱,即刻就做吧 。

    一、创建主窗口窗体

    首先创建一个主窗口窗体,一个MDI应用程序的主窗口的FormStyle属性必须设置为fsMDIForm。不但要为应用程序增加File Open和 File Save 对话框,还要增加一个菜单。

    1、启动Delphi,并从主菜单选择【File | New | Application】;

    2、把主窗体的Name属性设置为MainForm

    image

    3、把Caption属性设置为Picture Viewer

    image

    4、把FormStyle属性设置为fsMDIForm

    image

    好了,下面为此窗体增加一个菜单,利用Delphi特性,引进一个预定义菜单,具体如下:

    1、点击组件选项板的Standard标签,并点击MainMenu按钮;

    image

    2、把MainMenu组件点击放置到窗体上,具体放到哪个地方无所谓了,因为在运行阶段,代表菜单的图标只是占地方而不显示,这是非可视化组件。

    image

    3、把MainMenu组件Name属性改为MainMenu

    image

    4、双击MainMenu组件,就会出现Menu Designer对话框;

    0090

    5、在MainMenu上点击鼠标右键,选择“Insert From Template…”,将出现Insert Template对话框;

    0091

    6、选择“MDI Frame Menu”并点击OK,此菜单将显示在Menu Designer上,关闭Menu Designer窗口。

    现在又回到了主窗体,注意现在窗体上多了一条菜单,此时先不要点击任何子菜单项,我们先准备File Open对话框和File Save对话框:

    1、点击组件选项板的Dialogs标签,选择Open Picture Dialog组件,并把它放到窗体上,这也是一个非可视组件。

    image

    2、把Open对话框的Name属性改为OpenPictureDialog

    image

    3、把Open对话框的Title属性改为“Open a Picture for Viewing”;

    image

    4、在窗体再增加一个Save Picture Dialog组件;

    image

    5、把此组件的Name属性改为“SavePictureDialog”,把Title属性改为“Save a Picture”;

    image

    image

    此时窗体看起来应该像下图:

     0092

    二、编写【File | Open…】和【File | Save As…】菜单选项代码

    下面就准备开始编写代码,Delphi提供了一种很好地编写菜单处理程序的方法,从而使遇到的麻烦最小。还不要建立MDI子窗体,但要充分了解它,并用它来为菜单处理程序编写代码,记住在建立MDI子窗体之前一直不要编译应用程序(因为还没有建立MDI子窗体,编译会出现错误的)

    1、在主窗体上选择【File | Open…】菜单项,这样就会在Code Editor中为此菜单项建立一个事件处理程序。

    2、为此事件处理程序键入下列代码:

    procedure TMainForm.Open1Click(Sender: TObject);
    var
      Child: TChild;
    begin
      if OpenPictureDialog.Execute then
      begin
        Child := TChild.Create(Self);
        with Child.Image.Picture do
        begin
          LoadFromFile(OpenPictureDialog.FileName);
          Child.ClientWidth := Width;
          Child.ClientHeight := Height;
        end;
        Child.Caption := ExtractFileName(OpenPictureDialog.FileName);
        Child.Show;
      end;
    end;

    这段代码首先打开一个“Open a Picture for Viewing”对话框,并得到一个文件名,如果点击这个对话框的OK按钮,就会产生一个TChild对象(TChild是MDI子类的名字,后面将要建立它。)图像文件被显示到窗体上的Image组件,并且MDI子窗口将会与图像大小相匹配,最后子窗体的标题会显示被选中的图像文件名。

    Note

    在上面的方法中,ExtractFileName函数是用来从路径中提取文件名的函数,文件名包含在OpenPictureDialog的FileName属性中,相关的函数包括ExtractFilePath、ExtractFileDir、ExtractFileDrive和ExtractFileExt。

    Note

    前面我们说过所有动态创建的对象到最后都要用Free删除掉,但是上面的代码中好像违反了这个规律,实际上并没有,因为VCL将负责释放分配给MDI子窗口的内存。注意TChild构造程序中的单个参数是Self;这是通知VCL,MDI子窗体的拥有者就是此MDI窗体窗口。当MDI窗体消失时,它将删除所有MDI子对象。

    3、按下F12键,切换到主窗体MainForm,现在从菜单中选择【File | Save As…】,将会显示该菜单项处理事件。

    4、键入以下代码:

    procedure TMainForm.SaveAs1Click(Sender: TObject);
    begin
      if SavePictureDialog.Execute then
      begin
        with ActiveMDIChild as TChild do
        { 检查MDI子窗体是否被激活,只保存激活窗体的图像文件}
          Image.Picture.SaveToFile(SavePictureDialog.FileName);
      end;
    end;

    这段代码比较简洁,头两行是用来检查MDI子窗口是否被激活,如果是激活的窗体,就会显示“Save a Picture”对话框,若用户点击OK,那就将用TPicture类的SaveToFile方法把图像存到盘上去。

    Note

    前面的这段代码中用到了as操作符,ActiveMDIChild属性返回一个指向TForm对象的指针,在这种情况下,实际上只需要一个指向TChild对象的指针(MDI子类是从TForm类派生来的),as操作符把ActiveMDIChild变量强制转化为一个TChild指针,如果as不能完成这种强制转化,as后面的语句将被忽略。

    在继续讲解前,我们先把这个工程保存起来,将Unit1保存为PctViewU.pas,将工程文件dpr保存为PictView。

    三、为【Windows】菜单编写代码

    1、F12切换到MainForm窗体上,从窗体上MainMenu菜单上选择【Windows | Tile】;

    2、只需要为此事件处理程序中输入一行代码即可,最终的事件处理代码如下:

    procedure TMainForm.ile1Click(Sender: TObject);
    begin
      Tile;
    end;

    3、切换到MainForm窗体,并为菜单【Windows | Cascade】创建代码,如下:

    procedure TMainForm.Cascade1Click(Sender: TObject);
    begin
      Cascade;
    end;

    4、切换到MainForm窗体,再次为菜单【Windows | Arrange All】创建代码如下:

    procedure TMainForm.ArrangeAll1Click(Sender: TObject);
    begin
      ArrangeIcons;
    end;

    好,主窗体工作完成了,下面将进行创建MDI子窗体。

    四、创建MDI子窗体

    MDI子窗体非常简单,实际上不必写任何代码,只要操作下列各步即可:

    1、用工具栏上的New Form按钮或者通过主菜单上的【File | New Form】来创建一个新窗体;

    2、把它的Name属性设置为Child,Caption属性将被忽略,因为在运行阶段将要动态设置此属性;

    image

    3、把FormStyle属性设置为fsMDIChild,为了把这个窗体当做MDI子窗体来处理,这是必须的。

    image

    为窗体本身要做的就这些,下面就在此窗体上放置一个Image组件,Image组件将显示用户选择的图形文件。

    1、点击组件选项板上的Additional标签,点击Image按钮,并把它放置到Child窗体上;

    image

    2、把它的Name属性设置为Image

    image

    3、把它的Stretch属性设置为True

    image

    4、把它的Align属性设置为alClient,Image组件将缩放到窗体的客户区大小;

    image

    5、选择Delphi主菜单的【File | Save】,以MDIChild保存此窗体单元。

    6、切换到Code Editor,点击PctViewU标签,然后从Delphi主菜单选择【File | Use Unit】,选择MDIChild单元,点击OK,这样该工程就可以编译了。

    此时,整个MDI子窗体看上去如下:

    0093

    我们的程序还没有完成,因为还差一个About框,此时我们更渴望看到程序的运行,先点击Run按钮,就可以运行程序了,选择【File | Open…】就可以打开任何图形文件了。

    注意MDI子窗口会自动缩放它所包含的图形,打开几个文件,然后试一试Window菜单的Cascade和Tile选项。

    五、建立About对话框

    到目前为止,我们自己随意建立一个属于自己的About框,我的About对话框效果如下:

    image

    1、将建立好的About窗体的Name属性设置为AboutBox,BorderStyle属性设置为bsDialog

    image

    image

    2、以PVAboutU保存此About对话框窗体单元;

    3、切换到Code Editor中的PctViewU标签,从Delphi主菜单选择【File | Use Unit】将PVAboutU单元包含近来;

    4、按F12切换到MainForm主窗体,从菜单上选择【Help | About】,这样就产生一个OnClick处理事件;

    5、为此事件添加代码如下:

    procedure TMainForm.About1Click(Sender: TObject);
    begin
      AboutBox.ShowModal;
    end;

    现在运行它,点击Run按钮,试一试Help菜单的About选项,运行效果如下:

    0094

    六、进一步完善程序

    此时这个程序已经可以运行了,但它不等于就没有值得完善的地方。

    对于这个程序还有两个问题需要值得注意,它们容易混淆,首先,当启动该程序时,会显示一个空白MDI子窗口,这是因为Delphi应用程序会自动建立所有窗体。我们可以从自动产生的清单中删除MDI子窗体。

    1、从Delphi主菜单中选择【Project | Options…】,将显示Project Option对话框;

    0095

    2、点击Forms标签,其中“Auto-create forms”中显示的就是所有会自动创建产生的窗体清单;

    3、点击其中不想要自动创建的窗体Child,选择 >按钮,就会从自动创建列表中删除该子窗口,并把它放置到“Available forms”列表中。

    再次运行此程序,这一次将不显示空白MDI子窗体。

    Caution

    如果要从自动产生清单中删除一个窗体,就必须保证在用它之前要建立一个专门的窗体,如果不建立一个窗体,指向窗体的指针就不能初始化,这就意味着还没有为此指针赋一个有意义的值(记住指针是由Delphi自动产生)。试图用这个指针,其结果将会产生一个非法错误,当从自动产生清单中删除一个窗体后,就必须负责在用它之前建立它。

    还有一个问题,就是在MDI窗体上点击关闭按钮时,发现子窗口并没有关闭,而是最小化,因此我们要修改它,使得点击关闭后真正被关闭。

    1、在Form Designer中选择Child子窗体,选中窗体本身,确认在Object Inspector的Component Selector中选择的是Child。

    2、双击Events页的OnClose事件,添加代码如下:

    procedure TChild.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := caFree;
    end;

    把关闭动作设置为caFree,指示VCL关闭子窗体,并释放与窗体有关的内存,这时点击MDI子窗体关闭按钮就可以正常关闭了。

    4、再次运行此程序,证明此程序的表现与前面所述的一样。

    以上代码均在Delphi7中测试通过,示例代码下载:一个简单MDI应用程序.rar

  • 相关阅读:
    关于返回上一页功能
    Mybatis Update statement Date null
    SQLite reset password
    Bootstrap Validator使用特性,动态(Dynamic)添加的input的验证问题
    Eclipse使用Maven2的一次环境清理记录
    Server Tomcat v7.0 Server at localhost failed to start
    PowerShell一例
    Server Tomcat v7.0 Server at libra failed to start
    商标注册英语
    A glance for agile method
  • 原文地址:https://www.cnblogs.com/pchmonster/p/2316012.html
Copyright © 2011-2022 走看看