BLOG中写了份文章,但一直没什么人气,所以贴到这里来,大家请帮忙看看,谢谢原地址 http://blog.csdn.net/flexitime/archive/2008/02/11/2088103.aspx
---------------------------1.5 改造主窗体的代码
在上一节中我们通过创建一个子窗体的父窗体来规范和简化子窗体的代码,但我们却为此使得主窗体的代码增加了不少,而且要创建一个子窗体时还要增加不少的代码。这样的效果还不是我们想得到的。现在让我们来看看如何来简化主窗体的代码 procedure TfrmMain.mnFormCClick(Sender: TObject);var  frm : TCustomChildForm;             begin  frm := SearchMDIChild(Sender);  if  frm = nil then    begin      frm := TfrmChildC.Create(Application);  //注一      AddMDIChildList(Sender, frm);    end;  frm.Show;end;对于每一个不同的子窗体,只是(注一)的代码有所不一样而已,因此要简化这个过程,我们必须要解决这个不同的地方。但这里有别于一般的情况,这里会改变的地方是一个“类对象”,因此我们要解决的是处理类对象的变量。我们可以参考一下 MDI_Tutorial.dpr中,我们经常删除掉的代码:Application.CreateForm(TfrmChildD, frmChildD);在这行代码中,CreateForm函数能把类作为函数,并将其创建成一个实例,最后赋值给一个变量,我们如果也能实现类似的函数就可以解决我们遇到的问题了我们看一下CreateForm是如果工作的,打开VCL中的Forms.pas,找到以下函数procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);var  Instance: TComponent;begin  Instance := TComponent(InstanceClass.NewInstance);  TComponent(Reference) := Instance;  try    Instance.Create(Self);  except    TComponent(Reference) := nil;    raise;  end;  if (FMainForm = nil) and (Instance is TForm) then  begin    TForm(Instance).HandleNeeded;    FMainForm := TForm(Instance);  end;end; 红色的地方就是我们想要的内容,我们参照上面的代码,可以写出以下的代码: TCustomChildFormClass = class of TCustomChildForm;……function TfrmMain.CallChildFrom(Sender: TObject;  AClass: TCustomChildFormClass): TCustomChildForm;begin  result := SearchMDIChild(Sender);  if result = nil then    begin      result := TCustomChildForm (AClass.NewInstance);      result.Create(Application);      AddMDIChildList(Sender, result);    end;  result.Show;end; procedure TfrmMain.mnFormCClick(Sender: TObject);begin  CallChildFrom(Sender, TfrmChildC);end; 至此,我们就简化了每一个Form的创建代码了,这样十分有利于我们新加窗体的显示,但现在主窗体看起来也十分杂乱,我们也采用与子窗体类似的方式,创建一主窗体的父窗体的方式去把这样控制代码进行划分,这样就不会杂乱了。我们把MainForm.pas另存为 MainFormDefine.pas,然后将这个frmMain改名为CustomMainForm,改好后就重新派生一个frmMain出来,可以用:File->New->Other->Inheritable Items->CustomChildForm最后在MDI_Tutorial.pas中将 Application.CreateForm(TCustomMainForm, CustomMainForm);语句删除,这样就可以了。同样,可能你会觉得现在那些文件位置放得不甚理想,所以我们在文件目录中再创建一个common的文件夹,把MainFormDefine.pas 及 ChildFormDefine.pas 都放进去,这样就不会影响整个目录的结构了。

解决方案 »

  1.   

    谢谢您的意见,
    只是觉得,有点问题,
    现在用Delphi来写数据库管理方面的软件应该还有在用MID方式吧。
    我这些方法其实是我写了好几个程序之后才总结出来的,以前我真的不知怎样控制好MID主窗体与子窗体的关系,在我而言,我觉得这篇文章起码对很多刚进门的同道们会有用的。
    最后,还是谢谢您的支持。
      

  2.   

    谢谢您的意见, 
    只是觉得,有点问题, 
    现在用Delphi来写数据库管理方面的软件应该还有在用MDI方式吧。 
    我这些方法其实是我写了好几个程序之后才总结出来的,以前我真的不知怎样控制好MDI主窗体与子窗体的关系,在我而言,我觉得这篇文章起码对很多刚进门的同道们会有用的。 
    最后,还是谢谢您的支持。
      

  3.   

    CallChildFrom(Sender, TfrmChildC); 
    这种方式创建代码会造成主窗体包含了大量的子窗体引用,建议你思考另一种做法:var
      Child: TChildForm; //自定义基类
    begin
      Child := CallChildFrom('TfrmChildC', Self); 
    end;这样就不会出现大量的引用,也方便你未来将TfrmChildC封装到bpl甚止dll中.而若要使用TfrmChildC上某一个TButton的方法,可以使用类似如下的方法:(Child.GetControl('Button1') as TButton).Click;以上经验,供大家参考。