C++Builder (BCB) 雖無 VB 式的原生控件數組,但利用 TList 容器可實現**更強大**的異構控件集合:不同類型控件(TEdit、TImage、TButton…)可混合存放、統一遍歷、批量操作屬性/事件。本文通過完整實例演示動態創建、維護混合類型控件數組的核心技巧。
TList 存儲 void* 指針,可容納任意 TControl 子類對象;(TImage*)List->Items[i])再訪問成員;class TForm1 : public TForm {
__published:
TPanel *Panel1, *Panel2;
TButton *Button1, *Button2, *Button3, *Button4;
private:
TList *MyVCL; // 控件數組容器
public:
__fastcall TForm1(TComponent* Owner);
virtual __fastcall ~TForm1();
};
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
MyVCL = new TList;
}
__fastcall TForm1::~TForm1() {
// 注意:TList 不擁有對象所有權,控件由 Owner (Form) 自動釋放
delete MyVCL;
}
void __fastcall TForm1::Button1Click(TObject *Sender) {
int top = 5;
for (int i = 0; i < 4; ++i) {
// TEdit 1: 序號
TEdit *editNo = new TEdit(this);
editNo->Parent = Panel1;
editNo->Text = IntToStr(i);
editNo->ReadOnly = true;
editNo->SetBounds(10, top, 24, 24);
MyVCL->Add(editNo);
// TImage: 圖標
TImage *img = new TImage(this);
img->Parent = Panel1;
img->Picture->LoadFromFile("None.BMP");
img->SetBounds(editNo->Left + editNo->Width, top, 24, 24);
MyVCL->Add(img);
// TEdit 2: 狀態文本
TEdit *editStatus = new TEdit(this);
editStatus->Parent = Panel1;
editStatus->Font->Name = "Arial";
editStatus->Font->Size = 12;
editStatus->Text = "禁止訪問";
editStatus->ReadOnly = true;
editStatus->SetBounds(img->Left + img->Width, top, 80, 24);
MyVCL->Add(editStatus);
top += 29; // 24 高 + 5 間距
}
Button1->Enabled = false;
Button2->Enabled = true;
}
void __fastcall TForm1::Button2Click(TObject *Sender) {
for (int i = 0; i < 4; ++i) {
// 每組 3 個控件,索引 1 為 TImage
TImage* img = dynamic_cast<TImage*>(MyVCL->Items[i * 3 + 1]);
if (img) img->Parent = Panel2;
}
Button2->Enabled = false;
Button3->Enabled = true;
}
void __fastcall TForm1::Button3Click(TObject *Sender) {
for (int i = 0; i < 4; ++i) {
TImage* img = dynamic_cast<TImage*>(MyVCL->Items[i * 3 + 1]);
if (img) img->Parent = Panel1;
}
Button3->Enabled = false;
Button2->Enabled = true;
}
void __fastcall TForm1::Button4Click(TObject *Sender) { Close(); }
| 技巧 | 說明 |
|---|---|
| 異構存儲 | TList 無類型限制,一個容器管理所有控件 |
| 安全轉型 | 推薦 dynamic_cast (RTTI) 替代 C 風格強轉,失敗返回 nullptr |
| 所有權清晰 | 控件 Owner=this,由 Form 自動銷毀;TList 僅持有指針 |
| 事件共享 | 不同類型控件可綁定同一 OnClick 等事件,通過 Sender 區分 |
| 索引規律 | 按創建順序固定索引模式,或改用 std::vector<std::variant<...>> (C++17) 更類型安全 |
此方案在 BCB 3.0/4.0 + Win95/98 驗證通過,對現代 C++Builder 版本同樣適用。掌握 TList 控件數組模式,能大幅簡化動態界面構建與批量操作邏輯。