BCB中对于多个组件的添加事件,有没有不用手动添加的方法,比如使用类似循环的方法

小乖乖_学技术 2012-09-02 08:44:11
比如我在工程中添加了100个EditBox组件,我想给每个EditBox组件添加OnChange事件,在OnChange事件改变EditBox组件的Text属性,比如:
void __fastcall TForm::Edit1Change(TObject *Sender)
{
String str=Edit1->Text;
if(str.Length()>30)
a->Text="";
}
我的问题有两个,第一是如何不用手动一一添加100个EditBox组件,而是使用一种快速的添加方法?
我尝试过全部选中这100个EditBox组件,如何在对象监视器中添加OnChange事件,但是没有添加100个OnChange事件,而是这些组件的事件都指向了第一个选择的组件的OnChange事件,这样只能改变Edit1->Text

第二是组件的名称是固定的,对100个组件进行操作,我的方法只能是使用100个组件的Name->属性等,请问有没有方法能简化程序书写
比如:
SetStructL(CheckBoxa1,CheckBoxb1,Editc1,Editd1);
SetStructL(CheckBoxa2,CheckBoxb2,Editc2,Editd2);
...
SetStructL(CheckBoxa100,CheckBoxb100,Editc100,Editd100);
有没有简化的程序书写方法
...全文
210 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
我不懂电脑 2012-09-06
  • 打赏
  • 举报
回复
第一是如何不用手动一一添加100个EditBox组件,而是使用一种快速的添加方法?
你可以用程序动态添加的 TEditBox *Editbox = new TEditBox(NULL);
其他问题参见楼上回答
  • 打赏
  • 举报
回复
9月4日:
对于帖子BCB中对于多个组件的添加事件,有没有不用手动添加的方法,比如使用类似循环的方法
我回复了三次,正经话回复不了,这里发个帖子供大家参考
先谢谢两位大侠ksrsoft和ccrun
我前天遇到该问题,我发到网上,昨天下班的时候我就想,是不是Edit1Change(TObject *Sender)中的参数可以处理一下,Sender中的参数应该是Edit1的对象指针,这样编写一个子函数就能处理,然后其它组件都可以使用Edit1Change处理函数,只不过对应的Sender是各自组件的对象指针,我回去尝试一下,可以实现,晚上睡觉前想起来看看问题的回复,有两位大侠帮忙,我学会了动态代码指定,和FindComponent函数
没有别的意思,只是把过程回忆一下,这里谢谢两位大侠了
为了后面的同胞遇到该问题,想了解详细的代码,我编了一个简单的程序,把代码公布一下:
新建工程,放两个Edit组件(对于第一个问题),放三个CheckBox组件(对于第二个问题),再放一个命令按钮:
头文件Text.h:
//---------------------------------------------------------------------------
#ifndef TestH
#define TestH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
TEdit *Edit2;
TCheckBox *CheckBox1;
TCheckBox *CheckBox2;
TCheckBox *CheckBox3;
TButton *Button1;
void __fastcall Edit1Change(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
private:
bool flag;
void __fastcall FuncChangeText(TObject * a); // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
源文件Text.cpp:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "Test.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
flag=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
//我原来的处理方法,必须使用组件名称,因为组件的名称不能写成通用形式,比如Editn,
//这样对应一个组件就得写出一个事件函数
// String str;
// str=Edit1->Text;
// if(str.Length()>10)
// Edit1->Text="";
//这是新的处理方法,可以让所有Edit组件的OnChange事件都指向Edit1OnChange事件Edit1Change
//在该事件中,可以直接使用组件的指针,这样就可以不使用组件的名称
FuncChangeText(Sender); //Sender是Edit1组件的指针
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FuncChangeText(TObject* a) //子函数
{
TEdit* str;
str=(TEdit*)a; //必须要添加强制类型转换,将TObject*转换成TEdit*,因为str
//是TEdit*类型的,所以要类型匹配
if(str->Text.Length()>10)
str->Text="";
//简化的写法
// if(((TEdit*)a)->Text.Length()>10) //必须要添加强制类型转换,将TObject*转换成//TEdit*,因为要类型匹配
// ((TEdit*)a)->Text="";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCheckBox* a;
if(flag==false)
{
for(int i=0;i<3;i++)
{
a=(TCheckBox*)FindComponent(String().sprintf(TEXT("CheckBox%d"), i+1));
// FindComponent(const AnsiString AName)函数的作用是标识一个指定的组件是否属于组件
//类型(比如判断组件AName 是否属于Edit组件类型),该函数返回组件(改组件的名称
//必须匹配字符串(AName参数))
a->Checked=true;
}
flag=true;
}
else
{
for(int i=0;i<3;i++)
{
a=(TCheckBox*)FindComponent(String().sprintf(TEXT("CheckBox%d"), i+1));
a->Checked=false;
}
flag=false;
}
}
//---------------------------------------------------------------------------
调试程序:
我在子函数中添加断点,我使用Watch窗口查看(str->Name)(表示当前是哪个Edit组件),我在Edit组件1中输入字符,(str->Name)的值是Edit1(说明Sender是Edit组件1的指针,Sender送到子函数的参数a,a又送给str),我又在Edit组件2中输入字符,(str->Name)的值是Edit2(说明Edit2的OnChange事件进入Edit1Change(Edit1的OnChange事件),同时Edit2把自身的指针送给Sender(Edit1Change的参数),Sender送到子函数的参数a,a又送给str,所以(str->Name)的值是Edit2)
如果有200个CheckBox组件(分成两列,一列是100个组件,横向的两个是一组),每组只能选择一个CheckBox组件,我有两个方法:
方法1:将CheckBox组件(第一列)按照顺序添加Hint属性值(组件1对应的CheckBox组件的Hint属性值是1,该列下面的组件的Hint属性值依次增加),我使用语句(int i=StrToInt(((TCheckBox*)Sender)->Hint);)得到当前OnClick事件对应的CheckBox组件的Hit值,这样就可以得到同组的CheckBox组件的对象指针,然后进行相应操作即可,这是针对CheckBox组件(第一列),CheckBox组件(第二列)的OnClick事件还得处理一下
方法2:就是在第一个CheckBox组件的OnClick事件中,对100组的CheckBox组件(每组两个),进行一组一组的判断,如果当前组的两个CheckBox组件都选择上了,那么就让这两个CheckBox组件都处于未选中状态,这种方法的优点是程序简洁,但是执行起来占用更多的内存(因为点击任意一个CheckBox组件,都会对这100组进行判断处理)
请问有没有更好的方法


  • 打赏
  • 举报
回复
对于帖子BCB中对于多个组件的添加事件,有没有不用手动添加的方法,比如使用类似循环的方法
我回复了三次,正经话回复不了,这里发个帖子供大家参考
先谢谢两位大侠ksrsoft和ccrun
我前天遇到该问题,我发到网上,昨天下班的时候我就想,是不是Edit1Change(TObject *Sender)中的参数可以处理一下,Sender中的参数应该是Edit1的对象指针,这样编写一个子函数就能处理,然后其它组件都可以使用Edit1Change处理函数,只不过对应的Sender是各自组件的对象指针,我回去尝试一下,可以实现,晚上睡觉前想起来看看问题的回复,有两位大侠帮忙,我学会了动态代码指定,和FindComponent函数
没有别的意思,只是把过程回忆一下,这里谢谢两位大侠了
为了后面的同胞遇到该问题,想了解详细的代码,我编了一个简单的程序,把代码公布一下:
新建工程,放两个Edit组件(对于第一个问题),放三个CheckBox组件(对于第二个问题),再放一个命令按钮:
头文件Text.h:
//---------------------------------------------------------------------------
#ifndef TestH
#define TestH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
TEdit *Edit2;
TCheckBox *CheckBox1;
TCheckBox *CheckBox2;
TCheckBox *CheckBox3;
TButton *Button1;
void __fastcall Edit1Change(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
private:
bool flag;
void __fastcall FuncChangeText(TObject * a); // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
源文件Text.cpp:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "Test.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
flag=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
//我原来的处理方法,必须使用组件名称,因为组件的名称不能写成通用形式,比如Editn,
//这样对应一个组件就得写出一个事件函数
// String str;
// str=Edit1->Text;
// if(str.Length()>10)
// Edit1->Text="";
//这是新的处理方法,可以让所有Edit组件的OnChange事件都指向Edit1OnChange事件Edit1Change
//在该事件中,可以直接使用组件的指针,这样就可以不使用组件的名称
FuncChangeText(Sender); //Sender是Edit1组件的指针
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FuncChangeText(TObject* a) //子函数
{
TEdit* str;
str=(TEdit*)a; //必须要添加强制类型转换,将TObject*转换成TEdit*,因为str
//是TEdit*类型的,所以要类型匹配
if(str->Text.Length()>10)
str->Text="";
//简化的写法
// if(((TEdit*)a)->Text.Length()>10) //必须要添加强制类型转换,将TObject*转换成//TEdit*,因为要类型匹配
// ((TEdit*)a)->Text="";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TCheckBox* a;
if(flag==false)
{
for(int i=0;i<3;i++)
{
a=(TCheckBox*)FindComponent(String().sprintf(TEXT("CheckBox%d"), i+1));
// FindComponent(const AnsiString AName)函数的作用是标识一个指定的组件是否属于组件
//类型(比如判断组件AName 是否属于Edit组件类型),该函数返回组件(改组件的名称
//必须匹配字符串(AName参数))
a->Checked=true;
}
flag=true;
}
else
{
for(int i=0;i<3;i++)
{
a=(TCheckBox*)FindComponent(String().sprintf(TEXT("CheckBox%d"), i+1));
a->Checked=false;
}
flag=false;
}
}
//---------------------------------------------------------------------------
调试程序:
我在子函数中添加断点,我使用Watch窗口查看(str->Name)(表示当前是哪个Edit组件),我在Edit组件1中输入字符,(str->Name)的值是Edit1(说明Sender是Edit组件1的指针,Sender送到子函数的参数a,a又送给str),我又在Edit组件2中输入字符,(str->Name)的值是Edit2(说明Edit2的OnChange事件进入Edit1Change(Edit1的OnChange事件),同时Edit2把自身的指针送给Sender(Edit1Change的参数),Sender送到子函数的参数a,a又送给str,所以(str->Name)的值是Edit2)
如果有200个CheckBox组件(分成两列,一列是100个组件,横向的两个是一组),每组只能选择一个CheckBox组件,我有两个方法:
方法1:将CheckBox组件(第一列)按照顺序添加Hint属性值(组件1对应的CheckBox组件的Hint属性值是1,该列下面的组件的Hint属性值依次增加),我使用语句(int i=StrToInt(((TCheckBox*)Sender)->Hint);)得到当前OnClick事件对应的CheckBox组件的Hit值,这样就可以得到同组的CheckBox组件的对象指针,然后进行相应操作即可,这是针对CheckBox组件(第一列),CheckBox组件(第二列)的OnClick事件还得处理一下
方法2:就是在第一个CheckBox组件的OnClick事件中,对100组的CheckBox组件(每组两个),进行一组一组的判断,如果当前组的两个CheckBox组件都选择上了,那么就让这两个CheckBox组件都处于未选中状态,这种方法的优点是程序简洁,但是执行起来占用更多的内存(因为点击任意一个CheckBox组件,都会对这100组进行判断处理)
请问有没有更好的方法


ccrun.com 2012-09-03
  • 打赏
  • 举报
回复
1。设计时给这100多个组件同时指定一个事件是可以的,但是必须得先有一个事件处理函数比如Edit1Change存在。然后选中多个Edit,在Event页面上点击OnChange事件的下拉框,选择Edit1Change就可以了。这是设计时指定。还可以运行时指定事件,因为你的组合命名是依次递加的规则,可以在一个循环中为多个组件指定事件处理函数,如:
TEdit *edt;
for (int i = 0; i < 4; i++)
{
edt = (TEdit *)FindComponent(String().sprintf(TEXT("Edit%d"), i + 1));
if (edt)
{
edt->OnChange = Edit1Change;
}
}


至于第二个问题,相信楼主看一下上面的代码,你自己就会写了。
  • 打赏
  • 举报
回复
我刚开始学习BCB,有不懂的还得多请教大侠们,哈
  • 打赏
  • 举报
回复
我刚开始学习BCB,有不懂的还得多请教大侠们,哈
  • 打赏
  • 举报
回复
恩,我明天编个程序实现一下,先谢谢,改天结贴给分
ccrun.com 2012-09-03
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
这个是昨晚写的代码,结果回复不来了,呵呵
[/Quote]

FindComponent的返回值尽量判断一下,因为有可能是NULL
缘中人 2012-09-03
  • 打赏
  • 举报
回复
这个是昨晚写的代码,结果回复不来了,呵呵

void __fastcall TForm1::FormCreate(TObject *Sender)
{
// this->Edit2->OnChange = this->Edit1Change;
// this->Edit3->OnChange = this->Edit1Change;
// this->FindComponent()
String s;
for( int i=2;i<100;i++)
{
s = "Edit"+String(i);
((TEdit*)this->FindComponent(s))->OnChange = this->Edit1Change;
}
}
缘中人 2012-09-02
  • 打赏
  • 举报
回复
至于其他99个控件用这个事件,
可以设计时多选控件,在onchange事件时选择指定到Edit1Change。
也可以动态用代码指定。

void __fastcall TForm1::FormCreate(TObject *Sender)
{
this->Edit2->OnChange = this->Edit1Change;
this->Edit3->OnChange = this->Edit1Change;
。。。
}
缘中人 2012-09-02
  • 打赏
  • 举报
回复
写一个公用事件,然后其他edit用这个可以了,主要是用Sender对象指针。

void __fastcall TForm1::Edit1Change(TObject *Sender)
{
((TEdit*) Sender)->Text = Now();
}
缘中人 2012-09-02
  • 打赏
  • 举报
回复
可以的

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧