Самоуничтожение визуального компонента

Ситуация:динамически создаются кнопки
  job_button_delete:= TButton.Create(Application);  with job_button_delete do  begin    Parent:= job; // job - это фрейм    Left:= 552;    Top:= 39*job_count+8;    Width:= 75;    Height:= 25;    Tag:= job_count;    Caption:= 'Удалить';    onclick:= del_job;  end;
и обработчик onclick
procedure TForm1.del_job(Sender: TObject);begin(Sender as TButton).Destroy;end;
при нажатии на кнопку она удаляется, но вместе с этим выдается ошибка обращения к памяти. Как я понимаю нельзя удалять объект из собственного же метода. Может быть есть какой-нибудь ещё способ?Заранее спасибо.
13 ответов

FreeAndNil?


FreeAndNil?
всмысле (Sender as TButton).Free?если да, то пробовал, тоже самое :(


PosiTive
всмысле (Sender as TButton).Free?
нетДобавлено через 56 секундЧто в справке написано по FreeAndNil?Добавлено через 4 минуты и 40 секундЛадно, если не можешь додумать, то вот:
FreeAndNil(job_button_delete);


PosiTive
Цитата(PosiTive @  29.3.2009,  15:03 )
всмысле (Sender as TButton).Free?
нетДобавлено @ 15:07Что в справке написано по FreeAndNil?Добавлено @ 15:10Ладно, если не можешь додумать, то вот:
FreeAndNil(job_button_delete);
таже самая ошибка памяти. на всякий случай кусок кода:
procedure TForm1.del_job(Sender: TObject);beginfreeandnil(Sender);end;


на всякий случай кусок кода:
ты видишь мой кусок кода или нет?? ГДЕ ТАМ SENDER?


Как я понимаю нельзя удалять объект из собственного же метода.
Правильно, нельзя.После вызова события OnClick в процедуре TWinControl.DoKeyPress еще идет обращение к полям экземпляра класса, хотя самого экземпляра уже не существует. Отсюда AV.Нужно реализовать "замедленное" удаление, например - через механизм сообщений Windows.


 job_button_delete:= TButton.Create(сюда запихай форму, к которой принадлежит кнопка);
job_button_delete:= TButton.Create(Application);  with job_button_delete do  begin    Parent:= job; // job - это фрейм    Left:= 552;    Top:= 39*job_count+8;    Width:= 75;    Height:= 25;    Tag:= job_count;    Caption:= 'Удалить';    onclick:= del_job;  end;
а где owner?


Поясняю.Мы - в обработчике события OnClick той кнопки, которую нужно уничтожить.Само собой, что уничтожить ее напрямую нет возможности (а соблазн так велик  ).Тогда делаем следующий финт ушами:
procedure TForm1.del_job(Sender: TObject);begin  PostMessage(Handle, WM_USER, integer(Sender), 0); // Именно Postmessageend;Объявляем приемщик сообщения:TForm1=class(.....)private  procedure MyButtonDelete(var Message:TMessage); message WM_USER;....end;procedure TForm1.MyButtonDelete(var Message:TMessage);begin  TObject(Message.Wparam).Free;end;
а где owner?
Какой Owner, какой Sender?У человека создается КУЧА кнопок динамически. Переменная job_button_delete теряет смысл сразу после выхода из процедуры создания, да и можно вполне обойтись и без нее.


Поясняю.Мы - в обработчике события OnClick той кнопки, которую нужно уничтожить.Само собой, что уничтожить ее напрямую нет возможности (а соблазн так велик  ).Тогда делаем следующий финт ушами:
procedure TForm1.del_job(Sender: TObject);begin  PostMessage(Handle, WM_USER, integer(Sender), 0); // Именно Postmessageend;Объявляем приемщик сообщения:TForm1=class(.....)private  procedure MyButtonDelete(var Message:TMessage); message WM_USER;....end;procedure TForm1.MyButtonDelete(var Message:TMessage);begin  TObject(Message.Wparam).Free;end;
Цитата(Akella @  29.3.2009,  15:19 )
а где owner?
Какой Owner, какой Sender?У человека создается КУЧА кнопок динамически. Переменная job_button_delete теряет смысл сразу после выхода из процедуры создания, да и можно вполне обойтись и без нее.
Большое спасибо за совет. У вас кошелек на Яндекс.Деньгах есть?


Какой Owner, какой Sender?У человека создается КУЧА кнопок динамически.
ну owner ведь должен быть у кнопки


Мы - в обработчике события OnClick той кнопки, которую нужно уничтожить.
  я стормозил


ну owner ведь должен быть у кнопки 
Ну дык а это кто:
job_button_delete:= TButton.Create(Application);
Хотя можно указать и Nil, если сам убивать собираешься. Вообще kami все правильно говорит. Этот метод кстати описан в книге Антона Григорьева.


Как я понимаю нельзя удалять объект из собственного же метода
Нельзя уничтожать объект не "из собственного метода", а "из собственного обработчика". Это две большие разницы."Собственный метод" - это метод, объявленный в этом классе, а "собственный обработчик" - это любой (подходящий) метод любого класса (объекта которого может даже не существовать), ссылка на который хранится в свойстве OnЧтоТоТам своего объекта. Причём в большинстве случаев обработчик является не своим методом, например:  TForm1.Button1Click - это обработсик OnClick кнопки Button1, но является методом формы Form1.Ещё пример "большой разницы":  Form2.Free;Здесь Free - "свой метод", и в нём вызывается деструктор, но он не "свой обработчик"...