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. yum提示another app is currently holding the yum lock;waiting for it to exit

    Another app 解决方法:rm -rf /var/run/yum.pid 来强行解除锁定,然后你的yum就可以运行了

  2. js随机从数组中取出几个元素

    JS如何从一个数组中随机取出一个元素或者几个元素. 假如数组为 var items = ['1','2','4','5','6','7','8','9','10']; 1.从数组items中随机取出一 ...

  3. VC----文件图标和窗口图标及在任务栏显示的图标

    WNDCLASSEX wndcls; wndcls.cbSize=sizeof(wndcls); wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hb ...

  4. jquery实现图片预加载

    使用jquery实现图片预加载提高页面加载速度和用户体,本就为大家详细分析jquery图片预加载的实现原理. 什么时候使用图片预加载? 如果页面使用了很多不是最初加载便可见的图片,有必要进行预加载: ...

  5. 个人js

    1.网页右侧地图浮动楼层,超过100px就显示 $(window).scroll(function(){ ){ //距顶部多少像素时,出现返回顶部按钮 $("#floor").fa ...

  6. LeetCode —— Merge k Sorted Lists

    /* ** 算法的思路: ** 1.将k个链表的首元素进行建堆 ** 2.从堆中取出最小的元素,放到链表中 ** 3.如果取出元素的有后续的元素,则放入堆中,若没有则转步骤2,直到堆为空 */ #in ...

  7. php字符串常用算法--字符串加密解密

    /** * 加密.解密字符串 * * @global string $db_hash * @global array $pwServer * @param $string 待处理字符串 * @para ...

  8. JSP的原理

    一.什么是JSP JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大特点在于,写JSP就行html, ...

  9. 关于hibernate纯sql查询返回结果集的问题(hbm.xml中不写多表关联)

    相信用过hibernate的兄弟们都会因为多表复杂查询后,为返回的结果如何组装到一个VO中而烦恼不已.我也不停的为此而烦恼,但是在看了hibernate的transform后,感觉这个方法还挺管用的. ...

  10. Java通过JNI调用C

    Java调用C有多种方式,本文介绍笔者最近的学习过程,避免今后再犯类似的错误. 首先,Java肯定是调用C的动态链接库,即通过编译器编译后的dll/so文件. 下面介绍gcc编译dll的方法. 一般情 ...