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. Redis+Spring缓存实例

    转自:小宝鸽 一.Redis了解 1.1.Redis介绍: redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).lis ...

  2. Java——文件选择框:JFileChooser

    import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import j ...

  3. Struts 中 ActionContext ctx.put()把数据放到ValueStack里之数据传输背后机制:ValueStack(值栈)

    1.     数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! ValueStack基础:OGNL要了解ValueStack,必须先理解OGNL ...

  4. 【转】常用的shell脚本

    from:http://blog.sina.com.cn/s/blog_4152a9f501013r6c.html 常用的shell脚本 (2012-10-10 22:09:07) 转载▼ 标签: 杂 ...

  5. CF461B Appleman and Tree (树DP)

    CF462D Codeforces Round #263 (Div. 2) D Codeforces Round #263 (Div. 1) B B. Appleman and Tree time l ...

  6. NetBeans使用习惯:升级与保存配置

    如何升级:点击 netbeans 的升级更新 ,即可升级版本:不推荐官网下载进行安装,否则会出现,以前的旧版本8.0的目录和8.0.1目录,虽然它会自动检测到以前版本的配置,提示导入... 如何备份: ...

  7. 【转载】VC维的来龙去脉

    本文转载自 火光摇曳 原文链接:VC维的来龙去脉 目录: 说说历史 Hoeffding不等式 Connection to Learning 学习可行的两个核心条件 Effective Number o ...

  8. [译]git push

    push就是把你本地仓储的commit传到远程仓储中去. 用法 git push <remote> <branch> push指定的分支到<remote>中去.   ...

  9. [译]Mongoose指南 - 中间件

    中间件是一些函数, 当document发生init, validate, save和remove方法的时候中间件发生. 中间件都是document级别的不是model级别的. 下面讲讲两种中间件pre ...

  10. LYDSY模拟赛day3 涂色游戏

    /* 非常好的题 */ #include <cstdio> #include <iostream> #include <cstdlib> #include < ...