首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

Delphi增强RTTI使用技巧征集,该如何处理

2012-02-23 
Delphi增强RTTI使用技巧征集Delphi2010之后的RTTI,功能有了很大增强,希望能将RTTI的一些技巧使用集中征集

Delphi增强RTTI使用技巧征集
Delphi2010之后的RTTI,功能有了很大增强,希望能将RTTI的一些技巧使用集中征集一下。那么就由我来抛出这第一块砖头吧!希望大家踊跃跟帖。
  我这这个技巧用例主要目的是挂钩某些内部私有事件,然后增加上一些自己的处理过程,这里我以TMenuItem的私有内部事件FOnChange作为例程。这个私有事件在菜单内部绑定,我们平常状态下,在外部无法更改!但是XE之后这个问题不在存在,使用它的全新RTTI,可以很容易的获得一个类对象的基本上所有的类的字段以及方法和属性等。

Delphi(Pascal) code
 
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    procedure FormShow1(Sender: TObject);
    procedure MenuItemChange(Sender: TObject; Source: TMenuItem; Rebuild: Boolean);
  public
    { Public declarations }
    OldCode: Pointer;
    OldMenuItemChangeCode: Pointer;
    OldSelfData: TObject;
  end;

var
  Form1: TForm1;

implementation
uses Rtti,TypInfo;

procedure TForm1.Button1Click(Sender: TObject);
var
  Item: TMenuItem;
begin
  Item := TMenuItem.Create(self);
  Item.Caption := '测试';
  MainMenu1.Items.Add(item);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Item: TMenuItem;
begin
  Item := TMenuItem.Create(self);
  Item.Caption := '测试';
  if MainMenu1.Items.Count > 0 then
    MainMenu1.Items.Items[0].Add(item);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  rttiContext: TRttiContext;
  rtype: TRttiType;
  rField: TRttiField;
  V: TValue;
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;
end;

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;



[解决办法]
据说2010的RTTI支持Record了,没试过,有空试试。
[解决办法]

[解决办法]
已经没有几个人在用D2010
[解决办法]
探讨
已经没有几个人在用D2010

------解决方案--------------------


RTTI,设置属性用的多些。
[解决办法]
现在除了没有办法的几个人之外
还有谁在使用delphi?

[解决办法]
这个我不懂哎
[解决办法]
感谢分享
[解决办法]
还在用Delphi7呢,2010暂时是不打算用了
[解决办法]
DELPHI2010(11)很多东西还没研究, 先学习了.

很多东西还是用DELPHI来做最方便! 建议升级到新版本.
[解决办法]
现在还在用bcb6.0,一直没升级过
[解决办法]
谢谢分享
[解决办法]
公司还是D6
期待D2012
[解决办法]
感谢分享
[解决办法]
me too
[解决办法]
好贴,支持!
[解决办法]
感谢分享
[解决办法]
好贴,支持!
[解决办法]
感谢分享
.....目前还在较低版本 Delphi 7 混迹 有空升级下 研究下LZ的东西
[解决办法]
我还在d5
[解决办法]
好,谢谢分享
[解决办法]
还用d7,纯支持一下
[解决办法]
现在delphi版风气很差
delphi到底会发展怎样?谁也说不清,但有一点是最明白不过的,很多人(当然也包括了)正用delphi7赚取大把的RMB
[解决办法]
进来学习一下!
[解决办法]
没玩过,有空玩玩
[解决办法]
感谢分享
[解决办法]

[解决办法]
delphi 学习中……
[解决办法]
dd if=/dev/sda of=MBR bs=512 count=1
[解决办法]
还在使用Delphi 7
[解决办法]
哈,Delphi2010!没用过,哪里有下的?

[解决办法]
好事啊,有空研究研究!
[解决办法]
[code=Delphi(Pascal)]
rttiContext: TRttiContext;
rtype: TRttiType;
rField: TRttiField;
[/code]
这部分是关键
[解决办法]

Delphi(Pascal) code
        rttiContext:   TRttiContext;    rtype:   TRttiType;    rField:   TRttiField;
[解决办法]
好谢谢分享
------解决方案--------------------


谢谢分享
[解决办法]
感谢分享
我在用Delphi 7
[解决办法]
支持这个,谁说没人用很多人在用的
[解决办法]

探讨

感谢分享
我在用Delphi 7

[解决办法]
为什么都用老版本呢?!
[解决办法]
我们公司还在用D6呢。
[解决办法]
我也来吧,我现在正在用Delphi2010,没什么可说的。用了好多年了。
[解决办法]
只是安装几次看了下,没人一起研究啊。
[解决办法]
哪些是符合技巧级别的呢?这个算不算,枚举值转字符串
TValue.From<TMyEnum>(EnumValue).ToString;

[解决办法]
LZ冲动了,那些星星只是曾经用过Delphi.现在说不定连代码都不写了,能来这里看看已经很不错了。你想让他们说什么呢?
[解决办法]

[解决办法]
http://www.360doc.com/content/10/0906/16/2962214_51630027.shtml
RTTI浅析 看了下,东西比较清楚,可惜我想用的一个没有
还在用delphi 7

热点排行