2

阅读文章后如何通过新的 RTTI 设置事件处理程序?,我想知道是否可以更动态地解决这个问题。例如,我想将任何组件的所有事件处理程序设置为零。

使用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);
4

1 回答 1

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;

但这不是因为 TValue.TryCast 在使用 .Code 参数为nil的 TMethod 值时存在错误。我会报告给 QC。希望它会在 D2011 或更新中得到修复。在那之前,尝试旧风格。

编辑:报告为QC# 81416。如果您想修复它,请投票。

于 2010-01-22T12:55:10.663 回答