Delphi XE的RTTI增强,动态Hook某些内部事件
Delphi2010之后的RTTI做了很大休整,现在用起来很爽了哦。甚至可以获取某些类的内部私有单元,然后为其赋值!讲这个RTTI增强的,可以参考网上的多个博客内容,我列举一下:
我这里的主要目的是挂钩某些内部私有事件,然后增加上一些自己的处理过程,这里我以TMenuItem的私有内部事件FOnChange作为例程。 这个私有事件在菜单内部绑定,我们平常状态下,在外部无法更改!但是XE之后这个问题不在存在,使用它的全新RTTI,可以很容易的获得一个类对象的基本 上所有的类的字段以及方法和属性等。
- begin
- rttiContext := TRttiContext.Create;
- rtype := rttiContext.GetType(TMenuItem);
- rField := rType.GetField('FOnChange');
- if rField <> nil then
- begin
- V := rField.GetValue(MainMenu1.Items);
- OldMenuItemChangeCode := TValueData(V).FAsMethod.Code;
- OldSelfData := TValuedata(V).FAsMethod.Data;
- TValueData(V).FAsMethod.Code := @TForm1.MenuItemChange;//菜单项目变化
- TValueData(V).FAsMethod.Data := self;
- rField.SetValue(self.MainMenu1.Items,v);
- end;
上面的代码就设置了MainMenu的items的私有事件变量FOnChange的新指向地址为本窗体的实现代码 了,OldMenuItemChangeCode,OldSelfData是保存私有事件的原有方法指针和传递的Self指针对象。用来在我们替换后的对 象中进行调用,不然原过程就不会被调用了。然后我们再来看看,新的FonChange的实现过程
- procedure TForm1.MenuItemChange(Sender: TObject; Source: TMenuItem;
- Rebuild: Boolean);
- var
- m: procedure(selfData: TObject;Sender: TObject; Source: TMenuItem;
- Rebuild: Boolean);
- begin
- if Assigned(OldMenuItemChangeCode) then
- begin
- m := OldMenuItemChangeCode;
- m(OldSelfData,Sender,Source,Rebuild);
- end;
- ShowMessage('菜单修改事件挂钩');
- end;
这个代码中最主要的就是如何来调用原来的FOnChange的执行过程了,熟悉Delphi的人应该都知道了Delphi的对象过程中可以使用Self表 示当前对象,而这个对象在对象过程中的传递是通过EAX传递的,而此时我们的新过程不是在MainMenu.Items的对象内部调用执行的,所以,我们 需要显示的传递SelfData作为源对象中的Self对象指针,所以我申明了一个指针过程如下:
m: procedure(selfData: TObject;Sender: TObject; Source: TMenuItem;
Rebuild: Boolean);
对于本申明过程,如果不是很明白的,请到CnPack的论坛上找本人对该类信息的详细分析过程 。
至此这个,挂钩内部的FonChange过程,就完成了,完整代码
http://blog.csdn.net/suiyunonghen/article/details/6116791
Delphi XE的RTTI增强,动态Hook某些内部事件的更多相关文章
- Delphi里的RTTI与反射(举例换掉FOnChange)
Delphi2010之后的RTTI做了很大休整,现在用起来很爽了哦.甚至可以获取某些类的内部私有单元,然后为其赋值!讲这个RTTI增强的,可以参考网上的多个博客内容,我列举一下:Delphi2010R ...
- Delphi下的RTTI函数大全
http://ljz9425.blog.163.com/blog/static/369148572008111635253858/ Delphi下的RTTI(下) 2008-12-16 15:52:5 ...
- delphi 2010与delphi XE破解版的冲突
在系统中同时安装了Dephi 2010LITE版与Delphi XE lite后,总是会有一个有问题 是因为两者都是读取C:\ProgramData\Embarcadero目录下的license文件, ...
- [转载]: delphi中XLSReadWrite控件的使用(2)---delphi XE下安装
一.下载 官方下载网址: http://www.axolot.com/components/download.htm 从这里可以下载到从Delphi5到DelphiXE全部支持的版本. 二.软件安装 ...
- delphi XE Berlin ReadProcessMemory WriteProcessMemory
delphi XE,Berlin [dcc32 Error] Unit9.pas(93): E2033 Types of actual and formal var parameters must ...
- FastReport for delphi xe 安装步骤
FastReport for delphi xe 安装步骤 1.先关闭DELPHI:2.下载后解压到一个目录,比如:D:FR:3.打开D:FR,运行recompile.exe ->点击" ...
- Delphi XE的firemonkey获取当前文件所在路径的方法
Delphi XE的firemonkey获取当前文件所在路径的方法 在之前,我们知道有三种方法: ExtractFilePath(ParamStr(0)) ExtractFilePath(Applic ...
- Delphi xe 下快捷使用 FastMM 的内存泄露检测功能
Delphi xe 集成了FastMM,调试程序是的时候可以方便地检查内存泄露了. 使用方法:在project中,添加一行: ReportMemoryLeaksOnShutdown := Debug ...
- Delphi XE中使用dbExpress连接MySQL数据库疑难问题解决(对三层的例子配置有帮助)
Delphi IDE中包含一个Data Explorer的组件,如下图所示: 该组件基于dbExpress(包含TSQLConnection.TSQLDataSet.TSQLQuery.TSQLSto ...
随机推荐
- js-计算器
<div class="main"><h1>HTML5-计算器</h1> <input id="num1& ...
- <转>eclipse如何修改dynamic web module version .
--------------------------------------------------------------------------------------------- 原 ...
- CSS层
在使用元素定位时,从可视角度讲,不可避免地会发生两个元素试图同时出现于同一位置的情况.显示其中一个就会覆盖另外一个. 如果将网页的二维空间延伸到三维空间,就会解决上述元素覆盖问题. 在坐标系中,通过增 ...
- virtualbox 虚拟机网络设置
1.宿主机网卡设置 virtualbox 第一块网卡设置 virtualbox第二块网卡设置 2.虚拟机网络设置 找到以上设置中MAC地址对应的那个网卡: 配置网络: 重启网络,ok.
- BT Smart vs ANT+ 技术孰优孰劣?
自从Bluetooth SIG提出Bluetooth 4.0,其BLE(Bluetooth Low Energy)开始用于穿戴式电子,而后也用于iBeacon室内定位,更之后Bluetooth 4.1 ...
- 浅析指针(pointer)与引用(reference)
在c++函数中,形式参数用引用和用指针都可以起到在被调用函数中改变调用函数的变量的作用.什么时候用引用作参数?什么时候用指针作参数呢 void function (int *ptr); void fu ...
- iOS中的retainCount
我们都知道iOS中采用引用计数的技术来管理内存,当一个对象没有任何一个地方引用的时候会自动释放,此时的retainCount为0,而且提供了一个-(NSInteger)retainCount的方法来获 ...
- HTML加载顺序总结测试
首先,页面加载顺序:解析HTML结构.加载外部脚本和样式表文件.解析并执行脚本代码.构造HTML DOM模型.加载图片等外部文件.页面加载完毕. 也就是:html → head → title → # ...
- React.js 是什么?
在相当长的一段时间内,我很努力地去尝试理解 React 是什么以及它在应用架构上的健壮程度.这篇文章解答了我希望别人为我解答的疑惑. React 是什么? 和 Angular,Ember,Backbo ...
- js文件中调用另一个js文件:
document.write("<script language='javascript' src='/UEditor/uparse.js'></script") ...