【问题标题】:Howto set event handlers with arbitrary type with RTTI in Delphi 2010?如何在 Delphi 2010 中使用 RTTI 设置任意类型的事件处理程序?
【发布时间】:2010-01-22 08:45:29
【问题描述】:

看了How to set event handlers via new 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);

【问题讨论】:

  • 那么旧样式有什么问题?还是不行吗?
  • 旧样式没有任何问题。我只是想使用相同的样式将处理程序设置为 nil 以及更改它。如果我想更改旧样式,则需要发布方法代码。使用新样式它也可以是公共的或私有的,在这种情况下我更喜欢它。那么我真的必须混合两种解决方案吗?

标签: delphi delphi-2010 rtti


【解决方案1】:

以下代码应该可以工作:

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;

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    相关资源
    最近更新 更多