動態指定事件程序名稱 |
答題得分者是:Justmade
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
|
tech_state
版主 發表:44 回覆:638 積分:641 註冊:2003-02-10 發送簡訊給我 |
引言: 請問我在button.click動態指定一個procedure ex button.click:= A(此A是動態傳入執行的) 而且A是我存在table取出的,所以型態是string; 請問要如何做?? 好像看過此篇討論,但是我找不到了,可否請知道的人回答我,謝謝cyl, 您好 不知道您指的是不是這篇 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=29976 ======================= 是非終日有,不聽自然無 天下本無事,庸人自擾之 |
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
由字串找 function 應該是沒有這樣的功能, 不過可以利用變通的方法, 自己定義 fname, fpointer 然後利用 getFuncPointer 傳入 function name, 傳回 function pointer 即可, 在 form 起來的時候先將所有的 function name 及 其對應的 pointer 寫入 fname, fpointer 陣列中, 範例程式碼如下:
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TVirtualClass = class class procedure myclick(Sender: TObject); end; TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure FormActivate(Sender: TObject); private { Private declarations } public { Public declarations } end; // var Form1: TForm1; fname: Array of String; fpointer: Array of Pointer; function getFuncPointer(funcname: string): Pointer; // implementation // {$R *.DFM} function getFuncPointer(funcname: string): Pointer; var i: integer; begin Result := nil; for i:= Low(fname) to High(fname) do begin if fname[i] = funcname then begin Result := fpointer[i]; break; end; end; end; // procedure TForm1.Button1Click(Sender: TObject); var myfunc: procedure(Sender: TObject) of object; begin @myfunc := getFuncPointer('TVirtualClass.myclick'); Button2.OnClick := myfunc; end; // procedure TForm1.FormActivate(Sender: TObject); begin SetLength(fname, 1); SetLength(fpointer, 1); fname[0] := 'TVirtualClass.myclick'; fpointer[0] := @TVirtualClass.myclick; end; // { TVirtulClass } // class procedure TVirtualClass.myclick(Sender: TObject); begin showmessage('123'); end; end. |
Justmade
版主 發表:94 回覆:1934 積分:2030 註冊:2003-03-12 發送簡訊給我 |
timhuang sir, Delphi 的 DFM 不是使用 RTTI 來Load進 Form 的嗎,但它也可處理 Event 以 Name 來設定,不知是用甚麼方法。 object Button1: TButton
Left = 32
Top = 56
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click <----
end 我確是像你所說的找不到由字串找 function 的方法,我只想到property來存放那些會動態提定的 function, 然後 database 記著 property 的名稱,提定時便可指定 property 的值給對應的 Evnet,不知是否可行。
|
hagar
版主 發表:143 回覆:4056 積分:4445 註冊:2002-04-14 發送簡訊給我 |
|
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
hagar 前輩真厲害, 確實這是一個比較完美的解法, 將程式修改一下, 將原來的 TVirtualClass 繼承自 TObject 才可以使用 MethodAddress, 然後就可以使用 MethodAddress 利用 名稱 來找出其位置, 另要注意該 function or procedure 一定要是在 published 的才能利用 MethodAddress 找出, 否則是不行的, 程式如下:
type TVirtualClass = class(TObject) published class procedure myclick(Sender: TObject); end; TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; // implementation {$R *.dfm} // procedure TForm1.Button1Click(Sender: TObject); var myfunc: TNotifyEvent; begin @myfunc := TVirtualClass.MethodAddress('myclick'); Button2.OnClick := myfunc; end; // { TVirtualClass } // class procedure TVirtualClass.myclick(Sender: TObject); begin showmessage('123'); end;另外關於 Justmade 前輩的提示, 我想, 應該也是利用 MethodAddress 來進行的, 因為在 Form 上的 button event 原型也都會定義在 form 中, 所以可以利用文字就找到該 function or procedure 的位置而指定給 button .... |
Justmade
版主 發表:94 回覆:1934 積分:2030 註冊:2003-03-12 發送簡訊給我 |
引言: 另外關於 Justmade 前輩的提示, 我想, 應該也是利用 MethodAddress 來進行的, 因為在 Form 上的 button event 原型也都會定義在 form 中, 所以可以利用文字就找到該 function or procedure 的位置而指定給 button .... >>< face="Verdana, Arial, Helvetica"> timhuang 兄 我之前亦在 help file 中找到過 Method Address 來試 ,但發現只能在找到 published 的 function (這亦是你範例中註明的)。而那些在元件區的 function (如 buttonclick) 是找不到的。 由於 DFM 的資料是 Form Create 後 Load 進去的,理論上我們亦可做同樣效果但就是甚樣找也找不到方法。 或許元件區的東東 Delphi 是暗地裡像你一樣放在另一個 Virtual Class 裡的 |
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
引言: 由於 DFM 的資料是 Form Create 後 Load 進去的,理論上我們亦可做同樣效果但就是甚樣找也找不到方法。 或許元件區的東東 Delphi 是暗地裡像你一樣放在另一個 Virtual Class 裡的 >>< face="Verdana, Arial, Helvetica"> 是的, Justmade 兄, 弟忽略了在 form 中定義的 Button1Click 是在 private 段(無指定屬性的段落為 private)而並非是 published, 所以可能不是用 MethodAddress 來找出其位置, 或許有類似但是不開放的 function 吧.. 弟進一步做了一個小測試, 一個程式中放兩個 >黑箱> 也就是不開放的 > |
Justmade
版主 發表:94 回覆:1934 積分:2030 註冊:2003-03-12 發送簡訊給我 |
哎呀...原來這樣就可以的....不知為甚麼之前沒試出來...
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure MyClick(Sender : TObject); private { Private declarations } public published { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); var myfunc: TNotifyEvent; begin @myfunc := MethodAddress('myclick'); Button2.OnClick := myfunc; end; procedure TForm1.MyClick(Sender: TObject); begin ShowMessage('MyClick'); end; end.似乎放在元件區的 是自動 publish 的.... |
timhuang
尊榮會員 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
對.... 沒錯, 在 TForm1 裡沒有寫屬性的區域是自動 published 的啦....~~
小弟誤會會變成 private, 應該是 Justmade 兄指點的沒錯, 是 published!! 這樣一來就所有的謎團都解開了呢..... 哈哈..... 一個字.... 讚! 但是在自訂的 class 中, 沒有寫屬性的區域確實是 private 的, 所以之前 Justmade 兄才會試不出來... 發表人 - timhuang 於 2003/05/07 23:54:37
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |