如何在Delphi 2010中使用RTTI设置任意类型的事件处理程序?

Chr*_*ler 2 delphi rtti delphi-2010

阅读帖子后如何通过新的RTTI设置事件处理程序?,我想知道是否有可能更动态地解决这个问题.例如,我想将任何组件的ALL事件处理程序设置为nil.

使用TValue.From <TNotifyEvent> (SomeMethod)不起作用有两个原因:1.类型未知(可能是TNotifyEvent,TMouseEvent等)2.我不能将'SomeMethod'设置为nil(无效转换)

在旧的RTTI风格中,我会做类似的事情:

var
  NilMethod: TMethod;
begin
[...]
NilMethod.Data := nil;
NilMethod.Code := nil;
SetMethodProp (AComponent,PropertyName,NilMethod);
Run Code Online (Sandbox Code Playgroud)

Mas*_*ler 9

以下代码应该工作:

procedure NilAllEventHandlers(myObject: TObject);
var
   context: TRttiContext;
   rType: TRttiType;
   field: TRttiField;
   value: TValue;
   nilMethod: TMethod;
begin
   nilMethod.Code := nil;
   nilMethod.Data := nil;

   context := TRttiContext.Create;
   rType := context.GetType(TButton);
   for field in rType.GetFields do
   begin
      if field.FieldType.TypeKind = tkMethod then
      begin
         TValue.Make(@nilMethod, field.FieldType.Handle, value);
         field.SetValue(myObject, value);
      end;
   end;
end;
Run Code Online (Sandbox Code Playgroud)

但它并不是因为当使用其.Code参数为nil的TMethod值时,TValue.TryCast中存在错误.我会把它报告给QC.希望它能在D2011或更新中得到修复.在此之前,尝试旧式.

编辑:报告为QC#81416.如果你想看到它固定,请投票.