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

如何在執行程式時取得在"Available forms"內之所有Form的名稱?

尚未結案
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-11-06 11:41:49 IP:218.170.xxx.xxx 未訂閱
請教各位先進,是否有辦法在執行程式時,透過函法或其它方法取得在設計程時在Project->Options->Forms->Available forms之所有Form的名稱。
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-11-06 11:45:38 IP:202.39.xxx.xxx 未訂閱
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=39304 --- Everything I say is a lie.
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-11-06 14:16:12 IP:218.170.xxx.xxx 未訂閱
先在此謝謝 hagar 兄的回覆。 可能我的意思沒有表達清礎,因為我的Form是動態產生的,而我又想經由程式能夠取得該執行程式在Project->Options->Forms->Available forms之所有Form的名稱,但此時這些Form不一定已開啟。 我曾經使用TScreen.CustomFormCount 及 TScreen.CustomForms去取得Form的名稱,但它只針對已開啟的Form有效,功能似乎和 hagar 兄提供的方法差不多,不知我的測試是否正確,尚請指教。
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-11-06 14:22:31 IP:147.8.xxx.xxx 未訂閱
Delphi knows about the forms listed in available forms (not auto created) because it SCAN the source codes... What do you want to do exactly?
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-11-06 14:36:12 IP:218.170.xxx.xxx 未訂閱
因為我想要管理專案內的Form,如此我可以不必透過人工手抄的方式得,可以節省人力。 甚至由特殊命名方式來管理權限。
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-11-06 14:47:47 IP:147.8.xxx.xxx 未訂閱
I can think of some ways... 1) make use of initialization/finalization section and create your own list of forms 2) write a tool to scan the source codes (can be implemented via OTA?)
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-11-06 17:03:41 IP:218.170.xxx.xxx 未訂閱
謝謝 william 兄的回答,因為我想那是最糟糕的狀況,另外是否可請教如何去讀取 Source Code,又檔案為何?是否可指點一個方向。謝謝
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-11-07 11:53:02 IP:147.8.xxx.xxx 未訂閱
Create wizard using OTA can only help you in maintaining the source. In your case, I think making use of a global list may be better...    In some unit, create the list, e.g.
var
    gForms: TStringList; { global }
initialization
    gForms := TStringList.Create;
finalization
    gForms.Free;
end.
Then in EVERY form:
initialization
    gForms.Add(Txxx.ClassName); { Txxx is the form class }
end.
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-11-11 09:06:48 IP:218.170.xxx.xxx 未訂閱
謝謝 william 兄熱心的回覆我的問題。 我也曾經想過先將Project->Options->Forms->Available Forms先移至Auto-create forms內,因其先自動產生,所以可以透過TScreen.CustomForms可以取得該Form的名稱,但這並不是符合我自動化的要求,因為它還是要手動,在我專案中加入一個新的Form,就必須如此做一次,有點不合自動化原則。 但還是謝謝您熱心的在幫我找尋答案。
ccchen
版主


發表:61
回覆:940
積分:1394
註冊:2002-04-15

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-11-13 11:05:23 IP:218.163.xxx.xxx 未訂閱
1. 先將Project->Options->Forms->Available Forms先移至Auto-create forms內 這是最不合理的, 全autocreate, 如果你有幾百個form, 一開始就等死了 2.讀souece,此source是指.dpr檔, 你可以由Delphi IDE之menu中project|ViewSource看到.dpr之Source, 你所有project中之unit均在此, form也一目了然, 可用TStringlist Load此檔, 一行行讀 不過在RunTime只有Exe 的情況下應該找不到此檔, 除非你預先用此工具讀出寫在一個檔中, 供RunTime讀物 3. 其實, 所有的Dfm均會以Resource方式存在EXE中, 直接讀Exe檔內之Resource[RCDATA]之部分即可建立所有dfm之list, 可參考delphix\demos\resxplor, 如果打算如此做, 還有問題我可以寫給你看 4. 如果你是要選FormClass之Name來動態Create Form, 到此即使建立了Form Name的List問題還是未解決, 有了name你還是必須FindClass, 或GetClass來取得Form 之class, 故所有Form在initialization 還是必須加上RegisterClass, (可Search一下本站),否則是找不到的
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-11-14 09:46:54 IP:218.170.xxx.xxx 未訂閱
感謝 ccchen 兄的回覆,我想這就是我所要的。 我也知道將所有Form移至Auto-create forms是不合理的,但在沒有資料可尋之下也只有使用了。如今依兄之所言,在[RCDATA]的資料雖然不完全是我自行RegisterClass的,但我可用命名技巧去克服此一問題,雖然尚實作出來,但應該是可以才對。 在此再次感謝您的指導,使我得以成長。
ccchen
版主


發表:61
回覆:940
積分:1394
註冊:2002-04-15

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-11-14 10:15:47 IP:218.163.xxx.xxx 未訂閱
雖已結案再討論一下吧: 1. 其實william兄所說可能是最恰當解法, 因為既然每一Form都要在initial part去Registerclass, 稍改一下宣告一個global 的TStringlist,再Registerclass的同時也Register到自己的TStringlist中, 處理起來是很方便 2. 我們做ERP, 一個dpr中常有4,5百個form, form架構由自己寫的source generator產生, 一定有Register form 之class 所有form 經由menu呼叫, menu由讀取sa文件而來, Unit name 配合Menu Name,因此完全不須煩惱這些問題 click Menu Item 自然會去GetClass找到FormClass來create 3. 另一個想法: 在classes.pas中, findClass其實是在RegGroups中找, 因此所有已Register之class應該都可以找的到, 可惜有用的東西都是private. 應該還是有方法在Memory中找到的, 只是還未找到方法
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-11-20 16:58:37 IP:218.170.xxx.xxx 未訂閱
我之所以會如此做,主要是因為一個專案通常都是經由數個人合力完成的,獨自一個人都會發生程式忘記登錄的狀況,更何況在人多的時候? 是故當初就想到,即然每一個非Auto-create的Form幾乎都會存在在Project->Options->Available Forms中,若我能得到該項資訊, 一.可以管理專案的程式。 二.可依此給予不同使用者在該程式上的權限設定。 三.加上如同ccchen兄所言之GetClass找到FormClass來create,既方便,又可 達到管理上的效果。 可惜一直苦無其門,才提出此一問題,請本站各位先進給予指教。 正如同ccchen兄第三項所言,因為是private,由該方法產生Form的子Form都不去呼叫其父Form,因為若呼叫,則會產生錯誤,是故我儘量以傳送物件或訊息方式將父Form的資料傳給子Form,這是我現在所能想到的方法了,若ccchen兄有發現其它方法,希望能給予小弟指導。 在此還是要謝謝各位參與討論的先進,因為有你們的熱心,才有今天的結果,再次謝謝。
JackTasy
初階會員


發表:22
回覆:97
積分:28
註冊:2002-06-06

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-11-26 10:12:55 IP:61.220.xxx.xxx 未訂閱
各位前輩,雖然本問題已經結案但我仍有一疑問希望確認! 我之前也一直希望能有方法可以在 MainForm 動態 Create ChildForm,即使增加 ChildForm 也不需要改 MainForm SourceCode,但前陣子努力沒有找到解決方法(除了用 DLL or BPL 方式可以,但我不要這兩種方式寫法) 看了上述各位的討論得知要達此類似功能必須 RegisteClass ...FindClass...GetClass 等等的,就如 『TI16502 Creating a form based on a string』所展示的技術類似,但要能 RegisterClass 必須要 Uses ChildForm!! 這樣就無法不改 MainForm 了。 so,我的問題就是,可否不要 uses Childform.pas 而達到上述功能要求呢?? 謝謝! (bpl 使用 LoadPackage 來載入,而一般做法則是使用 uses ,所以我想可能還是必須要 uses 要產生的子 Form 才行吧,不知道對不對...??) JackTasy
------
JackTasy
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-11-29 20:27:03 IP:218.174.xxx.xxx 未訂閱
JackTasy兄的問題,其實ccchen兄在網上已發表了多篇相關的文章,我也從ccchen兄那學了不少有關的東西。 其實在 MainForm 動態 Create ChildForm,而不要 uses Childform.pas ,的最主要的問題,在我看來最主要的問題是在你如何告知程式要開啟那一個Form?這就就我之所以要提出這個主題的所在,如何取得在該支程式的所有Form的FormName Class,再將該資訊提供給該程式Form管理程式。 因為我是採樹狀程式清單,所以在點選樹狀葉時,就會提供該葉所對映的Form Name,我在MainForm就可以自動去開啟該程式,而不需去修改MainForm,更不必去 uses ChildForm了。 只是當初我在使用此方法時,碰到下列問題 1.如果是採用"物年寶庫"繼承的方式,要如何開啟。 2.如果在開啟該Form時要傳入資料時,要如何依不同Form之所需去傳送資料。 所幸在一一解決中。 所以我認為JackTasy兄應該都可解決,因為都可以實作出來。
JackTasy
初階會員


發表:22
回覆:97
積分:28
註冊:2002-06-06

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-12-01 12:19:53 IP:61.220.xxx.xxx 未訂閱
請問 Wesly ,如果可以是否可以說明一下做法呢? 因為我嘗試用上述相關做法必須要先 uses 否則編譯時期就不過通過。 如果是可行的話我想可能是我某個關鍵點沒有作對吧,希望 Wesly 可以指點迷津或告訴我哪裡有相關資源可以 Study,謝謝! ps: FormName And ClassName 都是已知狀況下了 JackTasy
------
JackTasy
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-12-04 08:52:15 IP:218.170.xxx.xxx 未訂閱
我上傳了一個檔案 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=41589 請參考,希望對你有幫助
JackTasy
初階會員


發表:22
回覆:97
積分:28
註冊:2002-06-06

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-12-08 00:16:23 IP:211.76.xxx.xxx 未訂閱
剛下載稍稍看了一下可以 Run 了,且 MainForm 不需要 Use 子 Form !! 太棒了,這就是我要的,真是太感激了,謝謝! 接下來我會好好研究程式碼,再次說聲謝謝! 這樣的文章應該也希望被列入當週精選.    <>< face="Verdana, Arial, Helvetica">引言: 我上傳了一個檔案 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=41589 請參考,希望對你有幫助 JackTasy
------
JackTasy
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#19 引用回覆 回覆 發表時間:2003-12-08 08:40:29 IP:211.21.xxx.xxx 未訂閱
引言: ...這樣的文章應該也希望被列入當週精選. ... < face="Verdana, Arial, Helvetica"> 如果 Wesly 兄上傳的檔案內容經過消化整理放在本頁頁面上 那真的就更完美了...
shaofu
高階會員


發表:5
回覆:136
積分:103
註冊:2003-01-07

發送簡訊給我
#20 引用回覆 回覆 發表時間:2003-12-08 10:55:48 IP:210.243.xxx.xxx 未訂閱
引言: 如果 Wesly 兄上傳的檔案內容經過消化整理放在本頁頁面上 那真的就更完美了...
看了一下, 基本上 Wesly 兄的 Demo 有兩個重點: 1. Exe 檔的分析, 從 RCData 段抓取出所有專案中 Form 的 ClassName 2. GetClass, RegisterClass 的運用, 使其不用 use unit, 就能操作其他的 form 對於如果是已知 ClassName 的情況下 (JackTasy兄的需求?), 1 的部份是可以跳過不看 <>< face="Verdana, Arial, Helvetica">引言: 在classes.pas中, findClass其實是在RegGroups中找, 因此所有已Register之class應該都可以找的到, 可惜有用的東西都是private. 應該還是有方法在Memory中找到的, 只是還未找到方法 這部份 ccchen 兄說的 private 應該是指 RegGroups 躲在 implementation 裏吧? 跟 Wesly 兄說的 form 關係應該是無關的.. 不過既然 VCL 沒開放就是沒辦法了, 除非 recompile classes.pas.. 發表人 -
Miles
尊榮會員


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

發送簡訊給我
#21 引用回覆 回覆 發表時間:2003-12-08 14:21:58 IP:218.160.xxx.xxx 未訂閱
抱歉插個花馬後炮一下, 這一篇真是太神奇了, 沒地方可以加分, 不然就給Wesly加分. 我不是高手, 高手是正在銀幕前微笑的人.
------


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


發表:22
回覆:97
積分:28
註冊:2002-06-06

發送簡訊給我
#22 引用回覆 回覆 發表時間:2003-12-08 23:59:32 IP:211.76.xxx.xxx 未訂閱
引言: 如果 Wesly 兄上傳的檔案內容經過消化整理放在本頁頁面上 那真的就更完美了...
這樣的小事讓小弟來代勞就可以了 特別聲明 原著是 Wesly 喔! 感謝他的無私奉獻,我會在下個專案中採用這種機制!
procedure TForm1.Button1Click(Sender: TObject);
var
  aFormClass : TPersistentClass;
  fakeForm : TForm;
  isHaveToCreate : Boolean;
  sFormClassName,sFormName : String;
  i, j: Integer;
begin
  sFormClassName := Edit1.Text;  //<-Edit1 輸入要開啟的 FormClassName ex:TForm2      aFormClass := GetClass(sFormClassName);
  if Assigned(aFormClass) then
  begin
      isHaveToCreate := True;
      j := -1;
      sFormName := Copy(sFormClassName, 2, Length(sFormClassName) - 1);
      //檢查是否已開啟
      for i := 0 to Screen.FormCount - 1 do
        if Screen.Forms[i].Name = sFormName then
        begin
          isHaveToCreate := False;
          j := i;
          break;
        end;
      //Form 的處理
      if isHaveToCreate then
      begin //建立新的From
        if aFormClass.ClassParent = TForm then
        begin
          Application.createForm(TComponentClass(aFormClass), fakeForm);
          fakeForm.Show;
        end
      end
      else if j > -1 then
        Screen.Forms[j].Show;
  end
  else ShowMessage(sFormClassName   ' not RegisterClass!!');
end;    ------------------------------------
另外在其他被開啟的 Form 中最後加入如下簡單兩行程式碼:    initialization                   //*
  RegisterClass(TForm2);         //*
end.    
這樣就行啦! JackTasy
------
JackTasy
Wesly
中階會員


發表:14
回覆:103
積分:53
註冊:2002-05-31

發送簡訊給我
#23 引用回覆 回覆 發表時間:2003-12-10 09:08:53 IP:218.170.xxx.xxx 未訂閱
謝謝JackTasy的幫忙,其實我也不是原著,上傳檔案之所以可以出現,必須要感謝本站上的諸位先進,因為他們的無私,我才得以將內容整理出來,在此要謝謝ccchen兄,我從他的相關文件才得以整理出。 因為最近在忙公事,本來要將由物件寶庫繼承Form的呼叫方法整理一下,某些關係,所以無法全部推出,請見諒,大約是下星期吧。 其實得到上列方法,問題才開始,如何將資訊傳出至該Form內,如何將自動開啟的Form完全關閉,不佔用記憶體,也是要特別留意的。
JackTasy
初階會員


發表:22
回覆:97
積分:28
註冊:2002-06-06

發送簡訊給我
#24 引用回覆 回覆 發表時間:2003-12-11 23:32:16 IP:211.76.xxx.xxx 未訂閱
引言: 謝謝JackTasy的幫忙,其實我也不是原著,上傳檔案之所以可以出現,必須要感謝本站上的諸位先進,因為他們的無私,我才得以將內容整理出來,在此要謝謝ccchen兄,我從他的相關文件才得以整理出。 因為最近在忙公事,本來要將由物件寶庫繼承Form的呼叫方法整理一下,某些關係,所以無法全部推出,請見諒,大約是下星期吧。 其實得到上列方法,問題才開始,如何將資訊傳出至該Form內,如何將自動開啟的Form完全關閉,不佔用記憶體,也是要特別留意的。
1.Wesly 兄太客氣了,你把研究成果完整的Source Post上來縮短大家學習曲線,實為難得。 2.希望能看到還有新作喔
------
JackTasy
系統時間:2024-11-23 1:32:13
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!