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

发布于 2024-08-18 18:06:24 字数 533 浏览 5 评论 0原文

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

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

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

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

after reading the post How to set event handlers via new RTTI?, I wonder if it is possible to solve this more dynamically. For example I want to set ALL event handlers of any component to nil.

Using TValue.From <TNotifyEvent> (SomeMethod) does not work for two reasons:
1. The type is unknown (could be TNotifyEvent, TMouseEvent etc.)
2. I cannot set 'SomeMethod' to nil (invalid cast)

In old RTTI style I would do something like:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绻影浮沉 2024-08-25 18:06:24

以下代码应该可以工作:

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。如果您想修复它,请投票。

The following code ought to work:

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;

But it doesn't because there's a bug in TValue.TryCast when working with a TMethod value whose .Code parameter is nil. I'll report it to QC. Hopefully it'll get fixed in D2011 or an update. Until then, try the old style.

EDIT: Reported as QC# 81416. Vote it up if you want to see it fixed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文