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. Github for Windows使用介绍

    Git已经变得非常流行,连Codeplex现在也已经主推Git.Github上更是充斥着各种高质量的开源项目,比如ruby on rails,cocos2d等等.对于习惯Windows图形界面的程序员 ...

  2. url下载网页的三种方法

    # -*- coding: utf-8 -*- import cookielib import urllib2 url = "http://www.baidu.com" print ...

  3. JavaWeb学习笔记——JDOM

    JavaDOC的网址:http://www.jdom.org/docs/apidocs/index.html import java.io.FileOutputStream; import org.j ...

  4. Java数据库——使用元数据分析数据库

    在JDBC中提供了DatabaseMetaData和ResultSetMetaData接口来分析数据库的元数据. DatabaseMetaData 使用DatabaseMetaData取得数据库的元信 ...

  5. td:first-child 伪类 匹配第一个 匹配第一个 <td> 元素

    css代码: td:first-child{border-right: 1px solid #d9dbdd; } 备注:在下面的例子中,选择器匹配作为任何元素的第一个子元素的 p 元素: 链接:htt ...

  6. JSONModel 嵌套字典数组 JSONModel nest NSDictionary NSArray

    JSONModel 嵌套字典数组  JSONModel nest NSDictionary NSArray

  7. Xcode卡顿解决方案

    1.禁用indexing 在终端(terminal) 输入 defaults write com.apple.dt.XCode IDEIndexDisable 并重启Xcode. (不是大神勿用哈,附 ...

  8. createStatement()的用法

    createStatement()的用法 标签: 数据库concurrencyscrollsql 2012-02-24 19:58 2508人阅读 评论(0) 收藏 举报  分类: JavaEE服务器 ...

  9. yii2 widget示例

    <?php namespace app\components; use yii\base\Widget; use yii\helpers\Html; class RctReplyWidget e ...

  10. C# MVC EF中匿名类使用

    控制器中代码: var list = context.Says.Join( context.Users, a => a.UserId, b => b.Id, (a, b) => ne ...