Delphi中匿名方法动态绑定事件
应恢弘之约,写了一个对其发布的匿名函数动态绑定到事件的封装,代码如下:
TAnonEvent=class
public
class function Wrap<T1,T2>(OnEvent:T1):T2;
end;
{ TAnonEvent }
class function TAnonEvent.Wrap<T1,T2>(OnEvent: T1):T2;
var
Addr:Pointer;
AMethod:PMethod;
begin
Addr:=PPointer(@OnEvent)^;
AMethod:=@Result;
AMethod.Code:=PPointer(IntPtr(PPointer(Addr)^)+SizeOf(Pointer)*3)^;//QueryInterface/AddRef/Release/Invoke
AMethod.Data:=Pointer(Addr);
end;
type
TNotifyEventA=reference to procedure(ASender:TObject);
procedure TForm3.Button1Click(Sender: TObject);
begin
Button2.OnClick:=TAnonEvent.Wrap<TNotifyEventA,TNotifyEvent>(procedure (sender: tObject)
begin
Button2.Caption:=DateTimeToStr(Now);
ShowMessage('OK');
end);
Button2.OnClick(Sender);
end;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
type
TAnonEvent=class
public
class function Wrap<T1,T2>(OnEvent:T1):T2;
end;
{ TAnonEvent }
class function TAnonEvent.Wrap<T1,T2>(OnEvent: T1):T2;
var
Addr:Pointer;
AMethod:PMethod;
begin
Addr:=PPointer(@OnEvent)^;
AMethod:=@Result;
AMethod.Code:=PPointer(IntPtr(PPointer(Addr)^)+SizeOf(Pointer)*3)^;//QueryInterface/AddRef/Release/Invoke
AMethod.Data:=Pointer(Addr);
end;
type
TNotifyEventA=reference to procedure(ASender:TObject);
procedure TForm3.Button1Click(Sender: TObject);
begin
Button2.OnClick:=TAnonEvent.Wrap<TNotifyEventA,TNotifyEvent>(procedure (sender: tObject)
begin
Button2.Caption:=DateTimeToStr(Now);
ShowMessage('OK');
end);
Button2.OnClick(Sender);
end;
|
【注意】
由于匿名函数中,我将TMethod.Data指向了匿名函数对应的接口对象,所以在匿名函数中,不要使用Self来代表当前对象。如果非要使用的话,那么自己修改下Wrap的代码,将AMethod.Data:=Pointer(Addr)改为指向当前函数所隶属对象的Self即可。
Delphi中匿名方法动态绑定事件的更多相关文章
- delphi中locate方法
TDataSet控件以及它的继承控件,例如TSimpleDataSet/TClientDataSet等都可以使用Locate方法在结果数据集中查寻数据.程序首先必须使用SQL命令从后端数据库中取得数据 ...
- JQ中的方法、事件及动画
css( ) 除了可以为元素添加样式外,还可用来查询元素,某样式值alert($('.cls1').css('width')); //100px(返回带单位的值)注意:原生CSS样式中有-的去掉并且将 ...
- C++Builder XE7 中“匿名”方法实现
class TMyProc : public TCppInterfacedObject<TThreadProcedure> { private: String p1; String p2; ...
- delphi 常用属性+方法+事件+代码+函数
内容居中(属性) alignment->tacenter mome控件 禁用最大化(属性) 窗体-> BorderIcons属性-> biMaximize-> False 让鼠 ...
- 在Delphi中使用C++对象(两种方法,但都要改造C++提供的DLL)
Delphi是市场上最好的RAD工具,但是现在C++占据着主导地位,有时针对一个问题很难找到Delphi或Pascal的解决方案.可是却可能找到了一个相关的C++类.本文描述几种在Delphi代码中使 ...
- Lambda表达式与匿名方法
在C#2中,由于有了方法组,匿名方法,类型的协变和抗变,使得运用delegate变得很容易,在注册事件时代码变得简单易读,但是在C# 2中,代码仍然有点臃肿,大块的匿名方法会降低代码的可读性,一般我们 ...
- 在Delphi中使用C++对象(转)
源:http://blog.csdn.net/henreash/article/details/7352335 Delphi是市场上最好的RAD工具,但是现在C++占据着主导地位,有时针对一个问题很难 ...
- 委托学习笔记后续:泛型委托及委托中所涉及到匿名方法、Lambda表达式
引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到和委托相关的匿名方法.Lambda表达式及泛型委托记录 ...
- C#基础精华07(委托事件,委托的使用,匿名方法)
1.委托概述 委托是一种数据类型,像类一样(可以声明委托类型变量).方法参数可以是int.string.类类型 void M1(int n){ } √ void M2(string s){ } √ ...
随机推荐
- 骑芯供应链(W 笔试)
单选题 1.调用本身构造方法 答案:this(X) 2.若y=3,a=2,b=4,运行y+=a++/--b,求y的值 答案: 3.不能控制servlet生命周期的方法是? 选项:init().serv ...
- class 写在 import的位置 类的名字第一个字母大写 后面没括号 ES6
class 写在 import的位置 类的名字第一个字母大写 后面没括号 class ObTableDataClass {}或者 const ObTableDataClass = class { in ...
- Qt中常用的类
QApplication 应用程序类 管理图形用户界面应用程序的控制流和主要设置 QLabel 标签类 提供 ...
- 纯html+css中实现静态选座位效果技巧(input+label使用小技巧)
很多时候,我们想通过html+css的方式实现排列在后方的代码在选中状态下,能控制排列在前的代码的样式.那么要怎么实现呢?在这里我就要用1个小技巧来完成. 众所周知的,我们css中的选择器通常只能向下 ...
- POJ - 3126 - Prime Path(BFS)
Prime Path POJ - 3126 题意: 给出两个四位素数 a , b.然后从a开始,每次可以改变四位中的一位数字,变成 c,c 可以接着变,直到变成b为止.要求 c 必须是素数.求变换次数 ...
- 查看mysql二进制日志报错问题
在排查网站被黑时想通过Mysql二进制日志找出修改字段时间,但是使用mysqlbinlog报错: [root@zfszsw1 bin]# ./mysqlbinlog /opt/mysql-bin.00 ...
- 如何用 CSS 创作一个立体滑动 toggle 交互控件
效果预览 在线演示 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/zjoOgX 可交互视频教程 此视 ...
- python基础知识12-异常
几个命令: sudo apt install tree tree 当前目录以树形结构展示出来. tree a 查看a内的所有目录.也可以跟绝对路径. a = input('请输入您的密码') 将用户输 ...
- luogu2770 航空路线问题
前置技能:HDU3376 Matrix Again 所以看到这个题,我们也会想着用最大费用最大流解决,因为从起点飞到终点再飞回来,就等于从起点飞两次到终点且这两次飞行除了起点终点之外没有访问超过一次的 ...
- jquery怎么获得ul中li的个数