onclick是TNotifyEvent类型;

type

  TNotifyEvent   =   procedure(Sender:   TObject)   of   object;

就是说他是一个过程,而且是有一个TObject的参数,并且包含在一个对象里~~

关于类的方法:   (不是类方法,这里指object   pascal中的静态方法,相当于C++的成员函数)

1:   带有隐含参数   self

2:   方法是方法,数据是数据。

3:Delphi的方法是一个结构

type

TMethod   =   record

  Code:   Pointer;     //方法的入口地址

  Data:   Pointer;     //类实例指针(Self参数)

end;

我们调用类的方法,其实分为2个部分,

1:调用方法的代码,通过类来获得方法入口地址。

2:访问对象的数据(也可能不访问),通过类的方法的那个隐含参数Self来访问。

我做了一个测试:

TMyObject   =   class

  private

    FName:   string;

  public

    procedure   ChangeName(AName:   string);

    procedure   ShowPrivate;

end;

procedure   TMyObject.ChangeName(AName:   string);

begin

  FName   :=   AName;   //修改私有变量

  ShowMessage('My   name   is   to   be   changed   to   '   +   AName);

end;

procedure   TMyObject.ShowPrivate;

begin

  ShowMessage('My   name   is   '   +   FName);

end;

procedure

TForm1.Button1Click(Sender:   TObject);

type

TCallFun   =   procedure(AName:   string)   of   object;

var

E:   TMyObject;

M:   TMethod;

begin

   E   :=   TMyObject.Create;

  M.Code   :=   @TMyObject.ChangeName;   //这里设置要访问的方法的入口地址

  M.Data   :=   @Pointer(E)^;       //设置Self参数,即类实例指针 @Pointer(E)^与Pointer(E)一样的         TCallFun(M)('Xbl');

  E.ShowPrivate;     //My   name   is   Xbl

  E.Free;

end;

  delphi里的普通函数指针pointer 为4个字节,但是对象的方法指针是8个字节,由对象指针self(4字节)和函数指针(4字节)组合而成. 将普通的函数指针变成对象的方法指针就不是难事了.

下面是简单的例子代码.

procedure  Button2Click(Sender: TObject);  //这里是一个普通的函数

implementation {$R *.DFM}

procedure  Button2Click(Sender: TObject);

begin

  ShowMessage('1');

end;

procedure TForm1.Button1Click(Sender: TObject);

var

  Method: TMethod;

begin

  Method.Code := @Button2Click;      //取得Button2Click函数指针

  Method.Data := nil;                               //也可以是self

  Button2.OnClick := TNotifyEvent(Method);

end;

How to execute a method (procedure/function) by name Category: Pascal Here's a simple trick to execute a Delphi object's method by name: ~~~~~~~~~~~~~~~~~~~~~~~~~

type

TForm1 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject) ;

procedure CallMeByName(Sender: TObject) ;

private

procedure ExecMethod(OnObject: TObject; MethodName: string) ;

end;

var

Form1: TForm1;

type

TExec = procedure of object;

procedure TForm1.ExecMethod(OnObject: TObject; MethodName: string) ;

var

Routine: TMethod;

Exec: TExec;

begin

Routine.Data := Pointer(OnObject) ;

Routine.Code := OnObject.MethodAddress(MethodName) ;

if NOT Assigned(Routine.Code) then Exit;

Exec := TExec(Routine) ;

Exec;

end;

procedure TForm1.CallMeByName(Sender: TObject) ;

begin

ShowMessage('Hello Delphi!') ;

end;

procedure TForm1.Button1Click(Sender: TObject) ;

begin

ExecMethod(Form1, 'CallMeByName') ;

end;

TMethod的更多相关文章

  1. TProcedure,TMethod,TNotifyEvent,TWndMethod的区别,并模拟点击按钮后发生的动作

    忽然发现TProcedure和TNotifEvent的区别还挺大的: procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage ...

  2. Delphi: TMethod转普通方法为对象方法

    回看旧时代码,以往清楚之记忆渐渐模糊,事隔多年,遗忘正在发生. TMethod方法,当初熟练再看已陌生,再做复习以作备忘. 简言之,它做为一相桥接,将普通事件或方法转换为类方法,其多用于事件动态设置中 ...

  3. Delphi调用爷爷类的方法(重新构造TMethod的data和code部分,其中Code指向祖父类的方法)

    Delphi通过inherited 可以调用父类的方法,但是没有提供直接调用父类的父类的方法(爷爷类),通过变通的方式实现如下: 假设父类是TFather,爷爷类TGrand,调用爷爷类的Write方 ...

  4. TMethod的学习与使用

    http://bbs.2ccc.com/topic.asp?topicid=496893

  5. TProfiler

    下载:访问 TProfiler 的 GitHub 主页,https://github.com/alibaba/TProfiler,点击 Clone or download 按钮的打开下载选项,点击该选 ...

  6. [.NET] CErrStack 方便地管理错误或异常

    Option Explicit On Option Strict On Imports System.Reflection Imports System.Diagnostics Public Stru ...

  7. 自己写一个java.lang.reflect.Proxy代理的实现

    前言 Java设计模式9:代理模式一文中,讲到了动态代理,动态代理里面用到了一个类就是java.lang.reflect.Proxy,这个类是根据代理内容为传入的接口生成代理用的.本文就自己写一个Pr ...

  8. 字符串驱动技术—— MethodAddress , MethodName , ObjectInvoke

    首先看一段Delphi帮助中的介绍(After Delphi 6 ): Returns the address of a published method. class function Method ...

  9. Delphi 中的 procedure of object

    转载:http://www.cnblogs.com/ywangzi/archive/2012/08/28/2659811.html 总结:TMyEvent = procedure of object; ...

随机推荐

  1. linux如何查看系统信息

    一:cpu [root@srv /]# more /proc/cpuinfo | grep "model name" model name    : Intel(R) Xeon(R ...

  2. crontab执行脚本中文乱码,手动执行没有问题

    crontab执行脚本中文乱码,手动执行没有问题 产生原因:       这是因为Unix/Linux下使用crontab时的运行环境已经不是用户环境了,因此原本用户下的一些环境变量的设置就失效了.例 ...

  3. re正则表达式16_managing complex regexes

    Managing Complex Regexes Regular expressions are fine if the text pattern you need to match is simpl ...

  4. python --- Python中的callable 函数

    python --- Python中的callable 函数 转自: http://archive.cnblogs.com/a/1798319/ Python中的callable 函数 callabl ...

  5. iOS注册,找回密码时用到的获取验证码

    #import "ViewController.h" #import "NSTimer+BlocksKit.h" @interface ViewControll ...

  6. php引用计数的基本知识

    每个php变量存在一个叫"zval"的变量容器中.一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信息.第一个是"is_ref",是个bool ...

  7. zencart分类页产品页去掉url中的id号

    最近公司新上的网站被seo指出要修改url,去掉url中产品id.由于我们用的是zencart框架,装了 Ultimate SEO URLs 插件,所以在网上应该有这方面的资料,本文主要参考资料: 原 ...

  8. Docker 修改默认存储位置

    首先使用 docker info 查看 docker 的基本信息 sudo docker info Containers: 0 Images: 5 Storage Driver: devicemapp ...

  9. webapi输入验证过滤器ValidationActionFilter

    public class validationActionFilter:ActionFilterAttribute { public override void OnActionExecuting(S ...

  10. DELL服务器引导光盘下载

    http://www.dell.com/support/home/cn/zh/cndhs1/Drivers/DriversDetails?driverId=68RWT&fileid=27311 ...