TMethod
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; ...
随机推荐
- ci重定向
ci重定向 对于/index.php/abc这种url,Apache和lighttpd会按"index.php?abc"来解释,而nginx会认为是请求名字是"index ...
- Centos: 修改 yum安装的mysql路径
1.使用命令service mysqld stop 停止mysql查看mysql数据库的默认路径:/var/lib/mysql使用cp -afir /var/lib/mysql/* /usr/l ...
- java实现Haffman编码
1.先创建一个树节点类(泛型类),为了方便使用集合的排序方法,泛型类要实现泛型接口Comparable,代码如下 package com.hjp.huffman; /** * Created by J ...
- cmake 静态调用 c++ dll 的类的一个例子(Clion IDE)[更新1:增加1.模版的应用,2.ma 的算法]
CMakeLists.txt project(aaa) add_library(aaa SHARED aaa.cpp) add_executable(bbb bbb.cpp) target_link_ ...
- VIM辅导:视频教程,文档资料,经典插件
VIM辅导:25个vim视频' 教程 '资源 转自: http://blog.jobbole.com/10250/ 编注:@程序员的那些事 12月14日在新浪微博发起的<你最常用哪些文本编辑 ...
- MAC 系统下使用 Sublime Text 2 直接编译运行 java 代码
本文参考了网上很多文章,就不一一列出了. sublime的版本是 sublime test 2 jdk版本 jdk1.7 1. mac下貌似直接就可以运行javac 和 java命令的,如果不能直接运 ...
- jar war
区别:Jar.war.EAR.在文件结构上,三者并没有什么不同,它们都采用zip或jar档案文件压缩格式.但是它们的使用目的有所区别: Jar文件(扩展名为. Jar,JavaApplication ...
- Ajax load html page
jQuery ajax - load() 方法 jQuery Ajax 参考手册 实例 使用 AJAX 请求来改变 div 元素的文本: $("button").click(fun ...
- Orchard源码分析(4.4):Orchard.Caching.CacheModule类
概述 CacheModule也是一个Autofac模块. 一.CacheModule类 CacheModule将DefaultCacheManager注册为ICacheManager: ...
- inet_ntoa、 inet_aton、inet_addr
inet_addr() 简述:将一个点间隔地址转换成一个in_addr. #include <winsock.h> unsigned long PASCAL FAR inet_addr ...