在 C++Builder 中動態建立控制項(無論是內建或繼承類別),只需遵循固定流程:
#ifndef MemoExH
#define MemoExH
#include
#include
class TMemoEx : public TMemo {
public:
__fastcall TMemoEx(TComponent* Owner);
// 可在此擴充自訂屬性/方法/事件
void __fastcall AppendTimestamp();
};
#endif
#include
#pragma hdrstop
#include "MemoEx.h"
__fastcall TMemoEx::TMemoEx(TComponent* Owner) : TMemo(Owner) {
// 建構時可預設屬性
Font->Name = "Consolas";
Font->Size = 10;
Color = clInfoBk;
}
void __fastcall TMemoEx::AppendTimestamp() {
Lines->Add(FormatDateTime("yyyy-mm-dd hh:nn:ss", Now()));
}
// MainForm.h
#include "MemoEx.h"
class TForm1 : public TForm {
__published:
// IDE 管理元件...
private:
TMemoEx* MemoEx; // 指標成員
public:
__fastcall TForm1(TComponent* Owner);
};
// MainForm.cpp
#include
#pragma hdrstop
#include "MainForm.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
// 動態建立於 FormShow 或建構函數中
MemoEx = new TMemoEx(this); // 1. Owner = this,自動釋放
MemoEx->Parent = this; // 2. 關鍵:加入視覺父層
MemoEx->Left = 10;
MemoEx->Top = 10;
MemoEx->Width = 300;
MemoEx->Height = 200;
MemoEx->Align = alClient; // 選填:自動填滿客戶區
MemoEx->Visible = true; // 預設 true,可省略
}
| 步驟 | 代碼 | 作用 | 常見錯誤 |
|---|---|---|---|
| 建立實例 | new TMemoEx(this) | Owner 設為視窗,視窗銷毀時自動 delete | 傳 NULL 導致記憶體洩漏 |
| 設定 Parent | MemoEx->Parent = this | 納入視覺樹,處理繪製/訊息/Tab 順序 | 忘記此行 → 控制項不顯示但編譯通過 |
| 設定幾何屬性 | Left/Top/Width/Height/Align | 決定位置大小 | 未設定 → 位置 (0,0) 大小 (0,0) 不可見 |
| 事件綁定 | MemoEx->OnChange = MemoExChange | 動態掛載事件處理函數 | 函數簽名必須符合 VCL 事件類型 |
// 獨立函數建立帶自訂控制項的視窗
TForm* CreateDynamicForm() {
TForm* frm = new TForm(Application);
frm->Caption = "Dynamic Form";
frm->Position = poScreenCenter;
TButton* btn = new TButton(frm);
btn->Parent = frm;
btn->Caption = "Click Me";
btn->SetBounds(50, 50, 100, 30);
btn->OnClick = [](TObject* Sender) {
ShowMessage("Dynamic Button Clicked!");
};
return frm; // 呼叫端負責 ShowModal / 釋放
}
動態建立 VCL 控制項的核心口訣:「Owner 管理生命,Parent 管顯示,幾何定位置,事件加行為」。掌握此模式,即可在執行期靈活構建複雜介面、實現插件化 UI、減少 DFM 檔案耦合。