全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1536
推到 Plurk!
推到 Facebook!

如何在執行期動態指定 Events 所執行的程式?

答題得分者是:Mickey
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-01-07 21:00:14 IP:211.76.xxx.xxx 未訂閱
例如在 MDIForm 上有一個 Button 在不同的 MDIChild Active 的時候. 在 Button.OnClick 會執行不同的 procedure. 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-01-07 22:24:02 IP:218.32.xxx.xxx 未訂閱
bestlong 你好: 不太清楚你的需求... 是要在 MdiForm 叫起 MdiChild 時, 一併 Assign 對應的 Procedure 到 Button.Onclick 嗎 ? 還是在 ButtonClick Procedure 中判斷不同的 Screen.ActiveForm 執行不同的 Code ?
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-01-07 22:31:46 IP:211.76.xxx.xxx 未訂閱
引言: bestlong 你好: 不太清楚你的需求... 是要在 MdiForm 叫起 MdiChild 時, 一併 Assign 對應的 Procedure 到 Button.Onclick 嗎 ? 還是在 ButtonClick Procedure 中判斷不同的 Screen.ActiveForm 執行不同的 Code ?
應該是說在每個 MdiChild 都共用到 MdiForm 的同一個 Button, 同一時間會有很多個 MdiChild, 只是不同的 MdiChild 作用時, 按下 MdiForm 的 Button 就會去執行該 MdiChild 的一個 procedure. 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
seaturn99
版主


發表:69
回覆:427
積分:214
註冊:2003-08-25

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-01-08 00:07:45 IP:211.76.xxx.xxx 未訂閱
bestlong 您好:    不知道我有沒有會錯意??? 定義一個 ButtonClick 的 procedure 假設 TMdiChild 是您造好的 ChildForm     
procedure TMdiChild.BtnClick(Sender: TObject);
var
  cForm : TMdiChild;
begin
  if (Sender as TButton).Parent.ClassType = TMdiChild then
  begin
    cForm := ((Sender as TButton).Parent) as TMdiChild;        if cForm.Caption = 'ChildForm1' then
      RunProc1
    else if cForm.Caption = 'ChildForm2' then
      RunProc2
    else if cForm.Caption = 'ChildForm3 then
      RunProc3
    ......
    ......
    
  end;
end;
...... 的地方是以此類推,另外也可以用 Tag 代替 Caption ,事先就要有定義,如此不管是哪個 Child Form 上的 Button 都會對應到同一 OnClick Event Method 上,利用 Caption (Tag) 可區分執行不同的 procedure ... ---- 我只會兩件事,這也不會,那也不會 ---- 眼見不一定為真
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-01-08 09:08:48 IP:218.163.xxx.xxx 未訂閱
引言: 應該是說在每個 MdiChild 都共用到 MdiForm 的同一個 Button, 同一時間會有很多個 MdiChild, 只是不同的 MdiChild 作用時, 按下 MdiForm 的 Button 就會去執行該 MdiChild 的一個 procedure.
因為 TButton 繼承自 TWinControl , Click 時會讓 MdiForm Active, 所以我改用 MenuItem 試, 參考看看 :
procedure TMDIMainForm.test1Click(Sender: TObject); // test1 is TMenuItem on MdiForm
begin
  if (Screen.ActiveForm)<>nil then
  with Screen.ActiveForm do begin
  ...// Find and Perform Procedure
  end;
end;    
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-01-09 13:41:04 IP:211.22.xxx.xxx 未訂閱
引言: 不知道我有沒有會錯意??? 定義一個 ButtonClick 的 procedure 假設 TMdiChild 是您造好的 ChildForm
procedure TMdiChild.BtnClick(Sender: TObject);
var
  cForm : TMdiChild;
begin
  if (Sender as TButton).Parent.ClassType = TMdiChild then
  begin
    cForm := ((Sender as TButton).Parent) as TMdiChild;        if cForm.Caption = 'ChildForm1' then
      RunProc1
    else if cForm.Caption = 'ChildForm2' then
      RunProc2
    else if cForm.Caption = 'ChildForm3 then
      RunProc3
    ......
    ......
    
  end;
end;
...... 的地方是以此類推,另外也可以用 Tag 代替 Caption ,事先就要有定義,如此不管是哪個 Child Form 上的 Button 都會對應到同一 OnClick Event Method 上,利用 Caption (Tag) 可區分執行不同的 procedure ...
感覺是有些怪怪的, 這個技巧大多是運用在多個可視元件共用同一個 Procedure 以減少重複的程式撰寫, 而且我程式所有的 Mdi_Child_Form 都是動態建立的, 所以也不能執行尚未 CreateForm 的程式碼內容. 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-01-09 14:24:53 IP:211.22.xxx.xxx 未訂閱
目前是找到利用 TNotifyEvent 的處理模式 可參考 http://delphi.ktop.com.tw/topic.php?topic_id=22406 該程式碼中替換及復原 OnDestore Event 的處理方式, 還有的研究呢. 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-01-09 14:42:30 IP:211.22.xxx.xxx 未訂閱
再說清楚一些就是, 所有的 MDIChildForm 都不知道有多少其他的 MDIChildForm , 但是必然的一定會有一個 MDIMainForm 的存在, 而 MDIMainForm 上的 Button.OnClick 也不知道自己要執行什麼, 直到程式執行時, 作用中(OnShow,OnActivate)的 MDIChildForm 才動態的將所要執行的 Procedure 去掛上 MDIMainForm.Button.OnClick ,同樣的在 MDIChild 脫離作用中(OnAvtivate)或關閉(OnClose)時要釋放 MDIMainForm.OnClick 與自己的關聯. 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-01-09 14:49:37 IP:211.22.xxx.xxx 未訂閱
目前程式的畫面大概如下:     我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-01-09 14:55:13 IP:211.22.xxx.xxx 未訂閱
又找到相關資料: 在網站 http://huanlin.adsldns.org/ 內有一篇 作者:Taco Oosterkamp 轉譯:蔡煥麟先生 的文章 文章:設計可維護的應用程式 http://sun.cis.scu.edu.tw/~nms9115/articles/delphi/MaintainableApp/MaintainableAppTW.htm 在該文章內容當中的 3.6.3 事件 這一章節中有談到處理的方式與附帶原始碼. 繼續研究 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-01-09 14:57:03 IP:211.22.xxx.xxx 未訂閱
引言: 又找到相關資料: 在網站 http://huanlin.adsldns.org/ 內有一篇文章: 設計可維護的應用程式 (原名:Maintainable Applications ) 作者:Taco Oosterkamp 轉譯:蔡煥麟先生 http://sun.cis.scu.edu.tw/~nms9115/articles/delphi/MaintainableApp/MaintainableAppTW.htm 在該文章內容當中的 3.6.3 事件 這一章節中有談到處理的方式與附帶原始碼. 繼續研究 我是雪龍
我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
Fishman
尊榮會員


發表:120
回覆:1949
積分:2163
註冊:2006-10-28

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-01-09 15:51:47 IP:210.65.xxx.xxx 未訂閱
Hi:    抱歉,插花一下 你可以將所有 OnClick 事件所要處理的程式碼寫在 MainForm 上,並在 CreateMDIChild 事件,指定各個 MDIChild 的 Button1 OnClick 事件  
procedure TMainForm.CreateMDIChild(const Name: string);
var
  Child: TMDIChild;
begin
  { create a new MDI child window }
    Child := TMDIChild.Create(Application);
    Child.Caption := Name;
    case MDIChildCount of
        1 : Child.Button1.OnClick := Click1;
        2 : Child.Button1.OnClick := Click2;
        3 : Child.Button1.OnClick := Click3;
    else
        Child.Button1.OnClick := NIL;
    end;      if FileExists(Name) then Child.Memo1.Lines.LoadFromFile(Name);
end;
不知這樣是否合乎你的需求 -------------------------------- 小弟才疏學淺,若有謬誤請不吝指教 --------------------------------
------
Fishman
Fishman
尊榮會員


發表:120
回覆:1949
積分:2163
註冊:2006-10-28

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-01-09 16:15:06 IP:210.65.xxx.xxx 未訂閱
Hi:     
 
unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, CHILDWIN, StdCtrls;    type
  TMDIChild1 = class(TMDIChild)
    procedure Button1Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;    var
  MDIChild1: TMDIChild1;    implementation    uses MAIN;    {$R *.dfm}    procedure TMDIChild1.Button1Click(Sender: TObject);
begin
//  inherited;
    showmessage('xx');
end;    procedure TMDIChild1.FormActivate(Sender: TObject);
begin
//  inherited;
    MainForm.Button1.OnClick := Self.Button1Click;
end;    end.
在各個 MDIChild 中,指定 MainForm.Button1 的 OnClick 事件 -------------------------------- 小弟才疏學淺,若有謬誤請不吝指教 --------------------------------
------
Fishman
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-01-09 16:25:43 IP:211.22.xxx.xxx 未訂閱
引言: 你可以將所有 OnClick 事件所要處理的程式碼寫在 MainForm 上,並在 CreateMDIChild 事件,指定各個 MDIChild 的 Button1 OnClick 事件
procedure TMainForm.CreateMDIChild(const Name: string);
var
  Child: TMDIChild;
begin
  { create a new MDI child window }
    Child := TMDIChild.Create(Application);
    Child.Caption := Name;
    case MDIChildCount of
        1 : Child.Button1.OnClick := Click1;
        2 : Child.Button1.OnClick := Click2;
        3 : Child.Button1.OnClick := Click3;
    else
        Child.Button1.OnClick := NIL;
    end;      if FileExists(Name) then Child.Memo1.Lines.LoadFromFile(Name);
end;
不知這樣是否合乎你的需求 -------------------------------- 小弟才疏學淺,若有謬誤請不吝指教 -------------------------------- < face="Verdana, Arial, Helvetica"> 你好 Fishman : 你的這個方式在小型的程式是可以的, 也是我以前有用到的方式, 但是如果會面臨 MdiChild 的數量很多的時候, 會有理解與除錯上的困擾,那不就慘了. 不過剛剛我已經測試出來了, 用了兩種方式, 馬上就要上場了. 目前就只擔心會不會有記憶體漏失的狀況. 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-01-09 16:53:49 IP:211.22.xxx.xxx 未訂閱
unit UMain;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ImgList, ComCtrls, ToolWin, Menus, ExtCtrls, DBCtrls, StdActns,
  ActnList, StdCtrls;    type
  TFMain = class(TForm)
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    Child11: TMenuItem;
    Child21: TMenuItem;
    mnuWindow: TMenuItem;
    ToolBar1: TToolBar;
    tbtnPrint: TToolButton;
    ImageList1: TImageList;
    tbtnFind: TToolButton;
    ToolButton3: TToolButton;
    ToolButton6: TToolButton;
    DBNavigator1: TDBNavigator;
    ActionList1: TActionList;
    WindowTileVertical1: TWindowTileVertical;
    WindowTileHorizontal1: TWindowTileHorizontal;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    procedure N1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Child11Click(Sender: TObject);
    procedure Child21Click(Sender: TObject);
  private
    { Private declarations }
    FTempOnClick: TNotifyEvent;
  public
    { Public declarations }
  end;    procedure OpenChiForm(FormClass: TFormClass; var fm; AOwner: TComponent);
procedure OpenDlgForm(FormClass: TFormClass; var fm; AOwner: TComponent);    var
  FMain: TFMain;    implementation    uses UChild_1, UChild_2;    {$R *.dfm}    procedure OpenChiForm(FormClass: TFormClass; var fm; AOwner: TComponent);
var
  i: integer;
  Child: TForm;
begin      for i := 0 to screen.FormCount - 1 do
  begin
    if Screen.Forms[i].ClassType = FormClass then
    begin
      Child := Screen.Forms[i];
      if Child.WindowState = wsMinimized then
        ShowWindow(Child.Handle, SW_SHOWNORMAL)
      else
        ShowWindow(Child.Handle, SW_SHOWNA);
      if (not Child.Visible) then Child.Visible := true;
      Child.BringToFront;
      Child.SetFocus;
      TForm(fm) := Child;
      exit;
    end;
  end;
  // 找不到 Form 就建立
  Child := TForm(FormClass.NewInstance);
  TForm(fm) := Child;
  Child.Create(AOwner);
end;    procedure OpenDlgForm(FormClass: TFormClass; var fm; AOwner: TComponent);
var
  i: integer;
  Child: TForm;
begin
  // 建立 Form
  TForm(fm) :=FormClass.Create(AOwner);
  try
    TForm(fm).ShowModal;
  finally
    TForm(fm).Free;
  end;
end;    procedure TFMain.N1Click(Sender: TObject);
begin
  self.Close;
end;    procedure TFMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if MessageDlg('確定離開本程式', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
    CanClose := false;
end;    procedure TFMain.Child11Click(Sender: TObject);
begin
  OpenChiForm(TFChild_1, FChild_1, self);
end;    procedure TFMain.Child21Click(Sender: TObject);
begin
  OpenChiForm(TFChild_2, FChild_2, self);
end;    end.    
我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#16 引用回覆 回覆 發表時間:2004-01-09 16:55:19 IP:211.22.xxx.xxx 未訂閱
unit UChild_2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, UChild_Base, StdCtrls; type TFChild_2 = class(TFChild_Base) Label1: TLabel; procedure FormActivate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormDeactivate(Sender: TObject); private { Private declarations } public { Public declarations } procedure ShowPrintForm(Sender: TObject); end; var FChild_2: TFChild_2; implementation uses UMain, UChild_2_Print; {$R *.dfm} procedure TFChild_2.FormActivate(Sender: TObject); begin inherited; // 掛上自訂的程序 FMain.tbtnPrint.OnClick := ShowPrintForm; end; procedure TFChild_2.ShowPrintForm(Sender: TObject); var FChild_2_Print: TFChild_2_Print; begin UMain.OpenDlgForm(TFChild_2_Print, FChild_2_Print, self); end; procedure TFChild_2.FormClose(Sender: TObject; var Action: TCloseAction); begin inherited; FMain.tbtnPrint.OnClick := nil; end; procedure TFChild_2.FormDeactivate(Sender: TObject); begin inherited; FMain.tbtnPrint.OnClick := nil; end; end. 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
bestlong
站務副站長


發表:126
回覆:734
積分:512
註冊:2002-10-19

發送簡訊給我
#17 引用回覆 回覆 發表時間:2004-01-09 17:10:54 IP:211.22.xxx.xxx 未訂閱
unit UChild_2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, UChild_Base, StdCtrls; type TFChild_2 = class(TFChild_Base) Label1: TLabel; procedure FormActivate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormDeactivate(Sender: TObject); private { Private declarations } public { Public declarations } procedure ShowPrintForm(Sender: TObject); end; var FChild_2: TFChild_2; implementation uses UMain, UChild_2_Print; {$R *.dfm} procedure TFChild_2.FormActivate(Sender: TObject); begin inherited; // 掛上自訂的程序 FMain.tbtnPrint.OnClick := ShowPrintForm; end; procedure TFChild_2.ShowPrintForm(Sender: TObject); var FChild_2_Print: TFChild_2_Print; begin UMain.OpenDlgForm(TFChild_2_Print, FChild_2_Print, self); end; procedure TFChild_2.FormClose(Sender: TObject; var Action: TCloseAction); begin inherited; FMain.tbtnPrint.OnClick := nil; end; procedure TFChild_2.FormDeactivate(Sender: TObject); begin inherited; FMain.tbtnPrint.OnClick := nil; end; end. 我是雪龍
------
http://blog.bestlong.idv.tw/
http://www.bestlong.idv.tw/
http://delphi-ktop.bestlong.idv.tw/
系統時間:2024-07-01 14:27:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!