1.創建組件的類聲明
class PACKAGE 新類名 : public 祖先類名
{
private:私有數據:
(1)內部私有用
(2)發布屬性的真正數據保存
(3)發布事件的數據保存
(1,2,3)私有數據初始化一般在構造函數中,(3)的初始化一般與祖先該事件相連。
通常為方便直接調用祖先方法常加保存祖先類型的變量:typedef 祖先類名 Inherit;
私有方法:僅在類定義內部使用,不希望被繼承使用,不希望公開使用。(盡量寫成通用函數)
protected:保護數據:一般很少用。
保護方法:一般是虛函數。在類定義時內部使用,對象不能直接調用,並把公開與否控制權給其派生類其派生類可以用重定義該方法,並可將其公開。
public:公有數據:一般屬性,但不屬於發布(即設計期不能操作)屬性並不是真正的數據需要私有數據來保存屬性,操作屬性通過方法。常用的定義如:
方式1:
__property AnsiString ItemData={read=FItemData,write=FItemData,default="A"};
方式2:
__property AnsiString ItemData={read=GetItemData,write=SetItemData,default="A"};
FItemData是其數據私有保存處GetItemData(),SetItemData()是實現讀寫函數,其內部除了設置數據外還可以加相應的處理代碼,這部份處理就是屬性的最大優點。即通過直接修改屬性既實現了數據的讀寫又可實現的代碼處理,然而用戶的感覺好像是只作了數據的改,正是這點“副作用”所帶來的。
另外如果對屬性的修改不需要響應處理則只用定義方式1就行了。
公有方法:實現類的封裝,改變數據成員都通過公有函數。(Method)重定義函數通常的先調用祖先類的該方法Inherit::XXX();(Inherit已說明,XXX表函數名), 然後再寫自身要作的處理代碼。
__published:發布屬性:同公有部分的屬性,區別在於發布屬性在設計期可直接通過對象觀察器修改。祖先類已發布的屬性,最好在此作確認。
順便指出方法不宜寫在發布聲明處,屬性同樣可寫成公有或私有,但是它們是無法在設計期訪問的,私有屬性僅在內部使用不向用戶提供。
}
寫組件應盡量多用屬性,而少用方法。只有屬性無法完成的工作才由方法來完成。
發布事件:
1.普通事件:參數唯一僅有TObject *Sender,一般用TNotifyEvent(指針類型)
如:__property TNotifyEvent OnExit={read=FOnExit,write=FOnExit} ;
同屬性一樣需要私有數據來保存事件指針。
TNotifyEvent FOnExit;另外是事件處理代碼。
void __fastcall MyOnExit(System::TObject *Sender)其實現代碼中由 FOnExit(Sender)語句觸發事件;(注意事件處理函數返值void)
2.特殊事件:
首先:需定義事件類型指針(類似於函數指針的定義)
typedef void __fastcall (__closure *TKeyDownEvent)(System::TObject* Sender, WORD &Key,TShiftState Shift);
其次:要有數據保存處。在private處聲明:如 TKeyDownEvent FOnKeyDown ;
再次:有相應事件處理函數一般在protected處聲明。如
protected:virtual void __fastcall MyOnKeyDown(System::TObject *Sender, WORD &Key,TShiftState Shift);
代碼中常有 FOnKeyDown(Sender,Key,Shift)
最後:設定連接(需要提供前三者:事件指針類型,數據存放處變量,事件處理函數)。
__property TKeyDownEvent OnKeyDown={read=FOnKeyDown,write=FOnKeyDown}; };
組件檢驗及注冊static inline void ValidCtrCheck(新類名 *){new 新類名(NULL);}
確保該控件聲明中沒有純虛函數,因為虛基類是不能生成實例的。
namespace 名稱空間
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(新類名)};
}
RegisterComponents("所屬包名", classes, 0);
還可加屬性編輯器說明 RegisterPropertyEditor(...)}}名稱空間是個C++特性,利用此Register()函數才可以區分其它控件。此命名必須符合規范,跟控件所在的文件名有關。如 TMyButton在 mybutton.cpp中則此命名空間為Mybutton.用New Component對話框生成新組件,不用考慮該問題。