首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C++Builder 元件開發深度解析:類聲明結構、屬性/事件/方法設計模式、註冊機制

     編輯:VC 教學

元件類聲明標準結構


class PACKAGE TMyComponent : public TComponent  // 或 TControl/TCustomControl
{
private:    // 內部實作細節
    // 1. 儲存屬性真實值的欄位
    int FMyProperty;
    // 2. 儲存事件處理器的欄位
    TNotifyEvent FOnMyEvent;
    // 3. 內部輔助方法
    void InternalUpdate();

protected:  // 衍生類可存取/覆寫
    // 1. 虛擬方法:衍生類可擴充行為
    virtual void __fastcall DoMyEvent();
    // 2. 訊息處理函數
    void __fastcall WMPaint(TMessage& Msg);

public:     // 執行期/設計期可存取 (非設計期可見)
    // 1. 建構/解構
    __fastcall TMyComponent(TComponent* Owner);
    __fastcall ~TMyComponent();
    // 2. 公開方法 (行為)
    void __fastcall RefreshData();
    // 3. 非發布屬性 (執行期可用,物件檢視器不可見)
    __property int RuntimeOnlyProp = {read=FRuntimeProp, write=SetRuntimeProp};

__published: // 設計期可見 (物件檢視器、屬性編輯器、串流)
    // 1. 發布屬性
    __property int MyProperty = {read=FMyProperty, write=SetMyProperty, default=0, nodefault};
    // 2. 發布事件
    __property TNotifyEvent OnMyEvent = {read=FOnMyEvent, write=FOnMyEvent};
};

屬性設計模式

模式語法適用場景
直接欄位存取__property int Prop = {read=FProp, write=FProp};簡單資料,無副作用
存取函數__property int Prop = {read=GetProp, write=SetProp};需驗證、觸發更新、副作用 (如重繪、通知)
預設值default=0 / nodefault減少 DFM 檔案體積,設計期顯示粗體
陣列屬性__property int Items[int] = {read=GetItem, write=SetItem};索引式存取
預設屬性__property int Items[int] = {read=GetItem, write=SetItem, default};Comp[0] 可簡寫為 Comp[0] (同樣),主要用於 default 指示器

事件設計模式

標準事件 (無參數/僅 Sender)


// 類型定義 (系統已定義)
typedef void __fastcall (__closure *TNotifyEvent)(System::TObject* Sender);

// 成員欄位
TNotifyEvent FOnClick;

// 發布
__property TNotifyEvent OnClick = {read=FOnClick, write=FOnClick};

// 觸發方法 (protected virtual 允許衍生類擴充)
virtual void __fastcall DoClick() {
    if (FOnClick) FOnClick(this);  // 呼叫使用者處理器
}

自訂參數事件


// 1. 定義事件類型 (函數指標)
typedef void __fastcall (__closure *TMyKeyEvent)(System::TObject* Sender, WORD& Key, TShiftState Shift);

// 2. 成員欄位
TMyKeyEvent FOnMyKey;

// 3. 觸發方法
virtual void __fastcall DoMyKey(WORD& Key, TShiftState Shift) {
    if (FOnMyKey) FOnMyKey(this, Key, Shift);
}

// 4. 發布
__property TMyKeyEvent OnMyKey = {read=FOnMyKey, write=FOnMyKey};

元件註冊與設計期安裝


// 同名命名空間 (慣例:檔名 MyComp.cpp → namespace Mycomp)
namespace Mycomp {
    // 設計期驗證 (防止抽象類被放入調色盤)
    static inline void ValidCtrCheck(TMyComponent*) {
        new TMyComponent(NULL);  // 若有純虛函數會編譯錯誤
    }

    void __fastcall PACKAGE Register() {
        TComponentClass classes[1] = { __classid(TMyComponent) };
        RegisterComponents("My Components", classes, 0);  // 調色盤分頁名
    }
}

進階技巧

  • 屬性編輯器:RegisterPropertyEditor(__typeinfo(AnsiString), TMyComponent, "MyProperty", __classid(TMyStringPropertyEditor)) 自訂下拉/對話框編輯。
  • 元件編輯器:RegisterComponentEditor(__classid(TMyComponent), __classid(TMyComponentEditor)) 加入右鍵選單動詞 (如「設定精靈」)。
  • 串流處理:覆寫 DefineProperties 儲存非發布資料;Loaded 讀取後初始化。
  • 包裝 ActiveX:TActiveXControl 基類,DECLARE_OLECONTROL 巨集。

常見錯誤

  • 發布區塊放入方法 (僅屬性/事件)。
  • write 指定非 __fastcall 函數。
  • 事件類型未加 __closure (BCB 關鍵字,表示成員函數指標)。
  • 忘記 PACKAGE 關鍵字 (動態套件導出/導入修飾)。
  • 設計期驗證 ValidCtrCheck 缺失導致抽象類被實例化 Crash。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved