能否由一个与某类属性名相同的字符串得到该属性值?(50分)

B

Beast

Unregistered / Unconfirmed
GUEST, unregistred user!
能否由一个与某类属性名相同的字符串得到该属性值?
比如:
A类由一个属性叫Caption
我能否通过一个值为'Caption'的字符串得到A.Caption的值呢?
类似于这样: A.GetValueByPropertyName('Caption')
 
代码:
function GetValue(const S: string): string;
begin
  if S = 'Caption' then
    Result := A.Caption
  else if S = 'Left' then
    Result := IntToStr(A.Left)
  else Result := 'Unknown';
end;
 
可以,你看一下TypInfo单元
GetStrProp函数即可
需要注意的是能访问的属性都必须是: Published类型的,这是因为Delphi只对
published类型产生RTTI信息
 
// uses TypInfo
// 记得引用这个单元

procedure TForm1.Button1Click(Sender: TObject);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(Button1.ClassInfo, 'Caption');
if Assigned(PropInfo) then
SetStrProp(Button1, PropInfo, 'Hello world');
end;

 
这个问题看来是我没有描述清楚:
比如:
有一个TObjA的类的对象ObjA,
ObjA有:
一个String的属性:s
一个integer的属性:i
现在有一个Form上的文本框的名字是EdtS,我需要使用类似这样的语句:
EdtS.text:=ObjA.GetPropValue('S');
不知道这次说明白了没有~~
 
beta不是已经说清楚了么,你可以参考D5开发人员指南,研究RTTI,或者
tseug@263.net 有例子
 
??我迟钝?
我要求的GetPropValue是直接返回属性值的,而GetProInfo返回的是一个PPropInfo呀,
我怎么能直接使用呢?
如果一定要象beta的方法实现就很麻烦了,结合我上面的例子就会是:
var
PropInfo_ObjA,PropInfo_EdtS :pPropInfo;
begin
PropInfo_ObjA := GetPropInfo(ObjA.ClassInfo, 'S');
PropInfo_EdtS := GetPropInfo(ObjA.ClassInfo, 'text');
if Assigned(PropInfo_ObjA) and Assigned(PropInfo_EdtS) then
SetStrProp(EdtS, PropInfo_EdtS, #########);
^^^^^^^^^这里怎么写?
end;
 
[:(],写个满足你要求的函数不就可以了么!
 
在下实在驽钝,那就劳烦兄台一下,指点在下一二,这个函数怎么写?我上面标明的地方应该怎么写?
 
unit MainFrm;

interface

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

type
TMainForm = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Panel1: TPanel;
Button5: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Panel1Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
MainForm: TMainForm;

implementation
uses TypInfo;
{$R *.DFM}

procedure SetIntegerPropertyIfExists(AComp: TComponent
APropName: String;
AValue: Integer);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
if PropInfo^.PropType^.Kind = tkInteger then
SetOrdProp(AComp, PropInfo, AValue);
end;
end;

procedure SetObjectPropertyIfExists(AComponent: TComponent
APropName: String;
AValue: TObject);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(AComponent.ClassInfo, APropName);
if PropInfo <> nil then
begin
if PropInfo^.PropType^.Kind = tkClass then
SetObjectProp(AComponent, PropInfo, AValue);
end;
end;

procedure SetBooleanPropertyIfExists(AComp: TComponent
APropName: String;
AValue: Boolean);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
if PropInfo^.PropType^.Kind = tkEnumeration then
SetOrdProp(AComp, PropInfo, Integer(AValue));
end;
end;

procedure SetStringPropertyIfExists(AComp: TComponent
APropName: String;
AValue: String);
var
PropInfo: PPropInfo;
TK: TTypeKind;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
TK := PropInfo^.PropType^.Kind;
if (TK = tkString) or (TK = tkLString) or (TK = tkWString) then
SetStrProp(AComp, PropInfo, AValue);
end;
end;

procedure SetMethodPropertyIfExists(AComp: TComponent
APropName: String;
AMethod: TMethod);
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
if PropInfo <> nil then
begin
if PropInfo^.PropType^.Kind = tkMethod then
SetMethodProp(AComp, PropInfo, AMethod);
end;
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
SetStringPropertyIfExists(Button1, 'Caption', 'Yahoo');
end;

procedure TMainForm.Button2Click(Sender: TObject);
begin
SetIntegerPropertyIfExists(Button2, 'Width', 50);
end;

procedure TMainForm.Button3Click(Sender: TObject);
begin
SetBooleanPropertyIfExists(Button3, 'Enabled', False);
end;

procedure TMainForm.Button4Click(Sender: TObject);
var
F: TFont;
begin
F := TFont.Create;
F.Name := 'Arial';
F.Size := 24;
F.Color := clRed;
SetObjectPropertyIfExists(Panel1, 'Font', F);
end;

procedure TMainForm.Button5Click(Sender: TObject);
begin
SetMethodPropertyIfExists(Button5, 'OnClick',
GetMethodProp(Panel1, 'OnClick'));
end;

procedure TMainForm.Panel1Click(Sender: TObject);
begin
ShowMessage(Button5.Caption);
end;


end.


 
不对呀~~
上面能做到的实际是“根据一个字符串得到一个对象的属性”而不是“属性值”
上面的代码只能设定属性值,不能得到属性值呀!
 
你的确是比较迟钝,甚至有点懒,下面是这样的函数:
TypInfo.Pas单元:
Function GetStrProp(Instance: TObject
PropName: String): String;
这个函数的用法是:
现在有一个Form上的文本框的名字是EdtS,我需要使用类似这样的语句:
EdtS.text:=ObjA.GetPropValue('S')
// 这是不对的
应该是
EdtS.Text:=GetStrProp(ObjA,'S')
//这是对的
不知道这次说明白了没有~~

 
明白了!!!!
太明白了!!
这得怨我太懒了,没有去看那个单元[:p]呵呵~~
再懒一次吧:
那我怎么知道这个属性是什么类型的呢?
// 谢谢TK128~这个Re完就发分!!
 
又偷一次懒了,你呀,做程序不能这样的!
这是我从TypInfo.pas拷贝下来的
function PropType(Instance: TObject
const PropName: string): TTypeKind
overload;
这个函数能知道某个属性是什么类型的
 
多人接受答案了。
 
顶部