Delphi2010之后的RTTI做了很大休整,现在用起来很爽了哦。甚至可以获取某些类的内部私有单元,然后为其赋值!讲这个RTTI增强的,可以参考网上的多个博客内容,我列举一下:

Delphi2010RTTI的增强

Delphi的Anymouse方法探秘

万一的Rtti系列

我这里的主要目的是挂钩某些内部私有事件,然后增加上一些自己的处理过程,这里我以TMenuItem的私有内部事件FOnChange作为例程。 这个私有事件在菜单内部绑定,我们平常状态下,在外部无法更改!但是XE之后这个问题不在存在,使用它的全新RTTI,可以很容易的获得一个类对象的基本 上所有的类的字段以及方法和属性等。

  1. begin
  2. rttiContext := TRttiContext.Create;
  3. rtype := rttiContext.GetType(TMenuItem);
  4. rField := rType.GetField('FOnChange');
  5. if rField <> nil then
  6. begin
  7. V := rField.GetValue(MainMenu1.Items);
  8. OldMenuItemChangeCode := TValueData(V).FAsMethod.Code;
  9. OldSelfData := TValuedata(V).FAsMethod.Data;
  10. TValueData(V).FAsMethod.Code := @TForm1.MenuItemChange;//菜单项目变化
  11. TValueData(V).FAsMethod.Data := self;
  12. rField.SetValue(self.MainMenu1.Items,v);
  13. end;

上面的代码就设置了MainMenu的items的私有事件变量FOnChange的新指向地址为本窗体的实现代码 了,OldMenuItemChangeCode,OldSelfData是保存私有事件的原有方法指针和传递的Self指针对象。用来在我们替换后的对 象中进行调用,不然原过程就不会被调用了。然后我们再来看看,新的FonChange的实现过程

  1. procedure TForm1.MenuItemChange(Sender: TObject; Source: TMenuItem;
  2. Rebuild: Boolean);
  3. var
  4. m: procedure(selfData: TObject;Sender: TObject; Source: TMenuItem;
  5. Rebuild: Boolean);
  6. begin
  7. if Assigned(OldMenuItemChangeCode) then
  8. begin
  9. m := OldMenuItemChangeCode;
  10. m(OldSelfData,Sender,Source,Rebuild);
  11. end;
  12. ShowMessage('菜单修改事件挂钩');
  13. 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某些内部事件的更多相关文章

  1. Delphi里的RTTI与反射(举例换掉FOnChange)

    Delphi2010之后的RTTI做了很大休整,现在用起来很爽了哦.甚至可以获取某些类的内部私有单元,然后为其赋值!讲这个RTTI增强的,可以参考网上的多个博客内容,我列举一下:Delphi2010R ...

  2. Delphi下的RTTI函数大全

    http://ljz9425.blog.163.com/blog/static/369148572008111635253858/ Delphi下的RTTI(下) 2008-12-16 15:52:5 ...

  3. delphi 2010与delphi XE破解版的冲突

    在系统中同时安装了Dephi 2010LITE版与Delphi XE lite后,总是会有一个有问题 是因为两者都是读取C:\ProgramData\Embarcadero目录下的license文件, ...

  4. [转载]: delphi中XLSReadWrite控件的使用(2)---delphi XE下安装

    一.下载 官方下载网址: http://www.axolot.com/components/download.htm 从这里可以下载到从Delphi5到DelphiXE全部支持的版本. 二.软件安装 ...

  5. delphi XE Berlin ReadProcessMemory WriteProcessMemory

    delphi  XE,Berlin [dcc32 Error] Unit9.pas(93): E2033 Types of actual and formal var parameters must ...

  6. FastReport for delphi xe 安装步骤

    FastReport for delphi xe 安装步骤 1.先关闭DELPHI:2.下载后解压到一个目录,比如:D:FR:3.打开D:FR,运行recompile.exe ->点击" ...

  7. Delphi XE的firemonkey获取当前文件所在路径的方法

    Delphi XE的firemonkey获取当前文件所在路径的方法 在之前,我们知道有三种方法: ExtractFilePath(ParamStr(0)) ExtractFilePath(Applic ...

  8. Delphi xe 下快捷使用 FastMM 的内存泄露检测功能

    Delphi xe 集成了FastMM,调试程序是的时候可以方便地检查内存泄露了.  使用方法:在project中,添加一行: ReportMemoryLeaksOnShutdown := Debug ...

  9. Delphi XE中使用dbExpress连接MySQL数据库疑难问题解决(对三层的例子配置有帮助)

    Delphi IDE中包含一个Data Explorer的组件,如下图所示: 该组件基于dbExpress(包含TSQLConnection.TSQLDataSet.TSQLQuery.TSQLSto ...

随机推荐

  1. Linux学习之head命令

    head 与 tail 就像它的名字一样的浅显易懂,它是用来显示开头或结尾某个数量的文字区块,head 用来显示档案的开头至标准输出中,而 tail 想当然尔就是看档案的结尾. 1.命令格式: hea ...

  2. Javascript基础示例:用JS写简易版贪吃蛇(面向对象)

    废话不多说,代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...

  3. Docker容器的数据管理

    Docker容器的数据管理 Docker容器的数据管理 什么是数据卷(Data Volume)? 数据卷是经过特殊设计的目录,可以绕过联合文件系统(UFS),为一个或者多个容器提供访问 数据卷设计的目 ...

  4. jQuery中的.live()与die()

    翻译原文地址:http://www.alfajango.com/blog/exploring-jquery-live-and-die/ 很多开发者都知道jQuery的.live()方法,他们大部分知道 ...

  5. 学习笔记(一) HTML+CSS基础课程

    这个周把慕课网的<HTML+CSS基础课程>课程学完,内容都是非常非常基础的,不过还是学到了几个小知识点,记下来先. <a>超链接发送邮件 直接上把他的图片给挪过来了,我就不打 ...

  6. 修改host文件的P处理

    notepad C:\WINDOWS\system32\drivers\etc\hosts 用文档创建hosts文件,添加上面代码.把文件后缀修改为 .bat 就不用每次很麻烦的查找host文件了.

  7. jquery学习(2)--选择器

    jquery-李炎恢学习视频学习笔记.自己手写. 简单的选择器    css 写 法: #box{ color:#f00;}    //id选择器    jquery获取:$('#box').css( ...

  8. fputcsv 和 fgetcsv

    public function putcsv(){ $list = M("ad")->limit(0,10)->select(); $fp = fopen('./fil ...

  9. C语言 格式说明符

    整数 lL代表long %#0 和%#x 可打印出八进制和十六进制前缀 short int long long long 无符号 八进制 %ho %o %Lo %LLo 十进制 %hu %u %Lu ...

  10. Matlab 之meshgrid, interp, griddata 用法和实例

    http://blog.sina.com.cn/s/blog_67f37e760101bu4e.html 实例结果http://wenku.baidu.com/link?url=SiGsFZIxuS1 ...