如何动态获取某个类的所有方法/属性,并调用/访问之, 像Java中的反射一样? 800分赠送!

解决方案 »

  1.   

    以下取得参透Delphi,获得类的信息。你可以去下载原代码,盒子中有,
    在18章
    unit Main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, TypInfo, StdCtrls, Buttons, ComCtrls, ExtCtrls, ImgList;type
      TDynIntArr = array of Integer;
      TDynStrArr = array of string;
      TDynArrClass = class(TObject)
      private
        FDynInt: TDynIntArr;
        FDynStr: TDynStrArr;
        procedure SetDynInt(const Value: TDynIntArr);
        procedure SetDynStr(const Value: TDynStrArr);
      published
        property DynInt: TDynIntArr read FDynInt write SetDynInt;
        property DynStr: TDynStrArr read FDynStr write SetDynStr;
      end;  TMainForm = class(TForm)
        ListBoxClasses: TListBox;
        MainSplitter: TSplitter;
        TreeViewClassInfo: TTreeView;
        ImageListClassInfo: TImageList;
        procedure ListBoxClassesClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure TreeViewClassInfoGetImageIndex(Sender: TObject;
          Node: TTreeNode);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      MainForm: TMainForm;implementationuses JuTypInfo, JuUtils;{$R *.dfm}procedure TMainForm.ListBoxClassesClick(Sender: TObject);  procedure SortBranches();
      var
        I: Integer;
      begin
        for I := 0 to Self.TreeViewClassInfo.Items.Count - 1 do
        begin
          if (Self.TreeViewClassInfo.Items[I].Text = 'Properties') or (Self.TreeViewClassInfo.Items[I].Text = 'Events') then
            Self.TreeViewClassInfo.Items[I].CustomSort(nil, 0, False);
        end;
      end;  procedure SetNodeImages();
      var
        I: Integer;
      begin
        for I := 1 to Self.TreeViewClassInfo.Items.Count - 1 do
        begin
          if Self.TreeViewClassInfo.Items[I].HasChildren then
            Self.TreeViewClassInfo.Items[I].ImageIndex := 1
          else
            Self.TreeViewClassInfo.Items[I].ImageIndex := 2;
        end;
      end;var
      StrList: TStrings;
      TypeInfo: PTypeInfo;
    begin
      Self.TreeViewClassInfo.Items.Clear();
      TypeInfo := PTypeInfo(Self.ListBoxClasses.Items.Objects[Self.ListBoxClasses.ItemIndex]);
      StrList := JuTypInfo.TypeInfoToStrings(TypeInfo);
      if Assigned(StrList) then
      begin
        try
          StrList.SaveToFile('Result.txt');
          LoadTreeNodesFromStrings(Self.TreeViewClassInfo.Items, nil, StrList);
          SortBranches();  // Sort properties branches and events branches
          SetNodeImages();  // Change image of node
          Self.TreeViewClassInfo.Items[0].Expand(False);  // Self.TreeViewClassInfo.FullExpand();
        finally
          FreeAndNil(StrList);
        end;
      end;
    end;procedure TMainForm.FormCreate(Sender: TObject);
    begin
      with Self.ListBoxClasses.Items do
      begin
        AddObject('TApplication', System.TypeInfo(TApplication));
        AddObject('TBitBtn', System.TypeInfo(TBitBtn));
        AddObject('TButton', System.TypeInfo(TButton));
        AddObject('TEdit', System.TypeInfo(TEdit));
        AddObject('TLabel', System.TypeInfo(TLabel));
        AddObject('TListBox', System.TypeInfo(TListBox));
        AddObject('TMemo', System.TypeInfo(TMemo));
        AddObject('TComponent', System.TypeInfo(TComponent));
        AddObject('TPersistent', System.TypeInfo(TPersistent));
        AddObject('TBits', System.TypeInfo(TBits));
        AddObject('TObject', System.TypeInfo(TObject));
        AddObject('TTypeKind', System.TypeInfo(TypInfo.TTypeKind));
        AddObject('TAlignment', System.TypeInfo(TAlignment));
        AddObject('TMultiReadExclusiveWriteSynchronizer', System.TypeInfo(TMultiReadExclusiveWriteSynchronizer));
        AddObject('TForm', System.TypeInfo(TForm));
        AddObject('TInterfacedObject', System.TypeInfo(TInterfacedObject));
        AddObject('IStreamPersist', System.TypeInfo(IStreamPersist));
        AddObject('TJuUniqueHash', System.TypeInfo(TJuUniqueHash));
        AddObject('TDynArrClass', System.TypeInfo(TDynArrClass));
        AddObject('TMainForm', System.TypeInfo(TMainForm));
      end;
    end;procedure TMainForm.TreeViewClassInfoGetImageIndex(Sender: TObject; Node: TTreeNode);
    begin
      if Node.IsFirstNode() then
      begin
        Node.ImageIndex := 0;
    //    if Node.Expanded then Node.ImageIndex := 0 else Node.ImageIndex := 1;
        exit;
      end;
      if Node.HasChildren then
      begin
        if Node.Expanded then Node.ImageIndex := 2 else Node.ImageIndex := 1;
      end
      else
        Node.ImageIndex := 3;
    end;{ TDyn }procedure TDynArrClass.SetDynInt(const Value: TDynIntArr);
    begin
      FDynInt := Value;
    end;procedure TDynArrClass.SetDynStr(const Value: TDynStrArr);
    begin
      FDynStr := Value;
    end;end.
      

  2.   

    //==============================================================================
    //将类的所有公开属性值组成字符串************************************************
    //==============================================================================
    function PropSaveStr(Instance: TObject): string;
    var TypeInfo, PropTypeInfo: PTypeInfo;
        TypeData: PTypeData;
        PropInfo: PPropInfo;
        PropList: PPropList;
        PropName: string;
        PropCount: word;
        i: integer;
    begin
      Result := '';
      TypeInfo := Instance.ClassInfo;
      TypeData := GetTypeData(TypeInfo);
      PropCount := TypeData^.PropCount;
      GetMem(PropList, PropCount*SizeOf(Pointer));
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      try
        { Получаем список свойств}
        GetPropInfos(TypeInfo, PropList);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        for i:=1 to PropCount do
        begin
          PropTypeInfo := PropList^[i-1]^.PropType^;
          PropName := PropList^[i-1]^.Name;
          PropInfo := PropList^[i-1];
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          case PropTypeInfo^.Kind of
            tkEnumeration: Result := Result + PropName + ':' +            GetEnumProp   (Instance, PropInfo)  + #13;
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            tkVariant    : Result := Result + PropName + ':' +            GetVariantProp(Instance, PropInfo)  + #13;
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            tkInteger    : Result := Result + PropName + ':' +   IntToStr(GetOrdProp    (Instance, PropInfo)) + #13;
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            tkFloat      : Result := Result + PropName + ':' + FloatToStr(GetFloatProp  (Instance, PropInfo)) + #13;
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            tkSet        : Result := Result + PropName + ':' +            GetSetProp    (Instance, PropInfo)  + #13;
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            tkChar,
            tkWChar,
            tkString,
            tkLString,
            tkWString    : Result := Result + PropName + ':' +            GetStrProp    (Instance, PropInfo)  + #13;
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            tkClass      : Result := Result + PropName + ':' +   VarToStr(GetPropValue  (Instance, PropName)) + #13;
          end;
        end;
      finally
        FreeMem(PropList, PropCount*SizeOf(Pointer));
      end;
    end;//==============================================================================
    //取得指定对象指定属性字符串值**************************************************
    //==============================================================================
    function GetPropStr(Instance: TObject; PropName: string): string;
    var PropInfo: PPropInfo;
    begin
      PropInfo := GetPropInfo(Instance.ClassInfo, PropName);
      case PropInfo.PropType^.Kind of
        tkEnumeration: Result := GetEnumProp(Instance, PropInfo);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkVariant    : Result := GetVariantProp(Instance, PropInfo);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkInteger    : Result := IntToStr(GetOrdProp(Instance, PropInfo));
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkFloat      : Result := FloatToStr(GetFloatProp(Instance, PropInfo));
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkSet        : Result := GetSetProp(Instance, PropInfo);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkChar,
        tkWChar,
        tkString,
        tkLString,
        tkWString    : Result := GetStrProp(Instance, PropInfo);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkClass      : Result := VarToStr(GetPropValue(Instance, PropName));
      else Result := '';
      end;
    end;//==============================================================================
    //设置指定对象指定属性字符串值************************************************
    //==============================================================================
    function SetPropStr(Instance: TObject; PropName: string; PropValue: string): Boolean;
    var PropInfo: PPropInfo;
    begin
      Result := True;
      PropInfo := GetPropInfo(Instance.ClassInfo, PropName);
      if Assigned(PropInfo) then
      case PropInfo.PropType^.Kind of
        tkEnumeration: SetEnumProp(Instance, PropInfo, PropValue);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkVariant    : SetVariantProp(Instance, PropInfo, Variant(PropValue));
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkInteger    : SetOrdProp(Instance, PropInfo, StrToInt(PropValue));
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkFloat      : SetFloatProp(Instance, PropInfo, StrToFloat(PropValue));
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkSet        : SetSetProp(Instance, PropInfo, PropValue);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkChar,
        tkWChar,
        tkString,
        tkLString,
        tkWString    : SetStrProp(Instance, PropInfo, PropValue);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        tkClass      : SetPropValue(Instance, PropName, Variant(PropValue));
      else Result := False;
      end else Result := False;
    end;
      

  3.   


    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    改变控件颜色
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    procedure TForm_Main.Button30Click(Sender: TObject);
    var PropInfo: PPropInfo;
        i: integer;
    begin
      for i:=0 to ComponentCount-1 do
      begin
        PropInfo := GetPropInfo(Components[i].ClassInfo, 'Color');
        if PropInfo<>nil then SetOrdProp(Components[i], PropInfo, clRed);
      end;
    end;
      

  4.   

    樓上的給的答案差不多了, 
    如果還不行, 可參考<<參透>>一書!建議: 這個問題, 給多個 100, 200分就算了, 不要搞什麼800分了!到時可能又有爭論
      

  5.   

    必须保存全部使用到的类信息,在Delphi和C++这类语言中不现实~~~放弃吧