Autor Téma: Změna rodiče v runtime  (Přečteno 446 krát)

Offline age.new

  • Hrdina
  • ****
  • Příspěvků: 309
  • Karma: 0
Změna rodiče v runtime
« kdy: 14-12-2020, 08:20:44 »
Vážená komunito,

snažím se v runtime změnit rodiče několika komponent, vytvořených v design části. Bohužel mi ukončení aplikace (tj, zničení rodiče hodí chyby ukazatele v paměti).

Vytvořil jsem si u rodiče proceduru ChangeChildren a přepsal ji pomocí override z TControl. Touto procedurou mi tak začali procházet všechny vznikající děti. Pro změnu rodiče jsem použil tento kód:

Kód: Delphi [Vybrat]
  1. procedure TMyF.ChangeChildren;
  2. var
  3.   b: boolean;
  4.   i: integer;
  5. begin
  6.   b := true;
  7.   while b do
  8.   begin
  9.     b := false;
  10.  
  11.     for i := 0 to Self.ChildrenCount - 1 do
  12.       if Self.Children.Items[i] is TControl then
  13.     begin
  14.       Self.Children.Items[i].Parent := FSlidePanel;
  15.  
  16.       b := true;
  17.       break;
  18.     end;
  19.   end;
  20. end;
  21.  

Kód funguje a skutečně výše uvedené děti převzali parametry nového rodiče. Problém ale nastane, když ukončuji aplikaci a dochází k volání Destroy všech objektů. Po zavolání Destroy u nového rodiče se objeví chyby paměti (Invalid Pointer Operation) v části, kde dochází k uvolňování paměti.

Když se podívám na kód ve for cyklu, tak je mi jasné, kde je chyba. To dítě je pořád alokovaný u jednoho rodiče ačkoliv má určeného rodiče nového. Nepřišel jsem ale, jak docílit změny rodiče, tj. přesunu dítěte pod jiného rodiče. Zkoušel jsem toho hodně, ale pouze výše uvedený kód je napůl funkční.

Děkuji za rady.
 
« Poslední změna: 14-12-2020, 08:22:30 od age.new »

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2978
  • Karma: 108
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Změna rodiče v runtime
« Odpověď #1 kdy: 14-12-2020, 08:37:40 »
Excellent
Rated 1 time
není to náhodou tím, že procházíš v cyklu a měníš partnera, a tím se změní i počet Child? Zkus použít downto v cyklu, tj. postupovat od konce.

Jinak je to celé divné, ale ještě poznamenám, že Owner není to samé co Parent a v případě, že Owner <>Parent, tak by se měl Owner uvolnit až po Parent, resp. pokud to nedokážeš zařídit, tak musíš u tech svojich komponent nastavit včas Parent aspon na nil. Nebo si to aspon myslim ...
Embarcadero MVP - Czech republic

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3290
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Změna rodiče v runtime
« Odpověď #2 kdy: 14-12-2020, 09:28:05 »
ale ještě poznamenám, že Owner není to samé co Parent a v případě
Jj, Parent je jen zalezitosti vizualizace, za zivotni cyklus odpovida Owner

Offline age.new

  • Hrdina
  • ****
  • Příspěvků: 309
  • Karma: 0
Re:Změna rodiče v runtime
« Odpověď #3 kdy: 14-12-2020, 10:21:55 »
není to náhodou tím, že procházíš v cyklu a měníš partnera, a tím se změní i počet Child? Zkus použít downto v cyklu, tj. postupovat od konce.

Jinak je to celé divné, ale ještě poznamenám, že Owner není to samé co Parent a v případě, že Owner <>Parent, tak by se měl Owner uvolnit až po Parent, resp. pokud to nedokážeš zařídit, tak musíš u tech svojich komponent nastavit včas Parent aspon na nil. Nebo si to aspon myslim ...

Cyklus je ve while, který řeší změnu. Opravdu docházelo k problému "jen" v postupném uvolňování dětí, tj. přesunutí jedné Free části na jinou pozici v kódu se problém vyřešil. Celou dobu jsem se zaměřoval na problém s nastavením rodiče v jiné části kódu a ono to byla takováto hloupost.

Děkuji.