Listowanie komponentów z zamianą Name na Caption

0

Znalazłem w necie kod do wylistowania komponentów w aplikacji. Chodzi mi teraz o to żeby listował nie Name a Caption komponentów.We wszystkich formach. Chodzi mi o Menuitem. Gdy dopisze application.Components nie szuka.

Mój kod:

procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
begin
  for i := 0 to ComponentCount -1 do
  if Components[i] is TMenuItem then
  ListBox1.Items.Add(TMenuItem(Components[i]).Caption);
end;

A gdy zastosuje kod z netu ze strony poniżej nie listuje komponentów typu PopupMenu czy Menu
http://www.marcocantu.com/ddh/ddh15/ddh15f.htm

procedure TDelExForm.AddOwned (
  Node: TTreeNode; Component: TComponent);
var
  I: Integer;
  ChildNode: TTreeNode;
begin
  for I := 0 to Component.ComponentCount - 1 do
  begin
    ChildNode := TreeView.Items.AddChild (Node,
      Format ('%s (%s)', [
        Component.Components[I].Name,
        Component.Components[I].ClassName]));
    AddOwned (ChildNode, Component.Components[I]);
  end;
end;

procedure TDelExForm.BtnOwnerClick(Sender: TObject);
begin
  TreeView.Items.BeginUpdate;
  Screen.Cursor := crHourGlass;
  try
    TreeView.Items.Clear;
    AddOwned (nil, Application);
  finally
    TreeView.Items.EndUpdate;
    Screen.Cursor := crDefault;
  end;
end;
0

Nie do końca rozumiem co chcesz osiągnąć i nie mam teraz dostępu do PC żeby sprawdzić. Ale chyba TMenuItem jest elementem danego TMainMenu lub TPopupMenu, a nie formatki. A do niej się w swoim kodzie odwołujesz. Poza tym jest jeszcze własność Controls.

0

Olesio chodzii mi o to czy jest możliwość zamiany TComponent na string? Aby listować w kodzie najpierw dla Form1 a następnie zamienić Form1 na Form2?

procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
begin
  for i := 0 to Form1.ComponentCount -1 do
  if Form1.Components[i] is TMenuItem then
  ListBox1.Items.Add(TMenuItem(Form1.Components[i]).Caption);
end;

Bo application nie działa jak w kodzie ze strony. Chce plik pomocy stworzyć i dlatego chcę wylistować ze wszystkich form treści w Menu i Popupmenu, żeby mieć tekst apózniej go opisać. Screnów nie chce robić, gdyż form jest dużo.

0

Czy ten kod cokolwiek Tobie dodaje? Dalej uparcie odwołujesz się do formatki, a MenuItem tłumacząc dosłownie to jakby element/pozycja w danym menu. Także jak sama nazwa wskazuje nie jest on elementem formatki. Poza tym nie rozumiem zdania zamienić TComponent na string. Bo co miałby zawierać ten string? A i sprawdzałeś Controls jeśli Components nie działa dla Main/PopupMenu? Chociaż dla MenuItem ostnieje jeszcze własność Items.

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Controls_TWinControl_Controls.html

Edit: przeanalizuj sobie kod z tego dołączonego modułu. Dysponując tylko tabletem w chwili obecnej mogłem pobrać swoje źródła i pokazać ten plik. Wykorzystałem go w dawnych swoich projektach, których GUI miały być w więcej niż jednym języku. Kod nie jest mój i nie jest on idealny, ale częściowo pomoże zrozumieć ideę.

0

Właśnie analizuję. Dzięki

Zrobiłem tak:

procedure AddOwned(Node: TTreeNode; Component: TComponent);
var
  i: Integer;
  ChildNode: TTreeNode;
  Komponent : string;
begin
  for I := 0 to Component.ComponentCount - 1 do
  begin
  if Component.Components[i] is TForm then
    Komponent := TForm(Component.Components[i]).Caption;

  if Component.Components[i] is TLabel then
    Komponent := TLabel(Component.Components[i]).Caption;

  if Component.Components[i] is TMenuItem then
    Komponent := TMenuItem(Component.Components[i]).Caption;

  if Component.Components[i] is TButton then
    Komponent := TButton(Component.Components[i]).Caption;

 // pozostałe klasy dalej ... =>

  ChildNode := Form1.TreeView1.Items.AddChild(Node,
    Format('%s (%s)',[Component.Components[i].Name, Komponent]));

  AddOwned(ChildNode, Component.Components[i]);
  end;
end;
2

Nie bolą Cie palce od pisania tych wszystkich klas? ;)

Rozwiązanie 1:
Użyj RTTI żeby sprawdzić/wyciągnąć własność Caption

Rozwiązanie 2:
Utwórz klasę dziedziczącą z TControl i upublicznij tę własność - małe rzutowanie i voila.

2

Jak sugeruje @spartanPAGE tu można zastosować RTTI wtedy bez problemu można sprawdzić czy dana kontrolka ma właściwość Caption i ją odczytać bez potrzeby rzutowania. Można posłużyć się np. taką funkcją (jest to wersja zgodna ze startym Delphi 7):

//uses TypInfo
function GetCaption(const Control: TControl; out Caption: string): Boolean;
const
  PROPERTY_NAME = 'Caption';
begin
  result:= False;
  if Assigned(Control) and IsPublishedProp(Control, PROPERTY_NAME) then
  begin
    Caption:= GetStrProp(Control, PROPERTY_NAME);
    result:= True;
  end;
end;

Parametry Control - kontrolka której Caption chcesz odczytać, Caption - parametr wychodzący tam będzie odczytany tekst
Funkcja zwraca True jeżeli kontrolka posiada publiczną właściwość Caption
Przykład użycia:

procedure TForm1.Button1Click(Sender: TObject);
var
  CtrlCaption: string;
begin
  if GetCaption(Label1, CtrlCaption)  then
    ShowMessage(CtrlCaption)
  else
    ShowMessage('Ta kontrolka nie posiada właściwości Caption');
end;

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