powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как очистить компонент от компонентов.
15 сообщений из 15, страница 1 из 1
Как очистить компонент от компонентов.
    #39783266
FIL23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрых суток,

Создаю динамически компоненты.

Владелец, а так же родитель компонентов является тот компонент в котором был создан компонент.

Т.е. получается дерево что ли.

А теперь вопрос как грамматно удалить компоненты?
Делаю так. Передаю Родительскую компоненту на которой находятся все компоненты которые подлежат уничтожению. И по очереди их зануляю.



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
procedure ClearFormByObjects(perForm:TComponent);
var
i:integer;
perObject:TObject;
begin
for i:=perForm.ComponentCount-1 downto 0 do
  begin
  perObject:=perForm.Components[i];
  FreeAndNil(perObject);
  end ;
end;



Но вот беда при создании эти же компонент возникает исключение (а иногда нет. как звезды сойдутся).
Код: pascal
1.
Project alladmin.exe raised exception class EAccessViolation with message 'Access violation at address 004037D6 in module 'alladmin.exe'. Read of address F685D88B'. Process stopped. Use Step or Run to continue.
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783282
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторА теперь вопрос как грамматно удалить компоненты?
Самому удалять ничего не нужно. Удаление - забота владельца.
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783298
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonавторА теперь вопрос как грамматно удалить компоненты?
Самому удалять ничего не нужно. Удаление - забота владельца.Ну, он же хочет вручную, не удаляя владельца.
Только не удаляет, а сразу освобождает. А надо сначала удалить из списка (Delete или Remove), а потом только можно освобождать, иначе будет каша.
Если не ошибаюсь)
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783309
ain-2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
procedure ClearFormByObjects(perForm:TComponent);
var
i:integer;
perObject:TObject;
begin
for i:=perForm.ComponentCount-1 downto 0 do
  begin
  perObject:=perForm.Components[i];
  FreeAndNil(perObject);
  end ;
end;




Код: pascal
1.
2.
3.
4.
5.
6.
procedure ClearFormByObjects(perForm: TControl);
var i:integer;
begin
  for i:=perForm.ControlCount-1 downto 0 do 
    perForm.Controls[i].Free;
end;
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783437
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23,

если я правильно понял вопрос, то некий объект решает, что ему пора быть уничтоженным? Верно?

Я бы сделал так: через PostMessage (а не SendMessage, это важно) отправил бы родительскому объекту сигнал, что меня дочернего объекта пора уничтожить. Таким образом через PostMessage разрывается CallStack и объект возможно будет кошерно удалить.

Техническая деталь: например, в WParam запихав integer(Self), передадим указатель
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783454
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён,

Только не родителю, а владельцу
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783462
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
const
   WM_DEL_CHILD_OBJ  = WM_USER + 1;

   
type
   TParentComponent = class(...)
   private
      procedure WMDelChildObj(var Message: TMessage); message WM_DEL_CHILD_OBJ;
   
   end;
   

procedure TParentComponent.WMDelChildObj(var Message: TMessage);
var
   Obj : TObject;
begin
   Obj := TObject(Message.WParam);

   ...
   FreeAndNil(Obj);   
end;  
//------------------------------------------------------------------------------



...
...
procedure TChildComponent.Remove();
begin
   PostMessage(FOwner.Handle, WM_DEL_CHILD_OBJ, integer(Self), 0);
end;
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783465
L_argo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ain-2,
Free может быть недостаточно. Еще нужно занулить.
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783474
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockТолько не удаляет, а сразу освобождает. А надо сначала удалить из списка (Delete или Remove), а потом только можно освобождать, иначе будет каша.

нет, если "владелец" - в смысле стандартного механизма TComponent.Owner - то они автоматически обмениваются Notification при удалении

FIL23,


FIL23
Код: pascal
1.
2.
  perObject:=perForm.Components[i];
  FreeAndNil(perObject);



Мрак. Зачем так сложно?
Код: pascal
1.
  perForm.Components[i].Destroy;


или
Код: pascal
1.
  perForm.Components[i].Free;



Но вообще, компонент-владелец сам удаляет своих детей при смерти.
Посмотри исходники TComponent в районе удаления.
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783486
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
L_argoain-2,
Free может быть недостаточно. Еще нужно занулить.

Занулить локальную переменную? Которая уже в следующем шаге того же самого цикла будет перезаписана?

ЗАЧЕМ ???
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783488
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик СемёнЯ бы сделал так: через PostMessage (а не SendMessage, это важно) отправил бы родительскому объекту

а если у родительского объекта нет GDI Handle ? вот вообще нет, как у TLabel ? Или в принипе может быть, но пока не создан ?

Кроик Семёнчто меня дочернего объекта пора уничтожить.

А если дочерний объект уже в процессе удаления, уже в деструкторе или рядышком ?
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783492
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockНу, он же хочет вручную, не удаляя владельца.

Внезапно, страшноужасное:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
destructor TComponent.Destroy;
begin
  Destroying;
  RemoveFreeNotifications;
  DestroyComponents;
  if FOwner <> nil then FOwner.RemoveComponent(Self);
  FObservers.Free;
  inherited Destroy;
end;



...но можно и руками
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783581
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23,

Если ты устраиваешь удаление вручную, беспокоясь, что они повиснут мусором потом, когда всё кончится, то зря, поскольку родитель, перед тем, как сдохнуть, убьет всех своих потомков. Если же есть другие причины, чтобы удалять их, то код корректный, ищи ошибку в другом месте.

И не надо путать их с контролами, это совсем другая история, ибо контрол, лежащий на TWinControl, может ему и не принадлежать. Положенный куда-нибудь Control будет удален при удалении своего потомка, а не объекта своего размещения. Можно, например, кидать на форму другую форму со всем её набранным в дизайнере функционалом и набором своих контролов. И вот если родителем этой формы будет наша парент-форма или её контрол, то можно не париться с её удалением, а если родителем формы является nil или Application, то удалить надо вручную.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure TForm6.Button1Click(Sender: TObject);
var i :integer;
begin
  for i := 1 to 1000 do  TLabel.Create(Button1);
  showmessage(inttostr(Button1.ComponentCount));
  showmessage(inttostr(Button1.ControlCount));

  //for i := Button1.ComponentCount-1 downto 0 do Button1.components[i].free;
  //while Button1.ComponentCount>0 do Button1.Components[0].free;
  With Button1 do while ComponentCount>0 do Components[ComponentCount-1].free;
  showmessage(inttostr(Button1.ComponentCount));
  showmessage(inttostr(Button1.ControlCount));
end;


:))
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783611
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.Borzov,

ЕМНИП не так.

Поскольку TWinControl завязаны на GDI-объекты, то при удалении VCL-Parent'a (который в терминах GDI и окажется владельцем) они удалятся тоже.

Т.е. кто первый удаляется - Owner или Parent - тот Control и убьёт.
...
Рейтинг: 0 / 0
Как очистить компонент от компонентов.
    #39783631
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,
Блин, верно. Второй абзац у меня - полный бред.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как очистить компонент от компонентов.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]