当开发类似解释程序或实现可视化操作功能等一类的应用程序时,都需要动态地创建控件(对象),而且还要为这些控件添加适当的事件处理程序,下面将介绍在C++Builder中如何实现基本的实现框架。
动态创建控件的一般过程:
TButton *btn = new TButton(this);
btn->Caption = "Button1";
btn->Parent = this;
btn->Show();
下面结合一个动态生成菜单的例子来实践如何动态创建控件并处理添加事件处理。
先编写一个函数用向一个已存在的菜单对象中插入菜单项:
void __fastcall TForm1::AddContextMenuItem(TPopupMenu *pMenu,
AnsiString caption, unsigned int tag, TNotifyEvent notifyEvent)
参数:
pMenu: 已存在的TPopupMenu对象指针
caption: 菜单项的标题
tag: 菜单项的tag值,用于标识不同的TMenuItem对象
notifyEvent: 该菜单项的事件处理函数
函数实现:
TMenuItem *mnuItem = new TMenuItem(pMenu); // Create new item |
然后编写调用AddContextMenuItem(...)的函数CreateContextMenu(),定义如下:
void __fastcall TForm1::CreateContextMenu(void) |
FContextMenu是TForm1的成员变量,UpdateContextMenuItem()是用于在FContextMenu的Popup事件中更新菜单项。
MenuItemClick与NullNotifyEvent都是TForm1中成员函数,是动态创建的控件的事件处理函数,格式为:
void __fastcall TForm1::MenuItemClick(TObject *Sender)
void __fastcall TForm1::NullNotifyEvent(TObject *Sender)
---------------------------------------------------------------------------------------------
代码如下:
.h文件中:
class TMyThread : public TThread
{
public:
__fastcall TMyThread(void);
private:
void __fastcall Execute();
};
.cpp文件中:
__fastcall TMyThread::TMyThread(void): TThread(true)
{
FreeOnTerminate=true;
Resume();
}
void __fastcall TMyThread::Execute()
{
Form1->createview();
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TMyThread *mythread = new TMyThread;
}
void __fastcall TForm1::createview() //createview()是我自己定义的函数
{
//动态生成LISTVIEW列表
TListView *tempview = new TListView(Form1);
tempview->Visible = true;
tempview->Parent = Form1;
}
就是以上代码运行后出现2个问题:
第一:点击Button按钮时没有创建listview控件
第二:关闭应用程序时出现以下错误提示:
应用程序发生异常 未知的软件异常(0x0eedfade),位置为0x77e8bc3f。
1:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TMyThread *mythread = new TMyThread();
mythread->Execute;
}
2:估计是内存未释放!!
TO:caizhen2000_82(猛将兄!!!)
你的方法不行呀,mythread->Execute;根本没有这个方法。
估计是内存未释放?可以说的具体一点吗?
希望大家给出可行的解决方案,在线等!
Form1->createview(); Form1??
你要把ListView 放在那里?
放在form1上呀
__fastcall TMyThread::TMyThread(void): TThread(true)
{
TListView *ListView1 = new TListView(Form1);
ListView1->Parent= Form1
FreeOnTerminate=true;
Resume();
}
放在构造函数中。
TO: chpst(斗转星移)
非常感谢你的帮助,2个问题全部解决,不过又出现了新的问题!
动态生成的listview如何在createview()函数中调用呀
---------------------------------------------------------------------------------------------
TButton *a;
a = new TButton(this);
a->Parent = Form1;
a->Top = 10;
a->Left = 10;
a->Width = 30;
a->Height = 10;
a->Caption = "haha";
如果要放到Panel上,指定的Parent指到Panel上就可以了Top
动态名字的话我个人比较喜欢用控件数组
比如
TButton *button[10];
创建的方法一样的
button[0] = new TButton(this);
你可以定义个全局变量num,代替方括号里面变量的位置Top
TButton * TempButton = new TButton(this);
TempButton->Parent = Form1;
TempButton->Top = 00;
TempButton->Left = 00;
... Width = 00;
... Height = 00;
... Caption = 00;
TempButton->Show();
Top
动态创建的控件数组是不用名字的,如果要在Panel上创建,只要把该控件的Parent属性设置为Panel就可以了Top
//..........
buttone1->Update();Top
TButton *a;
string=buttonname="button"+i;//I定义成全局的变量。
a = new TButton(this);
a->Parent = Panel;
a->Top = 10;
a->Left = 10;
a->Width = 30;
a->Height = 10;
a->Name= buttonname;
注,不知道这样指名子行不行。如果系统不让的话没办法了Top
别忘了下边I+1
------------------------------------------------------------------------------------
在有些情况由于特殊的需求,需要开发自己的VCL组件以满足需求。对于初学者来说有些问题是需要强调一下的。
第一:就是文件及类的命名问题
菜单操作过程:“Component->New Component...”,在“New Component”对话框的“Unit file name”栏中输入你的类名,如你的类名为“TMyClass”,则这里只要填写“MyClass”,注意这里没有加“T”。确认后会打开该文件。
完成对源文件的编辑并保存后,就要向IDE环境中 安装该组件,操作如下:“Component->Install Component...”,选择“Into new package”页,在“Unit file name”中输入要安装的组件源文件路径及文件名,“Package file name”中输入你要生成的新包文件路径及文件名,注意你里的包名应该为类的名字,如“TMyClass.bpk”,这样就会生成.bpk包文件与包源文 件“TMyClass.cpp”,如果把包名写MyClass.bpk,则你的组件的源文件就会被覆盖掉,当然你可以选择存入在不同的路径下,但这样就会 不容易管理和容易产生混淆。
第二:如何给新的组件自定义图标
一般情况下是需要为自己编写的组件选择一个合适的图标,以更形象地表达该组件的功能,这个图标是在设计阶段在RAD环境中的组件栏中显示,一般大小为24x24。
首先,打开C++Builder 自带的Image Editor,选择“File->New...->Component Resource File(.dcr)”,然后选择“Resource->Bitmap”,输入尺寸和颜色数据,确认后就创建了一个位图让你编辑,默认的资源名为“Bitmap1”,应该将这个名字更改,以和你的.bpl文件名一致,如你的组件的.bpl为“TMyComponent.bpl”,则它的名字应为“TMYCOMPONENT”,并且合部大写。双击该结点就可开始编辑你的图标,当然也可以使用PhotoShop之类的软件做好后直接使用“粘贴”命令粘贴,注意最多支持256色。
当图标绘画完成后就可以存盘,这时必须注意其命名的问题,该文件名必须与你的组件类名一致,如你的组件类名为“MyComponent”,则文件名应为“MYCOMPONENT.dcr”,并且全部大写。再次安装你的组件后就可以使用你自定义的图标了。