jak 'trzymac' dynamiczne komponenty

0

Witam

robie aplikacje z duza iloscia dynamicznych komponentow.

zastanwiam sie jak je umiescic w programi...
bo tworzenie zmiennych juz w kodzie mija sie z celem,
moge tez na formularzu umiescic ListeKomponentow (TList), ale przeciez jest juz takie cos (ComponentList)
zasatanwiam sie tez nad jakimis tablicami komponentow ale zadne z tych rozwiazan
jakos mi nie pasuje.

macie jakies pomysly jak to rozwiazac?
Jak sami to robicie?

pozdrawiam

0

a czemu lista / tablica CI nie pasuje??

0

ja sie moze nie znam
(ale mysle ze z duzej ilosci 'dziwnych' pomyslow zawsze moze wyjsc cos interesujacego:P)
ale jak sie tworzy komponenty uzywajac TList to sa one dostepne przez ta wlasnie liste
oraz przez liste Components rodzica.

jakos mam takie zboczenie ze chcialbym zeby wszystko bylo tylko raz
wiec wymyslilem cos takiego:

begin  
  TPanel.Create(Form1); // zauwaz ze nie ma tu zmiennej ktora przyjmuje stworzony obiekt
  with TPanel(Components[ComponentCount-1]) do begin
    parent := Form1;
    left := 10;
    top := 10;
    width := 100;
    height := 100;
  end;
end;

dzieki temu program jest lzejszy o jedna TList:D

chetnie dowiem sie co o tym myslicie
moze sa jakies oczywiste przeciwwskazania
dla takiego rozwiazania:-) o ktorych nie pomyslalem?

0

A jeśli nie będzie ten komponent dodany dokładnie na pozycji ComponentCount - 1 w tablicy Components? Jeśli pokombinują coś w przyszłej wersji Delphi, będziesz musiał zmieniać kod :) Pierwsze 2 linijki zastąpiłbym taką:

with TPanel.Create(Form1) do begin

I włala :)

Zresztą jeśli program nie ma bardzo dużo zmiennych, setek komponentów dynamicznych itd. to moim zdaniem możesz spokojnie używać też listy, wiele pamięci nie zje, a zawsze może być wygodniej dla Ciebie :) Tylko znowu dochodzi problem pilnowania wskaźników. Tablicę Components trzyma właściciel, z listą musiałbyś bawić się sam (chodzi mi o problem pt. "czy obiekt jeszcze istnieje", tzn. w ogólności o wiszące wskaźniki).

0

ja jestem takiego zdania

  1. co sam stworzyłem sam niszczę - czyli zawsze create(nil), żeby mi nic nie zrobiło Destroy na obiekcie
  2. z tego co mi wiadomo (ale mogę się mylić) to komponent "wędrują" po liście ComponentList, tzn zmieniają swoje indexy w skutek działań innych niż dodawanie/usuwanie elementów
  3. jedna lista w tą czy w tamtą przy setkach komponentów to najmniejszy problem
  4. przy własnej liście (a nawet kilku) wiesz dokładnie gdzie co masz
0

Masz duzo racji i coraz bardziej sie przekonuje do wlasnej listy (a nawet kilku).

Czy moglbys rozwinac punkt 1:

  1. co sam stworzyłem sam niszczę - czyli zawsze create(nil), żeby mi nic nie zrobiło Destroy na obiekcie

rozumiem ze zamiast destroy robisz create(nil) - wytlumaczysz po co tak?

0

jeśli tworzysz np. przycisk tak

btn = TButton.Create(form1);

to jak zamkniesz form1 to ona wtedy sprawdza swoje "dzieci" j je niszczy, czyli niejako automagicznie wywoła się btn.Destroy; (albo Free - nie pamiętam ale raczej free)
Jeśli teraz ja też będę chciał, jak przystało na grzecznego programistę, posprzątać po sobie i dam btn.Free to dostanę AV bo btn już nie istnieje bo zwolniła go zamykana forma.

Dlatego mam zasadę, że dla tworzonych dynamicznie komponentów nie przypisuje właściciela i sam je niszczę

0
Misiekd napisał(a)

dam btn.Free to dostanę AV bo btn już nie istnieje bo zwolniła go zamykana forma

Nie do końca. Metoda Free testuje, czy obiekt jest różny od nil i tylko wtedy wywoła destruktor:

if Self <> nil then
  Self.Destroy;
0

Co do kilku list na wlasne komponenty...
Chyba niewiele zyskam tworzac wlasna liste skoro i tak nie uzywam zmiennych
wiec za kazdym razem bede musial wyszukiwac w jakis sposob interesujacy mnie komponent...
a Components ma metode FindComponent() ktora zwraca komponent o podanej nazwie.

no i pytanie kolejne sie pojawilo
Czy moge zrobic tak:

var CurCmd: TRSCommand;
for i := 0 to X do begin
  CurCmd := TRSCommand.create(Form1);
  CurCmd.name := 'Komenda'+IntToStr(i);
end;

chodzi mi o to czy kolejne tworzone komponenty nie beda sie gryzly ze soba w jednej zmiennej...

0
brodny napisał(a)
Misiekd napisał(a)

dam btn.Free to dostanę AV bo btn już nie istnieje bo zwolniła go zamykana forma

Nie do końca. Metoda Free testuje, czy obiekt jest różny od nil i tylko wtedy wywoła destruktor:

if Self <> nil then
  Self.Destroy;

tylko zauważ, że jak wywołasz coś.Free to wcale coś nie równa się nil :P. Żeby to działało to po Self.Destroy powinno jeszcze być Self := nil;

0

Możesz.

0

a ja lubie przechowywać wszystko w dynamicznej tablicy...:

var
panels: array of Tpanel;
liczba:integer;

oczywiście musisz potem ustawić na początku
liczba:=0;

tworzenie panela:

inc(liczba)
SetLength(panels,liczba);
panels[i] := Tpanel.Create( Form1 );
panels[i].jakiestamwlasciwosci:=...;
0

Z tymi komponentami to nie jest warunek if Assigned(cokolwiek) then ? Nie zmienia to jednak, że sposób MiskaD jest o tyle bezpieczny bo pewny.

0

aSSIGNED SPRAWDZA CZY COS <> nill

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