Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Уничтожение TFrame, Ошибка при уничтожении фрейма 
:(
    Опции темы
DmiSbr
Дата 22.8.2010, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 14.4.2010

Репутация: нет
Всего: нет



Доброго всем дня !
Никак не соображу в чем прикол

Создаю Frame (File -> New Frame)
Показываю его на основной форме

Код

var fr: TFrame2;
begin
  fr:=TFrame2.Create(Form1);
  with fr do begin
    Parent:=Form1;
    Top:=100;
    Left:=100;
    Visible:=true;
  end;


Все замечательно

На фрейv вешаю TButton с обработчиком

Код

procedure TFrame2.Button1Click(Sender: TObject);
begin
  Free;
end;


Опять же все красиво, фрейм разрушается без последствий

Добавляю TSpeedButton с таким же обработчиком, и вуаля - вылетает AV 
" EAccessVialation .... Access Violation at address 00010017.Write of address 00008100"

В интернете по данной теме ничего не нашел.
Может кто прольет свет на данный вопрос ?

Delphi 5, Windows XP SP2
Delphi 5
PM MAIL   Вверх
kami
Дата 22.8.2010, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 22
Всего: 72



Кнопка фрейма ведь  тоже будет уничтожена, а мы в обработчике ее события.
как-то так
PM MAIL WWW   Вверх
DmiSbr
Дата 22.8.2010, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 14.4.2010

Репутация: нет
Всего: нет



Зы
Странно, но ведь для TButton я никакой специальной обработки по уничтожению не пишу, и при этом все нормально

PM MAIL   Вверх
DmiSbr
Дата 22.8.2010, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 14.4.2010

Репутация: нет
Всего: нет



2 kami

Спасибо за ссылку
Теперь все работает замечательно

Обработчик для кнопки

Код

procedure TFrame1.SpeedButton1Click(Sender: TObject);
begin
  PostMessage(Handle, WM_USER, integer(Sender), 0);
end;


Объявляем приемщик сообщения:

Код

TFrame1 = class(TFrame)
....
  private
    procedure DeleteFrame(var Message:TMessage); message WM_USER;


Код

procedure TFrame3.DeleteFrame(var Message:TMessage);
begin
  // Уничтожаем кнопку
  TObject(Message.Wparam).Free;
  // И уже потом уничтожаем фрейм
  Free;
end;



PM MAIL   Вверх
БелАмор
Дата 22.8.2010, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 7
Всего: 17



Цитата(DmiSbr @  22.8.2010,  10:11 Найти цитируемый пост)
Странно, но ведь для TButton я никакой специальной обработки по уничтожению не пишу, и при этом все нормально


Из факта "один раз проскочил" не надо делать вывод "всегда так делать"...
Посмотрите ссылки:
1. http://forum.vingrad.ru/topic-301514.html
(поиск по фразе "Купите красивую рамочку" или "Запрещается уничтожать объекты")
2. http://www.delphikingdom.com/asp/answer.asp?IDAnswer=76938
(моё сообщение и ссылка в нём)
PM   Вверх
БелАмор
Дата 23.8.2010, 01:52 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 7
Всего: 17



Цитата(DmiSbr @  22.8.2010,  10:11 Найти цитируемый пост)
Странно, но ведь для TButton я никакой специальной обработки по уничтожению не пишу, и при этом все нормально

Фраза, которую можно понимать по-разному...
Если интерпретировать её как "я же кнопку не удаляю сам, как же она удалится?", то ответ будет таков:
При своём уничтожении компонент удаляет другие компоненты, для которых он является:
  а) Владельцем (Owner'ом)
  б) Родителем (Parent'ом)
Владелец - это тот, кто ответственен за уничтожение тех, кем он владеет при своём уничтожении. Владелец назначается при вызове конструктора, например: TButton.Create(Self).
Всем компонентам, расположенным на форме или фрейме (независимо от того, непосредственно или на других элементах, например, панелях), Owner'ом назначается именно эта форма или фрейм. Именно поэтому при уничтожении формы всё, что на ней расположено, будет уничтожено автоматически (в том числе невизуальные компоненты вроде датасетов).
Родитель - это тот, на чём лежит контрол визуально, например, панель, на которой лежит кнопка. Панель при своём уничтожении будет также уничтожать кнопку, лежащую на ней.

Цитата(DmiSbr @  22.8.2010,  16:20 Найти цитируемый пост)
procedure TFrame3.DeleteFrame(var Message:TMessage);
begin
  // Уничтожаем кнопку
  TObject(Message.Wparam).Free;
  // И уже потом уничтожаем фрейм
  Free;
end;

Здесь нет необходимости уничтожать кнопку самостоятельно. При своём уничтожении фрейм её уничтожит в любом случае.

И ещё...
Вы не уловили самого главного: зачем вообще нужен финт ушами с сообщением...
А нужен он для того, чтобы уничтожением объекта занимался кто-то, кто не являетя обработчиком ни одного из уничтожаемых объектов и не вызывается из этих обработчиков. Это достигается тем, что в обработчике нажатия кнопки посылается сообщение тому, кто будет заниматься уничтожением, после чего происходит выход из обработчика. И вот только после этого кто-то внешний, кому было послано сообщение, начинает обработку сообщения и уничтожает тех, на кого ему показали. Таким образом, обработчик сообщения не должен быть обработчиком ни для фрейма, ни для кнопки. Сделайте его обработчиком для формы. И передавайте ссылку не на кнопку, а на фрейм.

P.S. Загляните ещё раз по ссылке, приведённой kami - я там добавил комментарий, который вам может быть небезынтересен.

Это сообщение отредактировал(а) БелАмор - 23.8.2010, 02:59
PM   Вверх
DmiSbr
Дата 23.8.2010, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 14.4.2010

Репутация: нет
Всего: нет



2 БелАмор
Большое спасибо за подробное объяснение
Про "ответственных" за уничтожение объектов я знаю. При разрушениии обычной формы уничтожаются все компоненты принадлежащие ей.
В том числе и кнопки, которые вызывают закрытие формы. При этом дополнительных телодвижений вроде как не требуется. Достаточно написать 
Код
procedure TForm2.SpeedButton1Click(Sender: TObject);
begin
  Close;
end;

Такого же мнения я был о фрейме. И често говоря был сильно удивлен, что нужны дополнительные финты.
Цитата
Вы не уловили самого главного: зачем вообще нужен финт ушами с сообщением...
А нужен он для того, чтобы уничтожением объекта занимался кто-то, кто не являетя обработчиком ни одного из уничтожаемых объектов и не вызывается из этих обработчиков....
Сделайте его обработчиком для формы. И передавайте ссылку не на кнопку, а на фрейм.

Просто мне не хотелось загрязнять код главной формы обработкой уничтожения фреймов. Так как будто красивее получилось.
Может я и не прав.
Цитата
P.S. Загляните ещё раз по ссылке, приведённой kami - я там добавил комментарий, который вам может быть небезынтересен.

Ссылка очень полезная. 
Еще раз Огромное спасибо
PM MAIL   Вверх
БелАмор
Дата 24.8.2010, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 7
Всего: 17



Цитата(DmiSbr @  23.8.2010,  21:00 Найти цитируемый пост)
При разрушениии обычной формы уничтожаются все компоненты принадлежащие ей.
В том числе и кнопки, которые вызывают закрытие формы. При этом дополнительных телодвижений вроде как не требуется. Достаточно написать 
procedure TForm2.SpeedButton1Click(Sender: TObject);
begin
  Close;
end;
Такого же мнения я был о фрейме. И често говоря был сильно удивлен, что нужны дополнительные финты.

Close не уничтожает форму, а закрывает, т.е. делает её невидимой. Скрытую форму при желании можно опять показать (и там будут все те же данные, которые были перед закрытием). А уничтожается форма точно так-же, как и всё остальное - через вызов Free.
И в отношении форм точно так-же сохраняется запрет на самоуничтожение из своего обработчика, только у форм есть метод Release, который может вызываться в обработчике и приводит к уничтожению формы не сразу, а после выхода из всех обработчиков. Косвенный способ вызова Release - в обработчике OnClose формы параметру Action, передаваемому по ссылке, присвоить значение caFree.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0491 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.