如何將寫好的萬年曆.EXE 之主 Form 轉成一個元件 |
尚未結案
|
bruce0211
版主 發表:157 回覆:668 積分:279 註冊:2002-06-13 發送簡訊給我 |
我寫好一個萬年曆
標準的寫法,只有一個Project 和主 Form ,
Compiler 成一個 萬年曆.exe
測試 OK 現想將其轉成一個元件
但手邊的資料都是繼承簡單元件而成新的元件
我想是否現在要繼承一 TForm 元件
然後再將我原本的 萬年曆 的程式碼全超過來
該 Public 的就 Public
有沒快速的方法將一般的 Form1 (以寫好程式碼在裡面)
快速的轉成一個 VCL ?? 如果 這個 TMyForm 將來不能當成 vcl 放到主 Form 上
那類似自己寫的萬年曆這種東西
要以哪個元件當繼承 base 呢 ?
因為我萬年曆上面不只是只有 Grid, 還有 button 等其他元件
所以不能像 delphi sample 中的 萬年曆直接繼承 TCustomGrid ...
TCalendar = class(TCustomGrid) 發表人 - bruce0211 於 2003/11/06 14:09:59
|
pedro
尊榮會員 發表:152 回覆:1187 積分:892 註冊:2002-06-12 發送簡訊給我 |
|
bruce0211
版主 發表:157 回覆:668 積分:279 註冊:2002-06-13 發送簡訊給我 |
找到方法了
我發現使用 Form 為 base 的元件可能是所有元件設計中最簡單的方式(因為設計核心時是在一般專案中設計並測試,且可放入任何你想要的元件,如果不是以 Form 為 base 的元件,光想想我們要設計將兩個元件聚合成為一個新元件就已經多不直多困難)
1.設計帶有 Form 的元件,如萬年曆,獨立的對話盒等等,通常這種類型的元件在 user 主 form 中是一不可視元件,也就是插到 Delphi 中只是一個 ICON 而已
(如標準的檔案開啟對話盒元件 TOpenDialog) ,需要用時再利用 if OpenDialog1.Execute then ... 這種方式去呼叫
2.由於這類元件不需在主畫面佔據位置,而是被獨立呼叫(就像是 ShowModal),所以設計元件時可以一般方法設計(可放入許多及任何元件的組合在裡面),如我要設計萬年曆,先用一般方式開一 Project1 專案,以及萬年曆的 unit1.pas & unit1.dfm , 將萬年曆內容寫好,並可 compiler 測試 ok (叫做 project1.exe),我們便可丟掉 project1.* 的檔案,只留下 unit1.pas 及 unit1.dfm 這兩個萬年曆的核心
3.開始設計元件,元件類別繼承自 TComponent , 也就是拿 TComponent 當藥引子,替 TComponent 增加一個公開的方法 "Execute" , 以及 Date 屬性 , 執行 Execute 時, TComponent 實際上是去呼叫完整的萬年曆程式,再將日期回傳 以下為 TMyCalendar 的元件內容 , 可以看出萬年曆程式碼並未寫在裡面,而是另外呼叫 MyCalendarSource.pas (也就是上面舉例的 Unit1.pas) , 而MyCalendarSource.pas 之 Form 名稱叫 FormMyCalendar (也就是上面舉例的 Unit1.dfm) , 整個TMyCalendar 只是當作藥引子 , 實際上萬年曆的程式碼是寫在 MyCalendarSource.pas 中的 其他類似的元件也可依樣畫葫蘆,先用一般方法設計專案設計 Form,測試 OK 後 , 留下 Form 這個部分的程式碼,再套到這個藥引子中
unit MyCalendar; interface uses SysUtils, Classes, Forms, MyCalendarSource; type TMyCalendar = class(TComponent) private { Private declarations } FDate: TDateTime; FRocYear: string; FRocMonth: string; FRocDay:string; procedure DateToRoc(ADate:TDateTime); protected { Protected declarations } public { Public declarations } constructor Create(AOwner : TComponent); override; destructor Destroy; override; function Execute: boolean; overload;//本元件公開的方法 function Execute(ALeft,ATop: integer): boolean; overload; ;//本元件公開的方法(可指定萬年曆出現的座標位置,復疊函式) published { Published declarations } property Date:TDateTime read FDate; //本元件公開的屬性,日期 property RocYear:string read FRocYear; //本元件公開的屬性,民國年 property RocMonth:string read FRocMonth; //本元件公開的屬性,民國月 property RocDay:string read FRocDay;//本元件公開的屬性,民國日 end; procedure Register; implementation constructor TMyCalendar.Create(AOwner : TComponent); begin inherited Create(AOwner); FDate := SysUtils.Date; DateToRoc(FDate); end; destructor TMyCalendar.Destroy; begin inherited Destroy; end; function TMyCalendar.Execute: boolean; var r:integer; begin FormMyCalendar:=TFormMyCalendar.Create(nil); try r:=FormMyCalendar.ShowModal; if r=1 then //mrOK; begin FDate:=FormMyCalendar.SelectDate; DateToRoc(FDate); result:=true; end else result:=false; finally FormMyCalendar.Release; end; end; function TMyCalendar.Execute(ALeft,ATop: integer): boolean; var r:integer; begin FormMyCalendar:=TFormMyCalendar.Create(nil); FormMyCalendar.Position:=poDesigned; FormMyCalendar.Top:=ATop; FormMyCalendar.Left:=ALeft; try r:=FormMyCalendar.ShowModal; if r=1 then //mrOK; begin FDate:=FormMyCalendar.SelectDate; result:=true; end else result:=false; finally FormMyCalendar.Release; end; end; procedure TMyCalendar.DateToRoc(ADate:TDateTime); var TmpYear, TmpMonth, TmpDay : Word; begin DecodeDate(ADate, TmpYear, TmpMonth, TmpDay); FRocYear:=FormatFloat('00',TmpYear-1911); FRocMonth:=FormatFloat('00',TmpMonth); FRocDay:=FormatFloat('00',TmpDay); end; procedure Register; begin RegisterComponents('MyWay', [TMyCalendar]); end; end.發表人 - bruce0211 於 2003/11/22 11:05:22 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |