如何在執行程式時取得在"Available forms"內之所有Form的名稱? |
尚未結案
|
Wesly
中階會員 發表:14 回覆:103 積分:53 註冊:2002-05-31 發送簡訊給我 |
|
hagar
版主 發表:143 回覆:4056 積分:4445 註冊:2002-04-14 發送簡訊給我 |
|
Wesly
中階會員 發表:14 回覆:103 積分:53 註冊:2002-05-31 發送簡訊給我 |
先在此謝謝 hagar 兄的回覆。 可能我的意思沒有表達清礎,因為我的Form是動態產生的,而我又想經由程式能夠取得該執行程式在Project->Options->Forms->Available forms之所有Form的名稱,但此時這些Form不一定已開啟。
我曾經使用TScreen.CustomFormCount 及 TScreen.CustomForms去取得Form的名稱,但它只針對已開啟的Form有效,功能似乎和 hagar 兄提供的方法差不多,不知我的測試是否正確,尚請指教。
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
Wesly
中階會員 發表:14 回覆:103 積分:53 註冊:2002-05-31 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
Wesly
中階會員 發表:14 回覆:103 積分:53 註冊:2002-05-31 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
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 發送簡訊給我 |
|
ccchen
版主 發表:61 回覆:940 積分:1394 註冊:2002-04-15 發送簡訊給我 |
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 發送簡訊給我 |
|
ccchen
版主 發表:61 回覆:940 積分:1394 註冊:2002-04-15 發送簡訊給我 |
雖已結案再討論一下吧:
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 發送簡訊給我 |
我之所以會如此做,主要是因為一個專案通常都是經由數個人合力完成的,獨自一個人都會發生程式忘記登錄的狀況,更何況在人多的時候? 是故當初就想到,即然每一個非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 發送簡訊給我 |
各位前輩,雖然本問題已經結案但我仍有一疑問希望確認!
我之前也一直希望能有方法可以在 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 發送簡訊給我 |
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 發送簡訊給我 |
|
Wesly
中階會員 發表:14 回覆:103 積分:53 註冊:2002-05-31 發送簡訊給我 |
|
JackTasy
初階會員 發表:22 回覆:97 積分:28 註冊:2002-06-06 發送簡訊給我 |
剛下載稍稍看了一下可以 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 發送簡訊給我 |
|
shaofu
高階會員 發表:5 回覆:136 積分:103 註冊:2003-01-07 發送簡訊給我 |
引言: 如果 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 發送簡訊給我 |
|
JackTasy
初階會員 發表:22 回覆:97 積分:28 註冊:2002-06-06 發送簡訊給我 |
引言: 如果 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 發送簡訊給我 |
|
JackTasy
初階會員 發表:22 回覆:97 積分:28 註冊:2002-06-06 發送簡訊給我 |
引言: 謝謝JackTasy的幫忙,其實我也不是原著,上傳檔案之所以可以出現,必須要感謝本站上的諸位先進,因為他們的無私,我才得以將內容整理出來,在此要謝謝ccchen兄,我從他的相關文件才得以整理出。 因為最近在忙公事,本來要將由物件寶庫繼承Form的呼叫方法整理一下,某些關係,所以無法全部推出,請見諒,大約是下星期吧。 其實得到上列方法,問題才開始,如何將資訊傳出至該Form內,如何將自動開啟的Form完全關閉,不佔用記憶體,也是要特別留意的。1.Wesly 兄太客氣了,你把研究成果完整的Source Post上來縮短大家學習曲線,實為難得。 2.希望能看到還有新作喔
------
JackTasy |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |