線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2894
推到 Plurk!
推到 Facebook!

有關動態呼叫Form

答題得分者是:Justmade
a07272
一般會員


發表:2
回覆:8
積分:2
註冊:2002-03-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-20 17:28:48 IP:211.78.xxx.xxx 未訂閱
請教各位前輩,如何在SDI的專案中以單一的Procedure呼叫不同的Form如 在主Menu.onclick中呼叫createform('Form1'),程式即會將Form1 create起來, CreateForm('Form2')則Form2就會create起來? 現行做法: procedure createform(vForm:String); begin If (vForm = 'Form1') Then Begin Create form1... End; If (vForm = 'Form2') Then Begin Create Form2... End; . . end; 這樣似乎很沒有效率,請各位前輩指教是否有更有效率的做法,謝謝...^_^
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-20 18:21:24 IP:61.155.xxx.xxx 未訂閱
USES UNIT2,......;    procedure createform(vForm:tform); begin vForm:=tform.Create(nil); vForm.Caption :=datetimetostr(now); vForm.Show ; end;    供参考!!!    风花雪月 e梦情缘
發表人 - wnhoo 於 2003/05/20 18:24:12
------
风花雪月 e梦情缘
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-20 19:11:50 IP:218.16.xxx.xxx 未訂閱
procedure TForm1.CreateForm(FormClass : TFormClass);
var
i : integer;
Fm : TForm;
begin
  fm := nil;
  for i := 0 to Screen.FormCount - 1 do
    if Screen.Forms[i] is FormClass then
      Fm := Screen.Forms[i];
  if not assigned(fm) then
    fm := FormClass.Create(Self);
  fm.Show;
end;    procedure TForm1.mForm2Click(Sender: TObject);
begin
  CreateForm(TForm2);
end;    procedure TForm1.mForm3Click(Sender: TObject);
begin
  CreateForm(TForm3);
end;
紅色的部份是自動測試該 Form 是否已存在,若已存在便叫它出來不用 Create 了,若不存在便Create它出來 若你想若使用者多按一次便多出一個,那刪掉紅色部份即可
banson1716
高階會員


發表:55
回覆:182
積分:167
註冊:2002-04-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-05-20 19:19:53 IP:218.175.xxx.xxx 未訂閱
試試看 http://delphi.ktop.com.tw/topic.php?topic_Id=21383
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-05-20 19:20:15 IP:218.16.xxx.xxx 未訂閱
引言: USES UNIT2,......; procedure createform(vForm:tform); begin vForm:=tform.Create(nil); vForm.Caption :=datetimetostr(now); vForm.Show ; end;
發問者清楚說明是要動態呼叫不同的 Form (如Form1,Form2) 而不是做全新的空 Form 解錯題每人皆有但像你比率那麼高還一直不肯改一改的真的很少見。 詳見 給 wnhoo ,也給關心事件的K.Top網友 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=30664
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-05-20 20:03:15 IP:61.155.xxx.xxx 未訂閱
a07272兄: 这应该是你想要的答按了:    procedure TForm1.createform(myform:string); var tmp:tform; begin tmp:=tform(FindComponent(myform)); Application.CreateForm(TForm,tmp); tmp.Caption:=myform; tmp.Show ; end; procedure TForm1.Button1Click(Sender: TObject); begin createform('form2'); end; Justmade兄: 不要无事生事,难道你没看见a07272兄要什么样的答按吗? 我前面是一般的动态呼叫FORM,应该和你提供的方法差不多吧。 我想我们应该为各位会员解答才对的, 如果我以后有什么错误请指出,不是象上面的!!!没事找事吗?! 风花雪月 e梦情缘
------
风花雪月 e梦情缘
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-05-20 20:18:49 IP:218.16.xxx.xxx 未訂閱
wnhoo, 自己做過例子出來,form2 及 form3 都是己設計好的 form,若用你剛才的程式碼能叫得出來,我登文向你公開道歉,若三天內你做不出來你向我登文道歉,如何? 若三天不夠,你現在就說明要多久,不要說不給你足夠時間。若你要我也做範例我可一兩小時內貼上來,甚樣 ?
turboted
版主


發表:95
回覆:754
積分:452
註冊:2002-07-23

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-05-20 20:58:32 IP:61.30.xxx.xxx 未訂閱
不就 FORM1->Show();就好了嗎 弄的真是有夠嘛煩的
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-05-20 22:54:32 IP:218.16.xxx.xxx 未訂閱
引言: FORM1->Show();就好了嗎
若是簡單的 Applicaiton, 預先 AutoCreate 所有 Form 又不 Free 的,可以用 Form1.showl 便可 但通常較大一點的程式都不會一開始 Create 所宥 Form 然後不 Free; 而是需要時 Create , 完成或想重來時就 Free 而且,發問者也題到要 create Form , 所以就用 一般 用時才找找 Create 了未,未有時 Create 的方法。
turboted
版主


發表:95
回覆:754
積分:452
註冊:2002-07-23

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-05-20 23:08:31 IP:218.167.xxx.xxx 未訂閱
仙人打鼓有時錯..^.^ 不好意思Justmade兄,麻煩您了
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-05-21 08:30:01 IP:61.155.xxx.xxx 未訂閱
unit Unit1;    interface    uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls;    type   TForm1 = class(TForm)     Button1: TButton;        procedure Button1Click(Sender: TObject);   private     { Private declarations }   public     { Public declarations }   end;    var   Form1: TForm1;    implementation uses unit2; {$R *.dfm} //动态调用(2) procedure Create_Self(vclassform:TFormClass;vForm:tform); begin Application.CreateForm(vclassform,vform); if vform.Tag = 0 then begin Try vform.ShowMOdal; Finally vform.Release; End; end else begin vform.Release; end; end; procedure TForm1.Button1Click(Sender: TObject); begin Create_Self(tform2,form2); end; end. Justmade兄:我今天上班的时候看到你的问题的,现在就帖上了。我感觉您象个“小孩子”似的童心未泯呀!!!! 风花雪月 e梦情缘
------
风花雪月 e梦情缘
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-05-21 09:14:34 IP:218.16.xxx.xxx 未訂閱
你這篇有使用你原先的程式碼嗎? 還不是使用了我使用的 TFormClass 作更改而做出來? 至於到底是否剛看到便貼出來,有留意 wnhoo 事件的人自然心裡有數。 你不敢接受挑戰以原來的程式碼做成出可執行呼叫其他已設計好的 Form 我不怪你也不逼你,這到底表示你已知道原先的錯。 如 turboted 版主所說,"仙人打鼓有時錯",其實錯了也沒甚麼大不了,我們平當看到若對答題沒甚麼影響會不理若有影響指出便是,對你的頭十數篇這種文章我們也多沒說一話便算了。 由於你的問題文章真是太多了,所以出問題時 post 出連結只是希望你能出文前想清楚別再亂出問。 至於發出挑戰,是因為你錯了不認還發難,既然你在上程式認了你的錯(雖然嘴上還硬)便算了。 我由始至現在從沒以版主的權力刪過你的一篇文章(重覆文除外)或扣你分,我始終專重你登文的權利,而對你特別強硬是因為你的問題真是太多了,若有另一人這樣多問題我一樣會這樣做。 反之,我亦看到你不少文章是好的能解決問題的,我絕對相信若你不亂 Post 文的話對 K.Top 是一個很有價值的會員。 所以,再說一次,希望你把精力習中在你會的題目,若引文引出處,不要在別人已答好題目改一點作答來摸魚;這樣事情將很快過去,到時我甚至可為我的強硬手法致歉。但若真的是似然固我,我只好執行其他版主與站務組的建議,刪文了事。 我的看法是:歪風就像病毒,一開始不正視解決它便會像野火遼原不可收拾,到時正直解題的人離開,只留下投機取巧者,對大家都沒好處。 發表人 - Justmade 於 2003/05/21 09:17:14
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-05-21 09:27:13 IP:61.155.xxx.xxx 未訂閱
如在主Menu.onclick中呼叫createform('Form1'),程式即會將Form1 create起來,CreateForm('Form2')則Form2就會create起來? ----------------------------------------------------- 我原先的程序代码是动态创建FORM。 請教各位前輩,如何在SDI的專案中以單一的Procedure呼叫不同的Form -------------------------------------------------------- 后面的程序代码是呼叫FORM 好象我的回答应该是对的,不知道a07272兄到底用什么答案。 这个可能是只有问问题的人自己知道了。 Justmade兄: 我感觉你越来越有意思了,这个题目我想应该结束了吧!!!! 风花雪月 e梦情缘
------
风花雪月 e梦情缘
a07272
一般會員


發表:2
回覆:8
積分:2
註冊:2002-03-12

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-05-21 13:03:18 IP:211.78.xxx.xxx 未訂閱
謝謝版主及各位前輩指教,但是我想可能是因為我沒有將問題定義清楚而導致各位的誤解,我的問題是如何在一個SDI專案中(可能包含上千支已開法完成的表單或Unit)利用一個Procedure去呼叫不同的表單如:CreateAppForm('客戶維護')就會將已開發完成的"客戶維護"畫面啟動,CreateAppForm('訂單查詢')就會將"訂單查詢"畫面啟動。我現行的做法是: . . . implementation uses Unit2, Unit3; {$R *.DFM} procedure TForm1.CreateAppForm(:vFormName :String); begin If (vFormName = 'Form2') Then Begin Try Form2 = TForm2.Create(Application); Form2.ShowModal; Finally Form2.Free; End; End; If (vFormName = 'Form3') Then Begin Try Form3 = TForm3.Create(Application); Form3.ShowModal; Finally Form3.Free; End; End; . . . end; 這樣做很沒有效率,因為每加一支程式,這個Procedure就必須修改一次,但礙於每支程式的Form Type不同又無法不做,請教各位前輩是否有更簡潔的方式,可以動態呼叫畫面,又不需每次修程式,謝謝...^_^
danny
版主


發表:100
回覆:522
積分:595
註冊:2002-03-11

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-05-21 13:25:27 IP:211.76.xxx.xxx 未訂閱
引言: 謝謝版主及各位前輩指教,但是我想可能是因為我沒有將問題定義清楚而導致各位的誤解,我的問題是如何在一個SDI專案中(可能包含上千支已開法完成的表單或Unit)利用一個Procedure去呼叫不同的表單如:CreateAppForm('客戶維護')就會將已開發完成的"客戶維護"畫面啟動,CreateAppForm('訂單查詢')就會將"訂單查詢"畫面啟動。我現行的做法是:
如果您要這樣做(我目前的系統就是這樣開發的), 要寫一個繼承自 TCustomAction 的元件, 如下:
  TMyAction = class(TCustomAction)
  private
    { Private declarations }
    FUserClassName,
    FUserPackageName,
    FParamVar: String;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;      published
    { Published declarations }
    property UserClassName: String read FUserClassName write FUserClassName;
    property UserPackageName: String read FUserPackageName write FUserPackageName;
    property UserParam: String read FParamVar write FParamVar;        property Caption;
    property Checked;
    property Enabled;
    property HelpContext;
    property Hint;
    property ImageIndex;
    property ShortCut;
    property Visible;
    property OnExecute;
    property OnHint;
    property OnUpdate;
  end;
再動態由外部檔案讀取 FormClassName 指定給 UserClassName, 將所有的 OnExecute 指定到共用的 NewExecute 統一產生 Form 如下: MyAction.OnExecute := NewExecute; NewExecute 內容如下:
  AForm := CreateFormByClassName(MyAction);
  if AForm <> nil then
    AForm.ShowModal;
剩下就是看您要將 MyAction 給 MainMenu or Toolbox 用了 ============================================
function CreateFormByClassName(const ClassName: String): TCustomForm;
var
  AClass: TPersistentClass;
  AForm: TForm;
begin
  Result := nil;
  AClass := GetClass(ClassName);
  if (AClass <> nil) then
  begin
    AForm := TComponentClass(AClass).Create(Application) as TForm;
    Result := AForm;
    AForm.Top := 0;
    AForm.Left := 0;
  end;
end;
記得所有的 Form 最後要加像如下程式, 給系統知道有此 Class 存在: initialization RegisterClass(TMyForm); finalization UnregisterClass(TMyForm); 發表人 - danny 於 2003/05/21 13:29:34
------
將問題盡快結案也是一種禮貌!
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-05-21 13:54:24 IP:218.16.xxx.xxx 未訂閱
請參考 : 動態以 Form 的 ClassName (字串) 建立唯一視窗 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=30803 那一個是按照 CCChen 前輩所給的資料寫成的,可以以Form 的 Class 或 Form 的 ClassName (String) 來呼叫打開視窗。 由於你之前說用在 Menu.onClick, 所以我認為既然你都寫在源程式中 用 'TForm1' 或 TForm1 都是一樣所以只提供較簡單的版本,而且那時未經 CCChen 前輩指點我要找只用 ClassName 的方法也要很費工夫。 雖然在你的回文仍看不出只使用 Class Name 來找的必要,但既然那個方法較好而又可使用動態地產生 Form 的 ClassName (如在資料庫讀取), 便附上這個範例的版本給你參考。
a07272
一般會員


發表:2
回覆:8
積分:2
註冊:2002-03-12

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-05-21 14:23:13 IP:211.78.xxx.xxx 未訂閱
感謝版主及各位前輩,謝謝
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-05-21 14:39:14 IP:218.16.xxx.xxx 未訂閱
danny 版主 TCustomAction 那部份是非常非常有用的,用他的方法可不用在每個 Button 寫 onClick,可全動態決定那個 Menu Item 去開那一個 Form。
系統時間:2024-11-24 21:58:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!