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.
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.
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?
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
@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;
kAzek napisał(a):
@wloochacz Dlaczego sprawdzasz czy
TWinControl
jak właściwośćCaption
może mieć choćbyTLabel
.
Dlatego, że trzeba obsłużyć pod-kontenery na kontrolki (panel, pagecontrol, itd.)
Poza tym - no co Ty opowiadasz, sprawdź jeszcze raz ;-)
@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;
@grzegorz_so: w którym miejscu? TRttiContext
to rekord, nie klasa.
Note: A call to Free is not necessary because the instance is released when the TRttiContext gets out of scope.
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;
Dzięki właśnie o coś takiego mi chodziło :)