使用MID的方法


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 都放進去,這樣就不會影響整個目錄的結構了。

7 个解决方案

#1


up

#2


無奈中,自己頂一下~~~

#3


挺不錯!不過好像沒有什么實際意義!至少是對大多數人來說!
如果樓主貼點對大多數人有用東西,頂貼的人就會很多!
最后說一句:方法確實挺好!

#4


謝謝您的意見,
只是覺得,有點問題,
現在用Delphi來寫數據庫管理方面的軟件應該還有在用MID方式吧。
我這些方法其實是我寫了好幾個程序之后才總結出來的,以前我真的不知怎樣控制好MID主窗體與子窗體的關系,在我而言,我覺得這篇文章起碼對很多剛進門的同道們會有用的。
最后,還是謝謝您的支持。

#5


謝謝您的意見, 
只是覺得,有點問題, 
現在用Delphi來寫數據庫管理方面的軟件應該還有在用MDI方式吧。 
我這些方法其實是我寫了好幾個程序之后才總結出來的,以前我真的不知怎樣控制好MDI主窗體與子窗體的關系,在我而言,我覺得這篇文章起碼對很多剛進門的同道們會有用的。 
最后,還是謝謝您的支持。

#6


CallChildFrom(Sender, TfrmChildC); 
這種方式創建代碼會造成主窗體包含了大量的子窗體引用,建議你思考另一種做法:

var
  Child: TChildForm; //自定義基類
begin
  Child := CallChildFrom('TfrmChildC', Self); 
end;

這樣就不會出現大量的引用,也方便你未來將TfrmChildC封裝到bpl甚止dll中.

而若要使用TfrmChildC上某一個TButton的方法,可以使用類似如下的方法:

(Child.GetControl('Button1') as TButton).Click;

以上經驗,供大家參考。

#7


謝謝你的意見,覺得不錯,這樣的話要在各子窗口中要建立一個自注冊的過程才可以達到這個效果,我會改進一下,謝謝

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com