簡單承繼元件的另類方法 (不用 Register 不用 Runtime Create) |
|
Justmade
版主 發表:94 回覆:1934 積分:2030 註冊:2003-03-12 發送簡訊給我 |
一般來說我們對標準的 VCL 元件作修正或簡單加強都會用這兩種方法之一 :
1. 正式承繼元件,加入 Register procedure 及加入 Package 來加入到 元件面版中
好處 : 可直接在元件面版加入該新元件到 Form 中在 Design Time 設定好
壞處 : 比較麻煩及會弄到很多元件
時機 : 當這個元件常用時最好是 Register 了他 2. 在使用的 Form (或另外有 uses 的 unit) 即時定義,不註冊,在程式碼動態建立
好處 : 當只使用一次(或很少次)時較簡單,不用寫註冊程式,不用先做好 Package
壞處 : 若當用則重覆(可放到獨立 unit 避免),動態建立通常要寫較多碼去初始化元件 (如 Top/Left/Width/Height 等)
時機 : 當這些改變不常用不想特意做多一個元件到 元件面版時 最近看某舊文章時看到 CCChen 前軰使用了一個我之前沒見過的方法,自己試用後覺得很好用,最近答題亦多次用上,所以給大家作一參考。
這個方法類似第二種方法但不用動態建立元件,因為新承繼的元件名是和標準元件一樣,但由於是在當前的Unit (也可放在獨立 unit 但 uses 一定要放得比標準元件的 unit 後),所以在Runtime 時優先使了這個新承繼的 Class 來建立元件。 好處 :
同 2, 加上不用動態建立元件可直接使用標準元件並在 DesignTime 設好 壞處 :
新加的功能及參數在 DesignTime 不能看到和作用,只能在 RunTime 有作用和設定,另同一Form 所有元件均會使用這個新Class,除非手動加入原本元件的 Unit 名。 時機 :
2 的時機若沒有同一Form 要一些舊元件一些新元件都適用。有些小更改即使當用但若更改部份不需在 DesignTime 運作亦可用這個方法,只要寫在一獨立 unit, 要使用時 use 這 unit 並確定放到 List 中原本元件 unit 之後即可。 實作 :
重點在於 Class 的名字和原本的 Class 相同,所以承繼自的元件名要加上 unit 名。 請看以下範例將 Delphi 5 的 標準 TButton 變成可顯示多行的 Caption :
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TButton = Class(StdCtrls.TButton) protected procedure CreateParams(var Params : TCreateParams); override; end; TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} { TButton } procedure TButton.CreateParams(var Params: TCreateParams); begin inherited; Params.Style := Params.Style BS_MULTILINE; end; procedure TForm1.FormCreate(Sender: TObject); begin Button1.Caption := 'Line1'#13#10'Line2'; end; end.重點 : 1. 此新Class仍叫 TButton 2. 承繼自的元件列名出處unit : Class(StdCtrls.TButton) 3. 其他跟其他承繼方法一樣 4, RunTime 時 Button1: TButton; 會優先使用了本 unit 所定義的 TButton 而使 Button1 支援多行的 Caption 其他例子 : http://delphi.ktop.com.tw/topic.php?TOPIC_ID=33637 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=33559 |
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
|
Justmade
版主 發表:94 回覆:1934 積分:2030 註冊:2003-03-12 發送簡訊給我 |
他那個方法根基上是錯的。
1. 如該篇讀者回應所言,Edit1 內跟本沒
FDesignColor: TColor;
FReadOnly: boolean;
這兩個變數,由於這是簡單的變數,所以就會按當時 Edit1 這個 Object Field 的排列取出某 Address 的值當成是這兩個變數的值變成好像有值並可改變的樣子,但若這是Object 便會立即出錯了。 2. Edit1 在 Create / Loaded 時不會去執行 TMyEdit 的 Create / Loaded 罷,所以若有東西要初始化就跟本沒執行如 :
FDesignColor:= clWindow; / FDesignColor:= Color;
跟本就不會執行到 3. 需然一看便覺得有問題但我還是測試了一下,因由使用
TMyEdit(Edit1).ReadOnly := False;
時弄亂了 Edit1 的結構
Edit1.Free; 時便會有 AV 看了 (不是 Adult Vedio 是 Access Violation 啦) > 哈哈說笑啦這招我也是向 > 他的作法若是只加一些 >
你的例子完全乎合我所說的這點所以當然沒問題 (
|
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
他那個方法根基上是錯的。
1. 如該篇讀者回應所言,Edit1 內跟本沒
FDesignColor: TColor;
FReadOnly: boolean;
這兩個變數,由於這是簡單的變數,所以就會按當時 Edit1 這個 Object Field 的排列取出某 Address 的值當成是這兩個變數的值變成好像有值並可改變的樣子,但若這是Object 便會立即出錯了。 如您所言, 他這篇文章寫的內容確實有點問題; 他是第一次發表文章可能不熟悉, 不過只是範例有點問題, 就如您以上所言, 但觀念及想法是沒問題的, 至少我有一些元件是這樣寫的; 例如以下範例:
type TMyEdit = class(TEdit) private function GetEnabled: boolean; procedure SetEnabled(Value: boolean); published property Enabled: boolean read GetEnabled write SetEnabled; end; function TMyEdit.GetEnabled: boolean; begin Result := inherited Enabled; end; procedure TMyEdit.SetEnabled(Value: boolean); begin inherited Enabled:= Value; if not Value then Text := ''; end以上是當 Enabled = False 時將 Text 清空 2. Edit1 在 Create / Loaded 時不會去執行 TMyEdit 的 Create / Loaded 罷,所以若有東西要初始化就跟本沒執行如 : FDesignColor:= clWindow; / FDesignColor:= Color; 跟本就不會執行到 他這部份好像有人指正過, 而作者好像有作一些回應 ... 其實這篇文章說穿了重點就在 inherited 的應用而已 3. 需然一看便覺得有問題但我還是測試了一下,因由使用 TMyEdit(Edit1).ReadOnly := False; 時弄亂了 Edit1 的結構 Edit1.Free; 時便會有 AV 看了 (不是 Adult Vedio 是 Access Violation 啦) <>如前所言 ...> > 哈哈說笑啦這招我也是向 >這是我的錯! 忘了給您加分了(已經補上) ...< >> 以小弟之見,他的作法若是只加一些 >他這篇文章重點是在 <>如何取代已有之 > 這部份和您這篇文章關念有點相同, 只是您是取代 >
------
將問題盡快結案也是一種禮貌! |
shaofu
高階會員 發表:5 回覆:136 積分:103 註冊:2003-01-07 發送簡訊給我 |
|
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
|
pwq
一般會員 發表:5 回覆:13 積分:3 註冊:2002-03-13 發送簡訊給我 |
|
shaofu
高階會員 發表:5 回覆:136 積分:103 註冊:2003-01-07 發送簡訊給我 |
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
在一年前,我曾經提問 ■如何更新內建 VCL 元件
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=18519 那時 ccchen 版主就建議我使用這個方法,只可惜,這個方法只能在 Delphi 中使用,每每看到 Delphi 可以這樣亂搞... 喔不... 是 Delphi 的寫作可以如此自由隨心所欲,就想改用 Delphi 來開發
<>< face="Verdana, Arial, Helvetica">引言:
我在答題分500前想節省一下文章數所以在此回應你下面的問題,希望你別介意 :
哈哈,Justmade 版主,您也想提高每篇文章得分數及答題數嗎? 沒空更新的網頁...
http://dllee.ktop.com.tw C及指標教學,計算機概論,資訊管理導論... http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell....
------
http://www.ViewMove.com |
Justmade
版主 發表:94 回覆:1934 積分:2030 註冊:2003-03-12 發送簡訊給我 |
引言: ■如何更新內建 VCL 元件 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=18519我之前沒看過那篇文章,不過曾看過 CCChen 前輩在某文章答題的程式碼有使用這個方法,所以說 CCChen 前輩就是高手中的高手丫。 引言:我是作一個實驗,給自己一個目標,看有100篇文章內能逹到甚麼文章得分數及答題數。 結果用了十五天, 100篇文章裡佔了 7 篇恭賀相關文章,4篇發表相關文章,1篇版主相關文章 88 篇答題相關文章,54 答題得分 339.5分。 不過由於節省文章數所以 1. 不能發問問題 2. 在處理版務時警告只能發短訊 (他們大多沒看) 3. 刪不當文章時沒先回文告訴原因 4. 題問者加插非原本問題時只能不理 (跟進原問題才會繼續回答) 5. 不能完全回答問題但有一些提示可供參考時只好不答 6. 儘量不參與非必要的網友及版主討論 所以若太著重每篇文章得分數及答題數的話,也有不少不良後果的。這會鼓勵網友少互動,若對題目有些有用的資料但不完整時不貼出來分享等等。 對於站長版主就更不公平了,有時要執行版務有需要 post 職務上的文章,但越儘責的反而越會拖低這兩項參數。 所以我這種做法只限那一百篇文章,做了個實驗知道自己可做到便好,之後不這樣了。引言: 我在答題分500前想節省一下文章數所以在此回應你下面的問題,希望你別介意 :哈哈,Justmade 版主,您也想提高每篇文章得分數及答題數嗎? |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
引言: 所以若太著重每篇文章得分數及答題數的話,也有不少不良後果的。這會鼓勵網友少互動,若對題目有些有用的資料但不完整時不貼出來分享等等。 對於站長版主就更不公平了,有時要執行版務有需要 post 職務上的文章,但越儘責的反而越會拖低這兩項參數。哈哈,我最早提出這項統計資料,本來就不是要找出誰是最努力的版主或是副站長,而是要找出最努力最有價值的明日之星,對於答分在 10 幾 20 分的網友,就可能有很高的排名,這樣,可以提高新進者的參與感及成就感。 您的高分,已是讓人望塵莫及的了,這個每篇文章得分王及每篇文章答題王的頭銜還是讓給新人吧 <>沒空更新的網頁... href="http://dllee.adsldns.org">http://dllee.adsldns.org 介紹Shells,LiteStep,GeoShell....
------
http://www.ViewMove.com |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |