获取控件属性列表分析

本文介绍了如何通过TCustomdxRTTIInspector获取组件属性列表,深入解析了GetComponentsProperties过程和TdxPropInfoList类的作用。tkProperties用于过滤组件属性,如tkClass, tkMethod等。通过TdxPropInfoList创建并遍历属性列表,展示控件属性信息,包括字体属性处理和特定类型的处理,如tkSet和tkClass。" 115010914,9351719,PyTorch学习率衰减策略详解,"['PyTorch', '深度学习', '优化算法', '模型训练', '机器学习']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Retrieves a list of component properties.

Pascal
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;
C++
int GetPropList(PTypeInfo TypeInfo, TTypeKinds TypeKinds, PPropList PropList, Boolean SortList = True);
int GetPropList(PTypeInfo TypeInfo, PPropList PropList);
int GetPropList(TObject * AObject, PPropList PropList);

点击打开链接

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;


循环 Anchors子项   TdxSetProperty
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句话就可以了

procedure TForm1.btn1Click(Sender: TObject);
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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值