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

[問題]如何動態產生多個form

尚未結案
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-12-24 00:16:57 IP:218.190.xxx.xxx 未訂閱
我是一個新手 請問 以下情況應該怎麼辦 我有二個form, form1 and form2, form1 有一個button ,listbox, form2 有一個button , ttable ,ttable 是連著一個database, 但沒有指定table name 我想問的是當我按form1 button 的時候,要產生一個新的form2 , 而form2內的ttable 的tablename 是由form1 的listbox 內容選擇而定, 如果選擇的 form2 已經存在就再 show 該form2, 如果沒有存在就產生一個,請問各位大大要怎樣寫,而且不同的table 會有各自一個form2, 所有form2 可以同時畫面上,請問要怎樣寫, 而form2 的button 是用來把現在的form2 free 的, 但我試過會memory error 請問應該怎麼做 謝謝
liorex
初階會員


發表:19
回覆:60
積分:32
註冊:2002-08-20

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-12-24 07:22:51 IP:61.64.xxx.xxx 未訂閱
我想你可以設定一個Form2的變數 當assigned(Form2)=true 就Form2.show 要是False 則 TForm2.create 當Tform2.create 之後再去設定Form2上的資料庫的連接 and Form2上的Button 你也許可以試著Postmessage 給Form1 來 做Form2的Close並且將Form2設為NIL ---------------------- 一切有為法 如夢幻泡影 如露亦如電 應做如是觀 ----------------------
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-12-24 09:59:25 IP:218.103.xxx.xxx 未訂閱
對不起 因為我真的是一個新手 請問可以再更具體一點嗎?或者是可以有code 嗎?? 謝謝大大
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-12-24 10:15:29 IP:218.103.xxx.xxx 未訂閱
另外我有試過在form1 的 button 上加這樣的code if form2 = nil then form2 := Tform2.Create(); 但這樣之後只會產生一個form2,在form1 的listbox 選什麼都不會再產生新的form2 請問是怎麼了?
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-12-24 12:01:59 IP:218.103.xxx.xxx 未訂閱
各位大大,可能我表達不太清楚我的問題 我cap了一些圖希望這樣會清楚一點,請各位幫忙,因為是工作的 圖中所看到的form2 是run time 的時候才會產生的 在form1所看到的A, B 是在listbox 裡的 當我選A的時候再按button1 ,就產生一個 form2 而這個form2 的caption 是form1 listbox 裡的選擇 , 比如說我選A , 就產生一個form2 而這個form2 的caption 會叫 a ,但是如果A的form2 已經存在那就不要產生新的,那把A的form2 visible就可以了, 而form2 裡的button1 是用來close 我現在在active 的form2 並且free 請問各位大大怎樣做了?
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-12-24 12:10:33 IP:218.170.xxx.xxx 未訂閱
form1的button1click    
    begin
  if form2=nil then 
     form2:=tform2.create(self);
  form2.caption:='a';
  form2.show;     
end;    
form2的button1click
    begin
  close;
end;
form2的onclose
procedure tform2.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  form2:=nil;
  action:=cafree;
end;
發表人 - hahalin 於 2004/12/24 12:11:44
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-12-24 12:30:56 IP:220.130.xxx.xxx 未訂閱
建議你以MDI的方式來呈現你的功能. 做法如下: [code] ●首先你先開啟一個先的Form,並存成Main, Form 的屬性設定如下: Name : frmMain FormStyle: fsMDIForm; 這個是你的主程式的 MDI MainForm. ●將你的TForm1及TForm2的屬性 FormStyle 設為 fsMDIChild,意思是說 現在你有兩個型態分別為TForm1及TForm2 的MDIChild Form Class(只是類別而已,此 時尚未產生實際的Form物件); ●將TForm2從Auto-Create Forms中移到Availabel Forms List中,界定上我們希望TForm2是動態產生的. 而TForm1保留為自動產生. ●此時執行程式,應該為出現MainFrom上有一個 From1(稱Form1是因為Delphi以這個變數自動 產生出來的TFrom1的實際物件).
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-12-24 12:30:59 IP:220.130.xxx.xxx 未訂閱
建議你以MDI的方式來呈現你的功能. 做法如下: [code] ●首先你先開啟一個先的Form,並存成Main, Form 的屬性設定如下: Name : frmMain FormStyle: fsMDIForm; 這個是你的主程式的 MDI MainForm. ●將你的TForm1及TForm2的屬性 FormStyle 設為 fsMDIChild,意思是說 現在你有兩個型態分別為TForm1及TForm2 的MDIChild Form Class(只是類別而已,此 時尚未產生實際的Form物件); ●將TForm2從Auto-Create Forms中移到Availabel Forms List中,界定上我們希望TForm2是動態產生的. 而TForm1保留為自動產生. ●此時執行程式,應該為出現MainFrom上有一個 From1(稱Form1是因為Delphi以這個變數自動 產生出來的TFrom1的實際物件).
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-12-24 12:53:15 IP:220.130.xxx.xxx 未訂閱
●接下來寫TForm1    implementation    uses Main, Unit2;    {$R *.dfm}    procedure TForm1.FormCreate(Sender: TObject);
begin
  Width := Button1.Left   Button1.Width   50;
  Height := ListBox1.Top   ListBox1.Height   50;
  ListBox1.Items.Add('A');
  ListBox1.Items.Add('B');
  ListBox1.Items.Add('C');
  ListBox1.ItemIndex := 0;
end;    procedure TForm1.Button1Click(Sender: TObject);
var
  AlreadyCreated: Boolean;
  Key: string;
  I: Integer;
begin
  if ListBox1.ItemIndex > -1 then
  begin
    Key := Trim(ListBox1.Items[ListBox1.ItemIndex]);
    AlreadyCreated := False;
    for I := 0 to frmMain.MDIChildCount-1 do
      if frmMain.MDIChildren[I] is TForm2 then
        if Key = frmMain.MDIChildren[I].Caption then
        begin
                frmMain.MDIChildren[I].SetFocus;
          AlreadyCreated := True;
                Break;
        end;        if not AlreadyCreated then
      with TForm2.Create(frmMain) do
      begin
              Caption := Key;
        Show;
      end;      end;
end;    ●接下來寫TForm2    procedure TForm2.FormCreate(Sender: TObject);
begin
  Width := Button1.Left   Button1.Width   50;
  Height := Button1.Top   Button1.Height   50;
end;    procedure TForm2.Button1Click(Sender: TObject);
begin
  Close;
end;    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;    
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-12-24 12:55:58 IP:218.103.xxx.xxx 未訂閱
引言: form1的button1click
    begin
  if form2=nil then 
     form2:=tform2.create(self);
  form2.caption:='a';
  form2.show;     
end;    
想請教一下 這樣的話,當我第一次按下FORM1 button 的話都會產生一個新的 form2 但之後我再選其他也不會再產生新的, 而且如果我按form2 的button去close, 之後再按form1 button 也是不行 會有memory error, form1裡的 form2 variables 不是等如nil
delphiwww
資深會員


發表:145
回覆:363
積分:368
註冊:2002-03-13

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-12-24 12:59:40 IP:202.39.xxx.xxx 未訂閱
改成如此
begin
  with tform2.create(application) do
  begin
    caption:='a';
    show;     
  end;
end;
引言:
引言: form1的button1click
    begin
  if form2=nil then 
     form2:=tform2.create(self);
  form2.caption:='a';
  form2.show;     
end;    
想請教一下 這樣的話,當我第一次按下FORM1 button 的話都會產生一個新的 form2 但之後我再選其他也不會再產生新的, 而且如果我按form2 的button去close, 之後再按form1 button 也是不行 會有memory error, form1裡的 form2 variables 不是等如nil
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-12-24 13:01:56 IP:220.130.xxx.xxx 未訂閱
把變數Form2忘掉吧!因為你產生的是 多個TForm2的Instance, From2 := TForm2.Create(); <<--產生第一個 From2 := TForm2.Create(); <<--產生第二個 請問之後你如何去存取'第一個'? 況且如果它的Owner為nil時,當程 式結束時,你如何去Freet它?
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-12-24 14:25:34 IP:218.103.xxx.xxx 未訂閱
引言: 把變數Form2忘掉吧!因為你產生的是 多個TForm2的Instance, From2 := TForm2.Create(); <<--產生第一個 From2 := TForm2.Create(); <<--產生第二個 請問之後你如何去存取'第一個'? 況且如果它的Owner為nil時,當程 式結束時,你如何去Freet它?
jow 你說得十分對我的問題就是這樣 怎麼辦? 一定要用MDI 嗎? SDI不行嗎?
Miles
尊榮會員


發表:27
回覆:662
積分:622
註冊:2002-07-12

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-12-24 14:30:00 IP:220.135.xxx.xxx 未訂閱
Hi SamSam1230 你好, 我寫了一個小範例, 應該可達到你的需求 範例在這裡http://delphi.ktop.com.tw/topic.php?TOPIC_ID=62188 原始碼如下
//======Form1=======
unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;    type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ListBox1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    MyFormList : TList;
  end;    var
  Form1: TForm1;    implementation    Uses Unit2;    {$R *.dfm}    procedure FreeMyForm(FormPoint: Pointer);
begin
  Form1.MyFormList.Delete(Form1.MyFormList.IndexOf(FormPoint));
  ShowMessage(IntToStr(Form1.MyFormList.Count));
end;    procedure TForm1.FormCreate(Sender: TObject);
begin
   MyFormList := TList.Create;
end;    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   MyFormList.Free;
end;    procedure TForm1.ListBox1Click(Sender: TObject);
var i : integer;
begin
   for i := 0 to MyFormList.Count - 1 do begin
       if TForm2(MyFormList.Items[i]).TableName = ListBox1.Items.Strings[ListBox1.ItemIndex] then begin
          TForm2(MyFormList.Items[i]).BringToFront;
          exit;
       end;
   end;
   Form2 := TForm2.Create(Self);
   Form2.Caption := ListBox1.Items.Strings[ListBox1.ItemIndex];
   Form2.TableName := ListBox1.Items.Strings[ListBox1.ItemIndex];
   Form2.Show;
   MyFormList.Add(Form2);
   Form2.FreeMyForm := @FreeMyForm;
end;    end.        //=======Form2=========
unit Unit2;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;    Type
  TFreeMyForm = procedure(FormPoint: Pointer);    type
  TForm2 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    FreeMyForm : TFreeMyForm;
    TableName : String;
  end;    var
  Form2: TForm2;    implementation    {$R *.dfm}    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   FreeMyForm(Self);
end;    end.    
我不是高手, 高手是正在銀幕前微笑的人.
------


我不是高手, 高手是正在銀幕前微笑的人.
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-12-24 14:30:04 IP:218.170.xxx.xxx 未訂閱
利用你原本的構想... caption...    
var i:integer;
begin
  for ih:=0 to application.ComponentCount-1 do begin
     if application.Components[i] is tform2 then
        if tform2(application.Components[i]).caption='a' then
        begin
           //
        end;
  end;
end;
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#16 引用回覆 回覆 發表時間:2004-12-24 14:37:11 IP:218.103.xxx.xxx 未訂閱
引言: 改成如此
begin
  with tform2.create(application) do
  begin
    caption:='a';
    show;     
  end;
end;
想請問一下這裡的application 是什麼意思??
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#17 引用回覆 回覆 發表時間:2004-12-24 14:41:42 IP:220.130.xxx.xxx 未訂閱
引言: jow 你說得十分對我的問題就是這樣 怎麼辦? 一定要用MDI 嗎? SDI不行嗎?
可以,那就不需要產生MainForm了, 而TForm1與TForm2就維持fsNormal 程式碼改為
procedure TForm1.Button1Click(Sender: TObject);
var
  AlreadyCreated: Boolean;
  Key: string;
  I: Integer;
begin
  if ListBox1.ItemIndex > -1 then
  begin
    Key := Trim(ListBox1.Items[ListBox1.ItemIndex]);
    AlreadyCreated := False;
    for I := 0 to Components-1 do
      if Components[I] is TForm2 then
        if Key = TForm2(Components[I]).Caption then
        begin
                TForm2(Components[I]).SetFocus;
          AlreadyCreated := True;
                Break;
        end;        if not AlreadyCreated then
      with TForm2.Create(Self) do//Self為TForm1
      begin
              Caption := Key;
         Show;
      end;
  end;
end;
要特別注意的是當Form1被Free的時候, 你應該就記憶體的釋放動作,多加注意. 可是我還是幾較建議用MDI.....< >< >< >< >
ha0009
版主


發表:16
回覆:507
積分:639
註冊:2002-03-16

發送簡訊給我
#18 引用回覆 回覆 發表時間:2004-12-24 14:52:25 IP:219.80.xxx.xxx 未訂閱
你好:
  你的問題重點應該是如何管理你的視窗,你可以直接使用 Listbox 內的 items 來
存放管理你的 TForm2,或者另外寫一個管理程序來管理你的 TForm2。附上一個範例希
望能有助你的了解。    範例http://sourceprovide.deepen.com.tw/k_top/K_Top_62150.rar
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#19 引用回覆 回覆 發表時間:2004-12-24 15:43:59 IP:220.130.xxx.xxx 未訂閱
版主的做法也很好,總之,程式架構應先決定好.    
 
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  O: TObject;
begin
  if ListBox1.ItemIndex > -1 then
  begin
    O := ListBox1.Items.Objects[ListBox1.ItemIndex];
    if Assigned(O) then TFrom2(O).Show
    else begin
      O := TForm2.Create(Self);
      O.Caption := ListBox1.Items[ListBox1.ItemIndex];
      O.Show;          ListBox1.Items.Objects[ListBox1.ItemIndex] := O;        end;
  end;
end;    procedure TForm2.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  if Owner if TForm1 then
    with TForm1(Owner),ListBox1,Items do
       Objects[ItemIndex] := nil;
  Action := caFree;
end;    
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#20 引用回覆 回覆 發表時間:2004-12-24 15:49:05 IP:218.103.xxx.xxx 未訂閱
引言: Hi SamSam1230 你好, 我寫了一個小範例, 應該可達到你的需求 範例在這裡http://delphi.ktop.com.tw/topic.php?TOPIC_ID=62188
非常謝謝Miles大大的 sourcecode 但是我開的時候有error?? 不知道是不是我用的version 不同 我是delphi 4.0 謝謝
Miles
尊榮會員


發表:27
回覆:662
積分:622
註冊:2002-07-12

發送簡訊給我
#21 引用回覆 回覆 發表時間:2004-12-24 17:56:18 IP:220.135.xxx.xxx 未訂閱
喔喔 我是Delphi6, 錯誤訊息是什麼 我不是高手, 高手是正在銀幕前微笑的人.
------


我不是高手, 高手是正在銀幕前微笑的人.
liorex
初階會員


發表:19
回覆:60
積分:32
註冊:2002-08-20

發送簡訊給我
#22 引用回覆 回覆 發表時間:2004-12-24 20:14:44 IP:61.64.xxx.xxx 未訂閱
一般來說 Delphi 4or5開Delphi6的文件會發生 錯誤有可能是 dfm檔有問題 你看看他的 DFM檔的caption是紀錄什麼樣的資訊 要視紀錄的是數字的話 將caption改成給字串值應該就可以了 ---------------------- 一切有為法 如夢幻泡影 如露亦如電 應做如是觀 ----------------------
系統時間:2024-07-04 5:16:55
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!