能通过事件的名称动态调用此事件吗?(100)

  • 主题发起人 主题发起人 Lessy
  • 开始时间 开始时间
L

Lessy

Unregistered / Unconfirmed
GUEST, unregistred user!
如题例如我自定义了一个过程Procedure1,能不能通过字符'procedure1'查找此过程,并把此过程动态赋予Tcombobox的onchange事件中?
 
只要参数结构一样,你可以直接赋值给onchange事件
 
To andrew57:这个我也知道呀,我要的效果是提交一个字符串(此字符串为过程的名称)变量,来动态调用此过程
 
做不到。
 
进RTTI就可以
 
可以定义类,此方法定义成类方法,然后将此类方法定义成published.通过rtti就可以实现, 如果你还想通过字符串查询到类,那么你必须注册这个类.呵呵,对基本功是个考验delphi2010似乎直接通过反射就可以实现,不用那么啰嗦
 
To apiao and kkyy:能不能用代码举个例子呀?
 
按我的想法,Procedure1在写程序时就已经写好了,所以,Procedure1是已知的,而且还有Procedure2~ProcedureN。这样,可以定义一个数组,保存Procedure1~ProcedureN,之后用判断:if 条件1='procedure1' then Tcombobox.onchange=procedure1;if 条件1='procedure2' then Tcombobox.onchange=procedure2;……if 条件1='procedureN' then Tcombobox.onchange=procedureN;
 
听起来像反射。。。
 
反射太消耗资源和效能,并不推荐。这样你的系统只要你引用了一个命名空间中的类,那整个名字空间都会被映射进你的系统,尽管,你可能仅仅使用了那个类,但为了反射特性,整个名字空间中的类都会被打包进去,太聪明,也太不聪明了。
 
delphi2010能做到http://blog.csdn.net/wxieyang/archive/2009/09/30/4620919.aspx这个网址是一个通过字符串方式调用类中的方法的例子。你可以参考一下。其实,通过字符串方式得到了函数的RTTI信息,基本上就得到了这个函数的一切了,当然也包括函数的地址了,得到了函数地址,剩下的就是赋值就是了,把这个地址赋值个你的事件
 
学习了,谢谢
 
还是RTTI强大.
 
To dark_power:你是说RTTI耗资源而且速度慢吗?衣你看,怎样做才好呢?To zbdzjx:你的想法好像可以,我会试试,就是要事先定义好事件,如果事件太多就很烦谢谢大家给我的建议,RTTI我不懂,谁有好的教程发来看看?
 
专门写一个函数(NewProcedure),将字符串'procedure1'(或是其它字符串)传进去。在函数中,只要判断传来的字符串,在执行对应的函数就可以了。Tcombobox.onchange=NewProcedure('procedure1')
 
你知道对象的名字和类属,也知道他所拥有的方法,既然该知道得都知道了,又何必非要绕弯去使用反射?反射是动态语言的特性,因为动态语言是基于解释执行过程的,执行时动态加载支持库。对于C/C++、Delphi这类静态语言,过多使用反射是相对低效的做法,大多数情况下,指针是最好的解决办法。出于便捷和安全考虑,动态语言里是尽可能封装和隐藏指针的,Delphi为了方便和安全也封装和隐藏了很多指针,所以相对而言很多时候,你会觉得Delphi比C/C++方便得多,但同样这都是有代价的,所以如果你看看System单元你会发现,很多内置函数其实都是用汇编来实现的,这就是因为使用RTTI同时又为了保证执行效率的折中办法。对于你的问题,既然你知道自己声明了一个过程,那又何须用反射查询?通常你都可以使用Assigned()函数来验证指针或例程是否为nil来判断有效性。如果,对于你给Onchange赋值后,就Assigned(Tcombbox1.Onchange)。然后根据返回值做出相应判断。尽量少用。打个不怎么恰当的比喻,你给你的自行车安上发动机,好不好?好啊,多省力气啊!但是就都好么?这也不见得,首先,你自行车的维护更繁琐复杂了,万一在路上发动机坏了,就的拖着走或推着走,那10多公斤的动力系统就是累赘了;其次,你的自行车的可控性降低了,你用脚踏的时候,看到不好可以用脚辅助刹车,甚至可以脚踏一横,两脚一使劲,纵身跃出去,但是对抗时速30、40,一两个马力的马达你吃得消么?最后,你维护修理车子的成本肯定也提高了。
 
其实我上面说的很清楚了。用反射是其中的一个办法。但是就目前的delphi2007以下的rtti特性,也能完成要求。以下是例子type TtxgisS57FieldClass = class of TtxgisS57Field; TtxgisS57Field = class(TPersistent) Published function: GetValue: integer; end;implementation //查询对象名 var _S57FieldClass:TtxgisS57FieldClass; _S57Field:TtxgisS57Field; begin _S57FieldClass := TPersistent(GetClass('TtxgisS57Field ')); _S57Field := S57FieldClass.Create; //如何获取published下的方法名,我就不罗嗦了initialization RegisterClass(TtxgisS57Field );end.多说几句其实楼主就是想找个通用的方法。如果不是, if then就可以了:)
 
可以把过程或函数做成单独的dll或bpl,动态调用。
 

Similar threads

后退
顶部