Author: Jonas Bilinkevicius
I am looking for code that returns a property value (presumably as a variant type)
based on the text name of the property, similar to the TTable.FieldByName function.
Answer:
This should get you started. You need to study the comments "typinfo.pas" for more
info.
1 unit MorePropInfo;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 StdCtrls;
8
9 type
10 TFrmMorePropInfo = class(TForm)
11 Button1: TButton;
12 Button2: TButton;
13 ListBox1: TListBox;
14 procedure Button2Click(Sender: TObject);
15 private
16 { Private declarations }
17 public
18 { Public declarations }
19 end;
20
21 var
22 FrmMorePropInfo: TFrmMorePropInfo;
23
24 implementation
25
26 {$R *.DFM}
27
28 uses
29 TypInfo;
30
31 procedure GetPropertyValues(AObj: TObject; AValues: TStrings);
32 var
33 count: integer;
34 data: PTypeData;
35 default: string;
36 i: integer;
37 info: PTypeInfo;
38 propList: PPropList;
39 propInfo: PPropInfo;
40 propName: string;
41 value: variant;
42 begin
43 info := AObj.ClassInfo;
44 data := GetTypeData(info);
45 GetMem(propList, data^.PropCount * SizeOf(PPropInfo));
46 try
47 count := GetPropList(info, tkAny, propList);
48 for i := 0 to count - 1 do
49 begin
50 propName := propList^[i]^.Name;
51 propInfo := GetPropInfo(info, propName);
52 if propInfo <> nil then
53 begin
54 case propInfo^.PropType^.Kind of
55 tkClass, tkMethod:
56 value := '$' + IntToHex(GetOrdProp(AObj, propInfo), 8);
57 tkFloat:
58 value := GetFloatProp(AObj, propInfo);
59 tkInteger:
60 value := GetOrdProp(AObj, propInfo);
61 tkString, tkLString, tkWString:
62 value := GetStrProp(AObj, propInfo);
63 tkEnumeration:
64 value := GetEnumProp(AObj, propInfo);
65 else
66 value := '???';
67 end;
68 if propInfo.default = longint($80000000) then
69 default := 'none'
70 else
71 default := IntToStr(propInfo.default);
72 AValues.Add(Format('%s: %s [default: %s]', [propName, value, default]));
73 {$80000000 apparently indicates "no default"}
74 end;
75 end;
76 finally
77 FreeMem(propList, data^.PropCount * SizeOf(PPropInfo));
78 end;
79 end;
80
81 procedure TFrmMorePropInfo.Button2Click(Sender: TObject);
82 var
83 count: integer;
84 data: PTypeData;
85 i: integer;
86 info: PTypeInfo;
87 propList: PPropList;
88 propInfo: PPropInfo;
89 propName: string;
90 propVal: variant;
91 tmpS: string;
92 begin
93 info := Button2.ClassInfo;
94 data := GetTypeData(info);
95 GetMem(propList, data^.PropCount * SizeOf(PPropInfo));
96 try
97 count := GetPropList(info, tkAny, propList);
98 ListBox1.Clear;
99 for i := 0 to count - 1 do
100 begin
101 propName := propList^[i]^.Name;
102 propInfo := GetPropInfo(info, propName);
103 if propInfo <> nil then
104 begin
105 case propInfo^.PropType^.Kind of
106 tkClass, tkMethod:
107 propVal := '$' + IntToHex(GetOrdProp(Button2, propInfo), 8);
108 tkFloat:
109 propVal := GetFloatProp(Button2, propInfo);
110 tkInteger:
111 propVal := GetOrdProp(Button2, propInfo);
112 tkString, tkLString, tkWString:
113 propVal := GetStrProp(Button2, propInfo);
114 tkEnumeration:
115 propVal := GetEnumProp(Button2, propInfo);
116 else
117 propVal := '...';
118 end;
119 tmpS := propVal;
120 ListBox1.Items.Add(Format('%s: %s [default: %s]', [propName, tmpS, '$'
121 + IntToHex(propInfo.default, 8)]));
122 {$80000000 apparently indicates "no default"}
123 end;
124 end;
125 finally
126 FreeMem(propList, data^.PropCount * SizeOf(PPropInfo));
127 end;
128 end;
129
130 end.
|