zoukankan      html  css  js  c++  java
  • Delphi XE的RTTI增强,动态Hook某些内部事件

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

    Delphi2010RTTI的增强

    Delphi的Anymouse方法探秘

    万一的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过程,就完成了,完整代码

    作者:不得闲
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原
    文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    vscode使用SSH Targets连接远程系统进行开发
    python2.7版本安装pip
    ubuntu系统安装最新版本nodejs
    win7安装yarn后执行报错
    Object合并,并使用默认值处理
    解决JSON.stringify序列化循环依赖对象报错
    docker环境下安装maven私服和gitlab
    单例模式的无锁实现
    【Java学习笔记】Java的垃圾回收机制
    Ubuntu下源码安装Python
  • 原文地址:https://www.cnblogs.com/DxSoft/p/1925907.html
Copyright © 2011-2022 走看看