Twoje pytanie nie jest zbyt użyteczne, ponieważ - ogólnie rzecz biorąc - jest zniechęcane do przechowywać danych (lub obiektów w Twoim przypadku) w kontroli GUI. Zobacz także komentarz Davida, jak zmienić swój projekt.
To, co sprawia, że pytanie ma charakter interakcyjny, to jednak różnica między kombinacją, która jest dzieckiem formy bezpośrednio i jest dzieckiem innego dziecka w formularzu (w tym przypadku ramka). Wygląda na to, że elementy pola kombi są zniszczone przed wywołaniem destruktora tej klatki. Oczywistymi alternatywami do odkrycia są: przesłonięcie Frame.BeforeDestruction
, przesłanie Frame.DestroyWindowHandle
, przesłanie , lub przechwycenie WM_DESTROY
w nadpisanym Frame.WndProc
, ale żaden z nich nie jest wywoływany, zanim elementy już nie istnieją.
Następną rzeczą, którą należy wypróbować, jest powtórzenie tego dla pola kombi. Okazuje się, że kiedy WM_DESTROY
przybywa do pola kombi, że przedmioty nadal tam są. Należy jednak uważać na przechwytywanie tej wiadomości, gdy kontrolka naprawdę jest niszczona, ponieważ VCL może często odtwarzać pole kombi. Wdrożyć go przy użyciu wstawienie klasę dla TComboBox
, co następuje:
unit Unit2;
interface
uses
Windows, Messages, Classes, Controls, Forms, StdCtrls;
type
TComboBox = class(StdCtrls.TComboBox)
protected
procedure WndProc(var Message: TMessage); override;
end;
TFrame1 = class(TFrame)
ComboBox1: TComboBox;
end;
implementation
{$R *.dfm}
{ TComboBox }
procedure TComboBox.WndProc(var Message: TMessage);
var
I: Integer;
begin
if (Message.Msg = WM_DESTROY) and (csDestroying in ComponentState) then
for I := 0 to Items.Count - 1 do
Items.Objects[I].Free;
inherited WndProc(Message);
end;
end.
Teraz, aby odpowiedzieć na pytanie: „Czy to jest lepszy sposób?”
Tak, ponieważ zapewnia zapewnienie zniszczenia obiektu na poziomie klatki. Innymi słowy: nie musisz zapamiętaj, aby poradzić sobie z tym dla każdej instancji oddzielnie.
I nie, nie jest, ponieważ to rozwiązanie wymaga, aby obiekty w polu kombi mogły zostać zwolnione w dowolnych okolicznościach, które ograniczają użycie do niepotrzebnej dodatkowej granicy.
Czy ta odpowiedź jest przydatna? Cóż, jeśli przeszkadza ci to w używaniu obecnego podejścia, to tak właśnie jest.
Poza tym, ja również znaleźć inną alternatywę poprzez ustawienie ramy za Parent
własności do zera w zawierającego postaci OnDestroy
Handler:
procedure TForm2.FormDestroy(Sender: TObject);
begin
Frame1.Parent := nil;
end;
W tym przypadku można bezpiecznie zniszczyć obiektów przechowywanych w kombi pudełko wewnątrz destruktora ramki. Ale to rozwiązanie jest nawet gorsze od obecnego, ponieważ nie jest opisowe. Wtedy Frame1.FreeComboObjects
jest znacznie lepszy.
Moja rada to zmienić projekt. Nie ma pola kombi będącego właścicielem tych obiektów. Niech ramka będzie je zawierała w dowolnym kontenerze, np. 'TObjectList'. Następnie możesz zniszczyć ten kontener w destruktorze ramki. –