Retrieves a list of component properties.
function GetPropList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropList; SortList: Boolean = True): Integer; overload; function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): Integer; overload; function GetPropList(AObject: TObject; out PropList: PPropList): Integer; overload;
procedure TCustomdxRTTIInspector.SetInspectedObject(Value: TPersistent);
-》CreatePropertyRows-》GetComponentsProperties
procedure TCustomdxRTTIInspector.GetComponentsProperties(const AInstances: array of TPersistent);
tkProperties 就是 AFilter。
tkProperties = tkAny - tkMethods - [tkUnknown]; 是在typInfo。pas文件中定义的。
procedure dxGetComponentProperties(AOwner: TComponent; AComponents: TdxComponentList;
AFilter: TTypeKinds; AProc: TdxGetPropEditProc);
var
I, J, CompCount: Integer;
CompType: TClass;
Candidates: TdxPropInfoList;
PropLists: TList;
Editor: TdxPropertyEditor;
EdClass: TdxPropertyEditorClass;
PropInfo: PPropInfo;
AddEditor: Boolean;
Obj: TPersistent;
begin
if (AComponents = nil) or (AComponents.Count = 0) then Exit;
CompCount := AComponents.Count;
Obj := AComponents[0];
CompType := AComponents[0].ClassType;//TFont
Candidates := TdxPropInfoList.Create(AComponents[0], AFilter);//获得了TFont的7个子属性 转而调用 TdxPropInfoList.Create
try
for I := Candidates.Count - 1 downto 0 do
begin
PropInfo := Candidates[I]; //font 7 个属性
EdClass := dxGetEditorClass(PropInfo, AComponents[0]);
...
AProc(Editor)
end;
procedure TdxSetProperty.GetProperties(Proc: TdxGetPropEditProc);
var
I: Integer;
begin
with GetTypeData(GetTypeData(GetPropType)^.CompType^)^ do
for I := MinValue to MaxValue do
Proc(TdxSetElementProperty.Create(FPropList, FPropCount, I));
end;
Font属性获取
TdxFontProperty
TdxClassProperty
'Constraints'
循环取子属性
ipaSubProperties
PropertyEditor.GetProperties(CreateRows);
也就是这个方法
procedure TdxClassProperty.GetProperties(Proc: TdxGetPropEditProc);
var
Components: TdxComponentList;
I: Integer;
begin
Components := TdxComponentList.Create;
try
for I := 0 to PropCount - 1 do
if TComponent(GetOrdValueAt(I)) <> nil then
Components.Add(TComponent(GetOrdValueAt(I)));
dxGetComponentProperties(nil, Components, tkProperties, Proc);//这个调用 TdxFontCharsetProperty 'Charset'
finally
Components.Free;
end;
end;
CompType ,把 TFont当做类再取该类的属性
- font的处理是AProc(Editor)转而调用下面函数,
- 控件属性从这里开始循环
procedure TCustomdxRTTIInspector.CreateRows(PropertyEditor: TdxPropertyEditor);
var
RowClass: TdxInspectorRowClass;
PropertyAttributes: TdxPropertyAttributes;
begin
RowClass := GetRowClass(PropertyEditor);
if RowClass = nil then Exit;
FCurrentRow := CreateRow(RowClass);
PropertyAttributes := PropertyEditor.GetAttributes;
FCurrentRow.Caption := PropertyEditor.GetName;
FCurrentRow.EditText := PropertyEditor.Value;
FCurrentRow.MaxLength := PropertyEditor.GetEditLimit;
FCurrentRow.ReadOnly :=
([ipaReadOnly, ipaSubProperties] * PropertyAttributes <> []);
FCurrentRow.Tag := Integer(PropertyEditor);
if FCurrentRow is TdxInspectorTextPickRow then
begin
PropertyEditor.GetValues(GetStrProc);
with TdxInspectorTextPickRow(FCurrentRow) do
begin
ImmediateDropDown := False;
Revertable := False;
PopupBorder := pbSingle;
OnCloseUp := PickRowCloseUp;
end;
end;
if FCurrentRow is TdxInspectorTextButtonRow then
TdxInspectorTextButtonRow(FCurrentRow).OnButtonClick := RowButtonClick;
FCurrentRow.Node.MoveTo(FParentNode, inaAddChild);
if ipaSubProperties in PropertyAttributes then
begin
//取子属性
if FCurrentRow.Caption = 'Font' then
ShowMessage('bbb');
FParentNode := FCurrentRow.Node;
PropertyEditor.GetProperties(CreateRows);//转而调用TdxClassProperty.GetProperties
FParentNode := FParentNode.Parent;
end;
end;
TPropInfo = packed record
PropType: PPTypeInfo;
GetProc: Pointer;
SetProc: Pointer;
StoredProc: Pointer;
Index: Integer;
Default: Longint;
NameIndex: SmallInt;
Name: ShortString;
end;
TTypeInfo = record
Kind: TTypeKind;
Name: ShortString;
{TypeData: TTypeData}
end;
TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,
tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,
tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray);
可见flist[0].PropType的TTypeKind类型描述就是要分析处理,也就是TTypeKind类型
tkClass, tkMethod,tkEnumeration、tkSet 事件,类属性(字体)函数,枚举、集合
type TAnchors = set of TAnchorKind;
type TAnchorKind = (akTop, akLeft, akRight, akBottom);
- 获取控件属性个数及信息,下面4句话就可以了
var
FCount:Integer;
FSize:Integer;
FList:PPropList;
i:Integer;
begin
FCount := GetPropList(Button1.ClassInfo, tkProperties, nil);// tkAny 全部属性 tkMethods 事件属性 tkProperties 属性
FSize := FCount * SizeOf(Pointer);
GetMem(FList, FSize);
GetPropList(Button1.ClassInfo, tkProperties, FList);
for i:=0 to FCount do
begin
if flist[i].PropType^.Kind in[ tkSet,tkClass] then
对特定类型处理
self.mmo1.Lines.Add( flist[i].Name );end;
FreeMem(flist,FSize);
end;procedure TdxEnumProperty.GetValues(Proc: TGetStrProc);
var
I: Integer;
EnumType: PTypeInfo;
begin
EnumType := GetPropType;
with GetTypeData(EnumType)^ do
for I := MinValue to MaxValue do
Proc(GetEnumName(EnumType, I));
end;
constructor TdxPropInfoList.Create(Instance: TPersistent; Filter: TTypeKinds);
begin
FCount := GetPropList(Instance.ClassInfo, Filter, nil);
FSize := FCount * SizeOf(Pointer);
GetMem(FList, FSize);
GetPropList(Instance.ClassInfo, Filter, FList);
end;