浅析DelphiXE中的动态Hook某些内部事件

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

Delphi2010RTTI的增强

Delphi的Anymouse方法探秘

万一的Rtti系列

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

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

上面的代码就设置了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;
  5. Sender: TObject; Source: TMenuItem;    
  6.  
  7. Rebuild: Boolean);  
  8. begin  
  9. if 
  10. Assigned(OldMenuItemChangeCode) then  
  11. begin    
  12. m := OldMenuItemChangeCode;      
  13. m(OldSelfData,Sender,Source,Rebuild);    
  14. end;    
  15. ShowMessage('菜单修改事件挂钩');end;  
  16.  

这个代码中最主要的就是如何来调用原来的FOnChange的执行过程了,熟悉Delphi的人应该都知道了Delphi的对象过程中可以使用Self表示当前对象,而这个对象在对象过程中的传递是通过EAX传递的,而此时我们的新过程不是在MainMenu.Items的对象内部调用执行的,所以,我们需要显示的传递SelfData作为源对象中的Self对象指针,所以我申明了一个指针过程如下:

 
 
 
  1. m: procedure(selfData: TObject;Sender: TObject; Source: TMenuItem;  
  2.   Rebuild: Boolean); 

本文名称:浅析DelphiXE中的动态Hook某些内部事件
转载来源:http://www.shufengxianlan.com/qtweb/news8/336108.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联