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的更多相关文章
-
TProcedure,TMethod,TNotifyEvent,TWndMethod的区别,并模拟点击按钮后发生的动作
忽然发现TProcedure和TNotifEvent的区别还挺大的: procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage ...
-
Delphi: TMethod转普通方法为对象方法
回看旧时代码,以往清楚之记忆渐渐模糊,事隔多年,遗忘正在发生. TMethod方法,当初熟练再看已陌生,再做复习以作备忘. 简言之,它做为一相桥接,将普通事件或方法转换为类方法,其多用于事件动态设置中 ...
-
Delphi调用爷爷类的方法(重新构造TMethod的data和code部分,其中Code指向祖父类的方法)
Delphi通过inherited 可以调用父类的方法,但是没有提供直接调用父类的父类的方法(爷爷类),通过变通的方式实现如下: 假设父类是TFather,爷爷类TGrand,调用爷爷类的Write方 ...
-
TMethod的学习与使用
http://bbs.2ccc.com/topic.asp?topicid=496893
-
TProfiler
下载:访问 TProfiler 的 GitHub 主页,https://github.com/alibaba/TProfiler,点击 Clone or download 按钮的打开下载选项,点击该选 ...
-
[.NET] CErrStack 方便地管理错误或异常
Option Explicit On Option Strict On Imports System.Reflection Imports System.Diagnostics Public Stru ...
-
自己写一个java.lang.reflect.Proxy代理的实现
前言 Java设计模式9:代理模式一文中,讲到了动态代理,动态代理里面用到了一个类就是java.lang.reflect.Proxy,这个类是根据代理内容为传入的接口生成代理用的.本文就自己写一个Pr ...
-
字符串驱动技术—— MethodAddress , MethodName , ObjectInvoke
首先看一段Delphi帮助中的介绍(After Delphi 6 ): Returns the address of a published method. class function Method ...
-
Delphi 中的 procedure of object
转载:http://www.cnblogs.com/ywangzi/archive/2012/08/28/2659811.html 总结:TMyEvent = procedure of object; ...
随机推荐
-
MAC下 mysql不能插入中文和中文乱码的问题总结
MAC下 mysql不能插入中文和中文乱码的问题总结 前言 本文中所提到的问题解决方案,都是基于mac环境下的,但其他环境,比如windows应该也适用. 问题描述 本文解决下边两个问题: 往mysq ...
-
DotNet项目中的一些常用验证操作
在项目中需要对用户输入的信息,以及一些方法生成的结果进行验证,一般在项目中较多的采用js插件或js来进行有关信息的校验,但是从项目安全性的角度进行考虑,可对系统进行js注入. 如果在后台对用户输入的信 ...
-
MSP430FR5739串口程序
今天急着用这个片子的串口,匆忙中调试串口也话费了一段时间,在网上下了一个程序,忽然就把所有问题搞清楚了,只是中断就看着头文件中寄存器写的,虽然通讯正常,不过不确定有没有写错.代码如下: #includ ...
-
css3动画3
1.transition过渡动画 2.@keyframes关键帧动画,配合transform.animation使用
-
Windows下PHP版本选取
1. 下载地址 http://windows.php.net/download/ 2. PHP大版本 PHP4:由于太古老.对OO支持不力已基本被淘汰. PHP5:分为三个分支——PHP5.2之前的版 ...
-
WebActivatorEx 注入时的使用
WebActivator类库提供了3种功能,允许分别在Application_Start初始化之前,之后以及ShutDown的时候,分别执行指定的代码,并且允许多次指定.示例如下: [assembly ...
-
vim下编写html的超级利器emmet
GitHub:里面有详细的文档说明 https://github.com/mattn/emmet-vim 下载地址: http://www.vim.org/scripts/script.php?scr ...
-
经验分享:如何用grep对PHP进行代码审计
这是一个常见的误解- 企业需要购买复杂和昂贵的软件来发现应用程序中安全漏洞:而这些专门的软件应用程序,无论是黑盒或白盒,开源或商业,都能很快的发现安全漏洞. 事实是:所有这些专业的漏洞扫描工具都有其特 ...
-
SDN期末
一.项目描述 负载均衡程序 二.小组分工 组名:我们真的很弱 组员:李佳铭.吴森杰.张岚鑫.薛宇涛.杨凌澜 三.代码演示及过程描述 四.课程总结
-
ASP.NET Core 中 HttpContext 详解与使用 | Microsoft.AspNetCore.Http 详解
笔者没有学 ASP.NET,直接学 ASP.NET Core ,学完 ASP.NET Core MVC 基础后,开始学习 ASP.NET Core 的运行原理.发现应用程序有一个非常主要的 “传导体” ...