C＋＋Builder中实现控件数组的功能
(西安 张志明) Borland C＋＋ Builder作为Inprise（原Borland）公司新推出的快速应用程序开发工具（RAD），具有威力强大的C＋＋语言和快捷便利的可视化编程完美结合的优点，遗憾的是其没有直接提供像VB中的控件数组的功能，需要开发者自己编程实现。 VB中的一个控件数组可以1、允许多个控件共享同一个事件句柄，2、提供了运行期间增加一个控件的机制，3、提供了一种方便的组合控件的方法。前两项在C＋＋ Builder中早已实现，而且CB更有一个优点。即不同类型的控件可以使用相同的句柄（只需在相关控件的Object Inspector窗口中的EVENT事件设置即可）。 C＋＋ Builder中使用了Tlist类对象来组合控件数组，与VB控件数组元素必须为同一类型控件相比较，C＋＋ Builder中的Tlist类对象可以组合任意类型的控件而不必强求同一种类，这样就大大地方便了程序开发者。例如可以把在不同Panel面板控件上的所有控件组合为一个控件数组。 作者在开发实时监控程序时，应用Tlist类对象创建、维护了多类型的控件数组。其实现原理与方法详见以下的原程序代码。实例程序实现了动态创建一个包含8个TEdit类型控件和4个TImage类型控件的控件数组，在程序运行中对所创建的控件进行修改、维护的功能（简单起见，只对TImage控件的Parent属性进行了修改，对控件数组中各个控件的属性修改及事件处理句柄均可依此方法修改）。 1、创建一个新的工程文件（New Application），在Form1上放置两个TPanel类型的Panel1和Panel2,调整大小合适，再在窗体下方放置四个TButton类型Button1,Button2,Button3,Button4，设置控件属性如下：Button1－>Caption=“新建控件数组”，Button2－>Caption=“改变控件位置”， Button3－>Caption=“还原到原位置”， Button4－>Caption=“退出”；Button2－>Enabled=false，Button3－>Enabled=false。 （注：以下黑体字部分为需要手工添加的代码） 2、在文件Unit1.H中加入以下声明： class TForm1 : public TForm { __published: // IDE－managed Components TPanel ＊Panel1; TPanel ＊Panel2; TButton ＊Button1; TButton ＊Button2; TButton ＊Button3; TButton ＊Button4; private: // User declarations TList ＊MyVCL; public: // User declarations __fastcall TForm1(TComponent＊ Owner); virtual __fastcall ～TForm1( ); }; 3、切换到工程的Form界面，双击工程的主界面Form，创建一个OnCreate事件句柄，在文件Unit1.CPP中加入以下代码： void __fastcall TForm1::FormCreate(TObject ＊Sender) { MyVCL = new TList;//创建TList对象 } 将TForm1析构函数加入到文件Unit1.CPP中： __fastcall TForm1::～TForm1() { delete MyVCL; //删除TList对象 } 4、双击标签（Caption）为“创建控件数组”的按钮，创建一个OnClick事件句柄，添加以下代码到OnClick事件句柄中： void __fastcall TForm1::Button1Click(TObject ＊Sender) { //创建新的控件，调整其位置，并加入到MyVcl（TList 类）之中 int temptop=5; for (int i=0;i<4;i＋＋) { TEdit ＊EditNow = new TEdit(this); EditNow－>Parent=Panel1; EditNow－>Text= IntToStr(i); EditNow－>ReadOnly=true; EditNow－>Top=temptop; EditNow－>Height=24; EditNow－>Width=24; EditNow－>Left=10; MyVCL－>Add(EditNow); //加入到控件数组中 TImage ＊ImageOff= new TImage(this); ImageOff－>Parent=Panel1; ImageOff－>Picture－>LoadFromFile(“None.BMP”); ImageOff－>Top=temptop; ImageOff－>Height=24; ImageOff－>Width=24; ImageOff－>Left=EditNow－>Left＋EditNow－>Width; MyVCL－>Add(ImageOff); //加入到控件数组中 TEdit ＊EditStatus = new TEdit(this); EditStatus－>Parent=Panel1; EditStatus－>Font－>Name = “Arial”; EditStatus－>Font－>Size = 12; EditStatus－>Text=“禁止访问”; EditStatus－>ReadOnly=true; EditStatus－>Top=temptop; EditStatus－>Height=24; EditStatus－>Width=80; EditStatus－>Left= ImageOff－>Left＋ImageOff－>Width; MyVCL－>Add(EditStatus); //加入到控件数组中 temptop=temptop＋24＋5; } Button1－>Enabled=false; Button2－>Enabled=true; } 5、同4所示方法，依次双击标签的标题（Caption）为“改变控件位置”、 “还原到原位置”、 “退出”的按钮，创建对应的OnClick事件句柄，添加以下代码到对应的OnClick事件句柄中： void __fastcall TForm1::Button2Click(TObject ＊Sender) { for (int i=0;i<4;i＋＋) ((TImage＊)MyVCL－>Items[i＊3＋1])－>Parent=Panel2; Button2－>Enabled=false; Button3－>Enabled=true; } void __fastcall TForm1::Button3Click(TObject ＊Sender) { for (int i=0;i<4;i＋＋) ((TImage＊)MyVCL－>Items[i＊3＋1])－>Parent=Panel1; Button3－>Enabled=false; Button2－>Enabled=true; } void __fastcall TForm1::Button4Click(TObject ＊Sender) { Close(); //关闭窗体 } 由上所述，实际的代码大多只是用于设定控件位置和基本属性，真正实现控件数组功能的代码并不太多，也不复杂，而且十分的灵活；需要注意的是使用TList类对象组合中的各项控件之前，必须先将其强制转换为一个对象指针以指明其类型，才能对其属性进行修改/赋值操作。 本文程序在C＋＋ Builder 3.0/ PWin95，C＋＋ Builder 4.0/ PWin98下调试通过。