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 相关快捷键

    linux 相关快捷键 http://linux.chinaunix.net/begin/2004-10-05/34.shtml#_Toc41417098 1.使用虚拟控制台登录后按“Alt+F2”键 ...

  2. Java数据结构的特点

  3. JSP 原理

    参考文献:http://www.cnblogs.com/xdp-gacl/p/3764991.html 一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都 ...

  4. 和安全有关的那些事(非对称加密、数字摘要、数字签名、数字证书、SSL、HTTPS及其他)

    转自http://blog.csdn.net/bluishglc/article/details/7585965 对于一般的开发人员来说,很少需要对安全领域内的基础技术进行深入的研究,但是鉴于日常系统 ...

  5. Euclidean Space

    http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm

  6. ecshop 如果缩略图为空,使用默认图片

    引用:$row['goods_img'] = get_image_path($row['goods_id'], $row['goods_img']); lib_common.php /** * 重新获 ...

  7. The method below converts an array of objects to a DataTable object in C#.

    http://www.c-sharpcorner.com/blogs/dynamic-objects-conveting-into-data-table-in-c-sharp1 public stat ...

  8. 3步完成chrome切换搜索引擎

    1.打开chrome://settings/,找到搜索 2.点击“管理搜索引擎”,出现弹窗. 增加搜索引擎,三个文本框分别输入:名称.快捷键.地址 3.在新的选项卡中,输入快捷键(如:github), ...

  9. android自定义控件(2)-拖拽实现开关切换

    在这里,我们的主要工作就是在原有代码的基础上,增加一个重写的onTouchEvent方法,刚添加上来的时候是这个样子的: @Override public boolean onTouchEvent(M ...

  10. c#之Redis队列在邮件提醒中的应用

    场景 有这样一个场景,一个邮件提醒的windows服务,获取所有开启邮件提醒的用户,循环获取这些用户的邮件,发送一条服务号消息.但问题来了,用户比较少的情况下,轮询一遍时间还能忍受,如果用户多了,那用 ...