真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網站制作重慶分公司

Delphi中怎么使用RTTI

今天就跟大家聊聊有關Delphi中怎么使用RTTI,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據(jù)這篇文章可以有所收獲。

我們提供的服務有:成都網站建設、做網站、微信公眾號開發(fā)、網站優(yōu)化、網站認證、官渡ssl等。為上千家企事業(yè)單位解決了網站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的官渡網站制作公司

概要

運行期類型信息(RTTI)是一種語言特征,能使應用程序在運行時得到關于對象的信息。

RTTI是Delphi的組件能夠融合到IDE中的關鍵。它在IDE中不僅僅是一個純學術的過程。
由于對象都是從TObject繼承下來的,因此,對象都包含一個指向它們的RTTI的指針以及幾個內建的方法。下面的表列出了TObject的一些方法,用這些方法能獲得某個對象實例的信息。

Delphi中怎么使用RTTI

 

第一部分:關于as 和 is

Object Pascal提供了兩個運算符as和is,用它們通過RTTI能對對象進行比較和強制類型轉換。
   關鍵字as是類型轉換的一種新的形式。它能把一個基層的對象強制類型轉換成它的派生類,如果轉換不合法就產生一個異常。假定有一個過程,想讓它能夠傳遞任何類型的對象,它應該這樣定義:
   Procedure Foo(AnObject :Tobject);
   在這個過程如果要對AnObject進行操作,要把它轉換為一個派生對象。假定把AnObject看成是一個TEdit派生類型,并想要改變它所包含的文本,用下列代碼:  (AnObject as Tedit).text := 'wudi_1982';
   能用比較運算符來判斷兩個對象是否是相兼容的類型,用is運算符把一個未知的對象和一個已知類型或實例進行比較,確定這個未知對象的屬性和行為。例如,在對(AnObject 進行強制類型轉換前,確定(AnObject 和TEdit是否指針兼容:

if (AnObject is Tedit) then
    Tedit(AnObjject).text := 'wudi_1982';
   注意在這個例子中不要再使用as進行強制類型轉換,這是因為它要大量使用RTTI,另外還因為,在第一行已經判斷Foo就是TEdit,可以通過在第2行進行指針轉換來優(yōu)化。

procedure TForm1.ClearEdit(Acontrl: TWinControl);
var
  i : integer;
begin
  for i := 0 to Acontrl.ControlCount-1 do
  begin
  if Acontrl.Controls[i] is TEdit then
  ((Acontrl.Controls[i]) as TEdit).Text := '';
  if Acontrl.Controls[i] is TCustomControl then
  ClearEdit( (Acontrl.Controls[i] as TCustomControl))
  end;
end;

 

第二部分:RTTI

上文中已經多次提到了RTTI,但好像并沒有看到RTTI出現(xiàn)。那么RTTI是如何表現(xiàn)自己的呢?你將發(fā)現(xiàn), RTTI至少在兩個地方對你有用。第一個地方是DELPHI的IDE,這在前面已提到過。通過RTTI,IDE就會知道你正在使用的對象和組件的任何事情。實際上,不只是RTTI,但為了這個討論,我們只談RTTI方面。其實上面的as,is操作都間接的使用了RTTI。
還是用個例子來演示吧。在觀看此例子之時,建議你看看typinfo.pas中的內容(DELPHI安裝目錄下/source/rtl/common/TypInfo.pas);
下面的例子主要分為兩部分,界面上半部分,主要演示通過rtti來顯示用戶選擇類型的信息。(有3個TListBox)。
下面的部分主要通過RTTI來完成通過配置信息對控件進行屬性的賦值操作,這里將演示文本類型和事件類型的賦值。
窗體文件如下:代碼如下:

object Form1: TForm1
  Left = 150
  Top = 161
  Width = 639
  Height = 372
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
  Left = 0
  Top = 0
  Width = 631
  Height = 185
  Align = alTop
  TabOrder = 0
  object GroupBox1: TGroupBox
    Left = 1
    Top = 1
    Width = 185
    Height = 183
    Align = alLeft
    Caption = '在這里選擇要查看類型的信息'
    TabOrder = 0
    object ListBox1: TListBox
      Left = 2
      Top = 15
      Width = 181
      Height = 166
      Align = alClient
      ItemHeight = 13
      TabOrder = 0
      OnClick = ListBox1Click
    end
  end
  object GroupBox2: TGroupBox
    Left = 368
    Top = 1
    Width = 262
    Height = 183
    Align = alRight
    Caption = '屬性信息'
    TabOrder = 1
    object ListBox3: TListBox
      Left = 2
      Top = 15
      Width = 258
      Height = 166
      Align = alClient
      ItemHeight = 13
      TabOrder = 0
    end
  end
  object GroupBox3: TGroupBox
    Left = 186
    Top = 1
    Width = 182
    Height = 183
    Align = alClient
    Caption = '基本信息'
    TabOrder = 2
    object ListBox2: TListBox
      Left = 2
      Top = 15
      Width = 178
      Height = 166
      Align = alClient
      ItemHeight = 13
      TabOrder = 0
    end
  end
  end
  object TPanel
    Left = 0
    Top = 185
    Width = 631
    Height = 157
    Align = alClient
    TabOrder = 1
    object Panel2: TPanel
      Left = 1
      Top = 1
      Width = 230
      Height = 155
      Align = alLeft
      TabOrder = 0
      object Label2: TLabel
        Left = 10
        Top = 8
        Width = 84
        Height = 13
        Caption = '要修改的控件名'
      end
      object Label3: TLabel
        Left = 8
        Top = 32
        Width = 72
        Height = 13
        Caption = '修改的屬性名'
      end
      object Label4: TLabel
        Left = 8
        Top = 64
        Width = 72
        Height = 13
        Caption = '將屬性修改為'
      end
      object edComName: TEdit
        Left = 104
        Top = 5
        Width = 78
        Height = 21
        TabOrder = 0
        Text = 'label1'
      end
      object edPproName: TEdit
        Left = 104
        Top = 32
        Width = 81
        Height = 21
        TabOrder = 1
        Text = 'caption'
      end
      object edValue: TEdit
        Left = 104
        Top = 56
        Width = 81
        Height = 21
        TabOrder = 2
        Text = '12345'
      end
      object btnInit: TButton
        Left = 8
        Top = 104
        Width = 75
        Height = 25
        Caption = '初始化'
        TabOrder = 3
        OnClick = btnInitClick
      end
      object btnModify: TButton
        Left = 104
        Top = 104
        Width = 75
        Height = 25
        Caption = '修改'
        TabOrder = 4
        OnClick = btnModifyClick
      end
    end
    object Panel3: TPanel
      Left = 231
      Top = 1
      Width = 399
      Height = 155
      Align = alClient
      TabOrder = 1
      object GroupBox4: TGroupBox
        Left = 1
        Top = 1
        Width = 397
        Height = 153
        Align = alClient
        Caption = '被修改的控件'
        TabOrder = 0
      object Label1: TLabel
        Left = 16
        Top = 32
        Width = 28
        Height = 13
        Caption = 'label1'
      end
      object BitBtn1: TBitBtn
        Left = 8
        Top = 64
        Width = 75
        Height = 25
        Caption = 'BitBtn1'
        TabOrder = 0
      end
    end
  end
end
end

unit main;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
  Forms,Dialogs,typinfo, StdCtrls, ExtCtrls, Buttons;
 
type
  InsertCom = record
  Name : string; //要修改屬性的組件名
  PproName : string;//要修改控件的屬性名
  MethodName :string;//要修改or添加給控件的事件名
  text : string; //屬性值,這里修改的是string類型的數(shù)值
  end;
  TForm1 = class(TForm)
  Panel1: TPanel;
  GroupBox1: TGroupBox;
  ListBox1: TListBox;
  GroupBox2: TGroupBox;
  GroupBox3: TGroupBox;
  ListBox2: TListBox;
  ListBox3: TListBox;
  Panel2: TPanel;
  edComName: TEdit;
  Label2: TLabel;
  Label3: TLabel;
  edPproName: TEdit;
  Label4: TLabel;
  edValue: TEdit;
  Panel3: TPanel;
  btnInit: TButton;
  btnModify: TButton;
  GroupBox4: TGroupBox;
  Label1: TLabel;
  BitBtn1: TBitBtn;
 
  procedure FormCreate(Sender: TObject);
  procedure ListBox1Click(Sender: TObject);
  procedure btnInitClick(Sender: TObject);
  procedure btnModifyClick(Sender: TObject);
  private
  TestCom : InsertCom;
  procedure MyClick(Sender : TObject); //給控件添加onclick事件
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
function CreateClass(const AClassName : string):TObject;//根據(jù)名字生成
var
  tm : TObject;
  t : TFormClass;
begin
  t := TFormClass(FindClass(AClassName));
  tm := t.Create(nil);
  Result := tm;
end;
 
procedure GetBaseClassInfo(AClass : TObject;AStrings : TStrings); //獲得類型的基本信息
var
  classTypeInfo : PTypeInfo;
  ClassDataInfo : PTypeData;
begin
  classTypeInfo := AClass.ClassInfo;
  ClassDataInfo := GetTypeData(classTypeInfo);
  with AStrings do
  begin
    Add(Format('name is :%s',[classTypeInfo.Name]));
    Add(format('type kind is :%s',[GetEnumName(TypeInfo (TTypeKind),integer(classTypeInfo.Kind))]));
    Add(Format('in : %s',[ClassDataInfo.UnitName]));
  end;
end;
 
procedure GetBaseClassPro(AClass : TObject;Astrings : TStrings); //獲得屬性信息
var
  NumPro : integer; //用來記錄事件屬性的個數(shù)
  Pplst : PPropList; //存放屬性列表
  Classtypeinfo : PTypeInfo;
  classDataInfo: PTypeData;
  i : integer;
begin
  Classtypeinfo := AClass.ClassInfo;
  classDataInfo := GetTypeData(Classtypeinfo);
  if classDataInfo.PropCount <> 0 then
  begin
    //分配空間
    GetMem(Pplst,sizeof(PpropInfo)*classDataInfo.PropCount);
    try
      //獲得屬性信息到pplst
      GetPropInfos(AClass.ClassInfo,Pplst);
      for I := 0 to classDataInfo.PropCount - 1 do
      begin
        if Pplst[i]^.PropType^.Kind <> tkMethod then
        //這里過濾掉了事件屬性
           Astrings.Add(Format('%s:%s',[Pplst[i]^.Name,Pplst[i]^.PropType^.Name]));
      end;
      //獲得事件屬性
      NumPro := GetPropList(AClass.ClassInfo,[tkMethod],Pplst);
      if NumPro <> 0 then
      begin
       //給列表添加一些標志
       Astrings.Add('');
       Astrings.Add('-----------EVENT-----------');
       Astrings.Add('');
       for i := 0 to NumPro - 1 do //獲得事件屬性的列表
         Astrings.Add(Format('%s:%s',[Pplst[i]^.Name,Pplst[i]^.PropType^.Name]));
      end;
    finally
      FreeMem(Pplst,sizeof(PpropInfo)*classDataInfo.PropCount);
    end;
  end;
end;
 
 
procedure TForm1.btnInitClick(Sender: TObject);
begin
  //修改label1的caption屬性為12345
  TestCom.Name := edComName.Text;
  TestCom.PproName := edPproName.Text;
  TestCom.text := edValue.Text;
  TestCom.MethodName := 'OnClick';
  btnModify.Enabled := true;
end;
 
procedure TForm1.btnModifyClick(Sender: TObject);
var
  pp : PPropInfo;
  obj : TComponent;
  a : TMethod;
  tm : TNotifyEvent;
begin
  obj := FindComponent(TestCom.Name);//通過名字查找此控件
  if not Assigned(obj) then exit; //如果沒有則退出
  //通過getPropInfo獲得指定控件的屬性信息,注意,這里只能獲得那些公開了的屬性
  pp := GetPropInfo(obj.ClassInfo,TestCom.PproName);
  if Assigned(pp) then
  begin
    //根據(jù)kind判斷類型是否為string類型
    case pp^.PropType^.Kind of
      //這里使用setStrProp來為string類型的屬性賦值,對起來類型的賦值,請參考TypInfo.pas
      tkString,tkLString,tkWString : SetStrProp(obj,TestCom.PproName,TestCom.text);
    end;
    //給要修改的控件添加onClick事件,
    pp := GetPropInfo(obj.ClassInfo,TestCom.MethodName);
    if Assigned(pp) then
    begin
      if pp^.PropType^.Kind = tkMethod then
      begin
        tm := MyClick;
        //Tmethod的code為函數(shù)地址,你也可以通過MethodAddress方法獲得
        a.Code := @tm;
        a.Data := Self;
        //對時間賦值
        SetMethodProp(obj,TestCom.MethodName,a);
      end;
    end;
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  btnModify.Enabled := false;
  //給listbox1添加一些類型的類名
  with ListBox1.Items do
  begin
    Add('TApplication');
    Add('TEdit');
    Add('TButton');
    Add('Tmemo');
    Add('TForm');
  end;
end;
 
procedure TForm1.ListBox1Click(Sender: TObject);
var
  t : TObject;
begin
  //當在類型列表中選擇一個類型并用鼠標單擊后,分別得到它的屬性信息和基本信息
  ListBox2.Clear;
  ListBox3.Clear;
  t := CreateClass(ListBox1.Items[ListBox1.ItemIndex]);
  try
    GetBaseClassInfo(t,ListBox2.Items);
    GetBaseClassPro(t,ListBox3.Items);
  finally
    t.Free;
  end;
end;
 
procedure TForm1.MyClick(Sender: TObject);
begin
  //給指定控件添加的一個方法
  ShowMessage('wudi_1982');
end;
 
initialization
  //初始化的時候注冊
  RegisterClasses([TApplication,TButton,TEdit,TMemo,TForm]);

看完上述內容,你們對Delphi中怎么使用RTTI有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


本文名稱:Delphi中怎么使用RTTI
標題URL:http://weahome.cn/article/pgdpgi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部