Lista komponentów VCL dla zaimportowanej Formy

0

Witam,
Chciałbym napisać aplikacje która wyświetli wszystkie komponenty wraz z właściwością "caption" zawarte w Formie. Przypuśćmy, że taka forma została stworzona w Rad Studio i została eksportowana. Następnie zostaje importowana i zostaje sporządzona lista komponentów wraz z właściwością "caption" i następnie eksportowana do Excela. Zna może ktoś jakiś plugin w Rad Studio który umożliwiłby podgląd komponentów z właściwością "caption", bądź jakiś pomysł jak napisać taką aplikacje? Z góry dziękuje.

0

i została eksportowana. Następnie zostaje importowana

co gdzie jak przez kogo? W delphi się nie eksportuje ani ni importuje formatek jako takich. Napisz o co Ci z tym chodzi.
I czy mówisz o własnym programie, czy o robienie listy komponentów dla obcych programów.

Jednym słowem: konkrety.

0

Chodzi mi tylko o uzyskanie informacji (lista komponentów jakie zawiera Forma). Coś takiego jak funkcja "component grid" w Gexperts bądź "structure" bądź jakiś class browser. Tyle że dodatkowo chciałbym mieć podgląd do właściwości "caption" dla każdego komponentu jeśli takowy posiada. Przypuśćmy że chciałbym sporządzić listę wszystkich komponentów+"caption" z konkretnej formy. Można to zrobić w jakiś sposób?
screenshot-20170414083350.png

2
neytro napisał(a):

Chodzi mi tylko o uzyskanie informacji (lista komponentów jakie zawiera Forma).

Banał:
Forma.ControlCount oraz Forma.Controls

Coś takiego jak funkcja "component grid" w Gexperts bądź "structure" bądź jakiś class browser. Tyle że dodatkowo chciałbym mieć podgląd do właściwości "caption" dla każdego komponentu jeśli takowy posiada. Przypuśćmy że chciałbym sporządzić listę wszystkich komponentów+"caption" z konkretnej formy. Można to zrobić w jakiś sposób?

Można.


uses
  Rtti;

procedure TfMain.btn15Click(Sender: TObject);

  procedure GetCaptionForControl(AControl : TWinControl);
  var
    I      : Integer;
    lRProp : TRttiProperty;
  begin
    for I := 0 to AControl.ControlCount - 1 do
    begin
      lRProp := TRttiContext.Create.GetType(AControl.Controls[I].ClassType).GetProperty('Caption');

      if Assigned(lRProp) then
        mmoServerAnswer.Lines.Append(lRProp.GetValue(AControl.Controls[i]).ToString);

      if AControl.Controls[I] is TWinControl then
        GetCaptionForControl(TWinControl(AControl.Controls[I]));
    end;
  end;

begin
  mmoServerAnswer.Clear;
  GetCaptionForControl(Self);
end;

mmoServerAnswer to zwykłe TMemo

1

@wloochacz Dlaczego sprawdzasz czy TWinControl jak właściwość Caption może mieć choćby TLabel.
Coś takiego:


uses
  System.TypInfo;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateControlsList(Form1);
end;

procedure TForm1.CreateControlsList(AParent: TWinControl);
var
  i: Integer;
  PropInfo: PPropInfo;
  Item: TListItem;
begin
  for i:= 0 to AParent.ControlCount -1 do
  begin
    PropInfo:= GetPropInfo(AParent.Controls[i], 'Caption');
    if Assigned(PropInfo) then //komnponent ma wlasciwosc Caption
    begin
       Item:= ListView1.Items.Add; //dodanie do ListView
       Item.Caption:= AParent.Controls[i].Name;
       Item.SubItems.Add(GetPropValue(AParent.Controls[i], PropInfo, True)); //pobranie caption
    end;
    //jezeli to twincontrol to moze byc rodzicem wiec rekurencyjne wywolanie procedury
    if AParent.Controls[i] is TWinControl then
      CreateControlsList(TWinControl(AParent.Controls[i]));
  end;
end;
0
kAzek napisał(a):

@wloochacz Dlaczego sprawdzasz czy TWinControl jak właściwość Caption może mieć choćby TLabel.

Dlatego, że trzeba obsłużyć pod-kontenery na kontrolki (panel, pagecontrol, itd.)
Poza tym - no co Ty opowiadasz, sprawdź jeszcze raz ;-)

0

@wloochacz:
Twoje rozwiązanie jest skuteczne, ale ma wycieki pamięci

procedure TF_dokument.Button4Click(Sender: TObject);

  procedure GetCaptionForControl(AControl: twincontrol);
  var
    I: integer;
    lRProp: TRttiProperty;
    lRttiContext: TRttiContext;
  begin
    for I := 0 to AControl.ControlCount - 1 do
    begin
      lRttiContext := TRttiContext.Create;
      try
        lRProp := lRttiContext.GetType(AControl.Controls[I].ClassType).GetProperty('Caption');
        if Assigned(lRProp) then
          self.Memo1.Lines.Append(lRProp.GetValue(AControl.Controls[I]).ToString);
      finally
        lRttiContext.free;
      end;
      if AControl.Controls[I] is twincontrol then
        GetCaptionForControl(twincontrol(AControl.Controls[I]));
    end;
  end;

begin
  self.Memo1.Lines.Clear;
  GetCaptionForControl(self);
end;
0

@grzegorz_so: w którym miejscu? TRttiContext to rekord, nie klasa.

System.Rtti.TRttiContext.Free

Note: A call to Free is not necessary because the instance is released when the TRttiContext gets out of scope.

2

bez '.create' bez '.free' i bez wycieków pamięci

procedure TF_dokument.Button4Click(Sender: TObject);

  procedure GetCaptionForControl(AControl: twincontrol);
  var
    I: integer;
    lRProp: TRttiProperty;
    lRttiContext: TRttiContext;
  begin
    for I := 0 to AControl.ControlCount - 1 do
    begin

      lRProp := lRttiContext.GetType(AControl.Controls[I].ClassType).GetProperty('Caption');

      if Assigned(lRProp) then
        self.Memo1.Lines.Append(lRProp.GetValue(AControl.Controls[I]).ToString);

      if AControl.Controls[I] is twincontrol then
        GetCaptionForControl(twincontrol(AControl.Controls[I]));

    end;
  end;

begin
  self.Memo1.Lines.Clear;
  GetCaptionForControl(self);
end;
0

Dzięki właśnie o coś takiego mi chodziło :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1