Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: xinyiman - Luglio 22, 2013, 07:28:00 pm

Titolo: elenco oggetti
Inserito da: xinyiman - Luglio 22, 2013, 07:28:00 pm
chi mi sa dire come leggere tutti gli oggetti assegnati ad una form? voglio leggere le dimensioni e i punti di partenza
Titolo: Re:elenco oggetti
Inserito da: bonmario - Luglio 22, 2013, 08:00:53 pm
Non sono sicuro di aver capito la domanda, comunque:

Codice: [Seleziona]
var Idx:Integer;
begin
  with Form1 do begin
    for Idx:=0 to ControlCount - 1 do begin
      Memo1.Lines.Add(Controls[Idx].Name);
      Memo1.Lines.Add(IntToStr(Controls[Idx].Top));
      Memo1.Lines.Add(IntToStr(Controls[Idx].Left));
      Memo1.Lines.Add('');
    end;
  end;
end;


Ciao, Mario
Titolo: Re:elenco oggetti
Inserito da: Stilgar - Luglio 22, 2013, 08:47:50 pm
In effetti la domanda non l'ho capite neppure io in questi termini.
Devi fare un for sui controls o sui components a secondo di quello che vuoi "vedere" ...

Stilgar
Titolo: Re:elenco oggetti
Inserito da: Stilgar - Luglio 22, 2013, 08:49:50 pm
Oppure la fai ancora più "sporca" ... sovrascrivi il metodo Notification. Filtri per l'operation "add" e hai tutte le notifiche ogni volta che un "oggetto" ha come parent/owner la form in questione.
Sul remove le togli dalla lista che ti stai gestendo ...

In genere viene usato per altre cose quel metodo ... ;)

Stilgar
Titolo: Re:elenco oggetti
Inserito da: xinyiman - Luglio 23, 2013, 08:28:01 pm
Non sono sicuro di aver capito la domanda, comunque:

Codice: [Seleziona]
var Idx:Integer;
begin
  with Form1 do begin
    for Idx:=0 to ControlCount - 1 do begin
      Memo1.Lines.Add(Controls[Idx].Name);
      Memo1.Lines.Add(IntToStr(Controls[Idx].Top));
      Memo1.Lines.Add(IntToStr(Controls[Idx].Left));
      Memo1.Lines.Add('');
    end;
  end;
end;


Ciao, Mario

ok funziona, ma ipotizziamo che lo vorrei ricorsivo, nel caso che dovessi elencare anche gli oggetti presenti su un tpanel presente sulla form? come fare?
Titolo: Re:elenco oggetti
Inserito da: El Salvador - Luglio 24, 2013, 02:24:10 am
Semplicemente all'interno del ciclo metti il codice per controllare se il componente corrente sia un TPanel. Una volta trovato, bisognerà solamente riutilizzare il codice usato per il form.

Questo è un esempio veloce. :)
Codice: [Seleziona]
procedure TForm1.ListFormControls;

procedure CheckControls(Comp: TCustomControl);
var
  idx: integer;
begin
  for Idx:=0 to Comp.ControlCount - 1 do
  begin
    Memo1.Lines.Add(Format('%s - top%s left%s',[Comp.Controls[Idx].Name,
                                                IntToStr(Comp.Controls[Idx].Top),
                                                IntToStr(Comp.Controls[Idx].Left)]));
    if Comp.Controls[idx] is TPanel then
      CheckControls(TPanel(Comp.Controls[idx]));
  end;
end;

begin
  CheckControls(Self);
end;   
Titolo: Re:elenco oggetti
Inserito da: bonmario - Luglio 24, 2013, 07:54:22 am
Oppure fai una procedura ricorsiva, così come faresti per cercare un file all'interno di una directory e delle sue sottodirectories.

Se ti serve il codice chiedi pure, che provo a buttar giù qualcosa.

Ciao, Mario
Titolo: Re:elenco oggetti
Inserito da: xinyiman - Luglio 24, 2013, 11:40:39 am
mario mi faresti un vero favore. ho provato con la ricorsione ma anche se passavo il componente mi rileggeva i componenti presenti sulla form. avro' toppato qualcosa
Titolo: Re:elenco oggetti
Inserito da: Stilgar - Luglio 24, 2013, 11:45:11 am
Codice: [Seleziona]
procedure CheckControls(Comp: TCustomControl);
var
  idx: integer;
begin
  for Idx:=0 to Comp.ControlCount - 1 do
  begin
    Memo1.Lines.Add(Format('%s - top%s left%s',[Comp.Controls[Idx].Name,
                                                IntToStr(Comp.Controls[Idx].Top),
                                                IntToStr(Comp.Controls[Idx].Left)]));
    if Comp.Controls[idx] is TPanel then
      CheckControls(TPanel(Comp.Controls[idx]));
  end;
end;
xinyiman ... ti hanno postato questo codice ... è questo che non funziona?

Edit:
Letto così mi sembra corretto... e non controlla 2 volte il nodo.
Titolo: Re:elenco oggetti
Inserito da: El Salvador - Luglio 24, 2013, 12:56:22 pm
Citazione
ho provato con la ricorsione ma anche se passavo il componente mi rileggeva i componenti presenti sulla form.
Hai usato il mio esempio? Prima di postarlo, l'ho provato e non rileggeva 2 volte i componenti.

Inoltre attento all'utilizzo del with. Io nell'esempio ho preferito toglierlo ed usare Comp per ogni volta che dovevo accedere alle proprietà del componente dato (cioè Comp.Controls e Comp.ControlCount). Questo per evitare possibili bug involontari, dato che se lasciati da soli, equivalgono a Self.Controls e Self.ControlCount, quindi portano ad un ciclo infinito, in quanto il programma continuerà a controllare l'elenco dei componenti del form.
Titolo: Re:elenco oggetti
Inserito da: Stilgar - Luglio 24, 2013, 01:18:38 pm
Infatti ElSalvador, secondo me si è perso il tuo post.
Per questo gli ho rimesso il codice che avevi preparato come esempio (ed in effetti il costrutto With avrebbe creato solo confusione anche nella lettura del codice. Lo uso veramente poco ed era molto comodo quando si scriveva codice in turbo pascal 5.5) ;)
Titolo: Re:elenco oggetti
Inserito da: bonmario - Luglio 24, 2013, 05:37:18 pm
Ok, allora prova il codice di El Salvador e facci sapere com'è andata.

Ciao, Mario
Titolo: Re:elenco oggetti
Inserito da: xinyiman - Luglio 24, 2013, 05:51:54 pm
Scusate io avevo usato quello di bonmario. quello di el salvador funziona alla grande. grazie
Titolo: Re:elenco oggetti
Inserito da: bonmario - Luglio 24, 2013, 07:30:01 pm
Tra l'altro non mi ero nemmeno accorto che la procedura postata da El Salvador era già ricorsiiva !!!

Ciao, Mario
Titolo: Re:elenco oggetti
Inserito da: brunello - Luglio 28, 2013, 10:12:35 am
avevo necessita' di una procedura simile ed ho provato ad utilizzarla con delphi ma non veniva compilata cosi' l'ho riscritta in maniera tale da ottenere un elenco completo dei componenti della form e funziona in entrambi i casi, saluti Brunello

procedure TForm1.Button1Click(Sender: TObject);

procedure lista(comp: TComponent);
var
  i: integer;
begin
  for i := 0 to comp.ComponentCount - 1 do
    begin
      Memo1.Lines.Add(comp.Components.Name);
      lista(comp.Components);
    end;
end;

begin
  Memo1.Lines.Clear;
  lista(Self);
end;
Titolo: Re:elenco oggetti
Inserito da: El Salvador - Luglio 30, 2013, 08:46:38 pm
Codice: [Seleziona]
procedure lista(comp: TComponent);
var
  i: integer;
begin
  for i := 0 to comp.ComponentCount - 1 do
    begin
      Memo1.Lines.Add(comp.Components[i].Name);
      lista(comp.Components[i]);
    end;
end;
Ti conviene mettere il codice utilizzando il tag (code), altrimenti perdi i vari [ i ] quando crei il post sul forum. :)
Titolo: Re:elenco oggetti
Inserito da: brunello - Luglio 30, 2013, 11:03:33 pm
... scusa non ci avevo fatto caso che si erano persi per strada, ciao Brunello
Titolo: Re:elenco oggetti
Inserito da: El Salvador - Luglio 31, 2013, 12:46:31 am
Tranqui. Non ti devi scusare. Capita :D