Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Метод


Страницы:   1 2 3

VetMIg ©   (2002-05-08 14:45:00) 

Почему, когда я уничтожаю форму методом "Free". После 3-го закрытия этой формы программа выдает ошибку?
Пример:
...
Form1.Visible:= False;
Form1.Free;
...


VetMIg   (2002-05-21 14:34:00) [1]

Спасибо друзья... Я вдоволь начитался. Обязательно попробую ваши советы. И еще раз спасибо :-))))))


Tonie   (2002-05-16 12:55:00) [2]

To KSergey © (15.05.02 16:11)

>PostMessage(Handle, CM_RELEASE, 0, 0);

Ну так в этом и смысл, сообщение CM_RELEASE будет помещено после уже имеющихся в очереди, поэтому и TCustomForm.CMRelease произойдет после того как все оставшиеся сообщения будут обработаны

Кстати Close вызывает Release, поэтому использование Close вместе c ... Action := caFree вполне корректно



procedure TCustomForm.Close;
var
CloseAction: TCloseAction;
begin
if fsModal in FFormState then
ModalResult := mrCancel
else
if CloseQuery then
begin
if FormStyle = fsMDIChild then
if biMinimize in BorderIcons then
CloseAction := caMinimize else
CloseAction := caNone
else
CloseAction := caHide;
DoClose(CloseAction);
if CloseAction <> caNone then
if Application.MainForm = Self then Application.Terminate
else if CloseAction = caHide then Hide
else if CloseAction = caMinimize then WindowState := wsMinimized
else
Release;
end;
end;


Fantos   (2002-05-16 11:52:00) [3]

Позволю заметить, что ПРИНЦИПИАЛЬНОЕ различие в использовании FREE или RELEASE я прочувствовал на собственных "граблях". И заключались они (грабли) в следующем:
- программа подключала DLL-ку (динамически, в отдельном потоке) с вызовом формы из нее (не модально!). В этом модуле шла работа с устройствами через COM-порты... Так вот, если в интерфейсной процедуре из DLL-ки (вы понимаете о чем я?) ставилось удаление формы через FREE, то основная программа ПРИ или ПОСЛЕ выполнения FREELIBRERY - частенько И НЕ ЗАКОНОМЕРНО вываливала ошибку AV ! Причина -- банальное ОТСУТСТВИЕ обработчика очереди сообщений...форма то уже УДАЛЕНА!
А вот когда FREE была заменена на RELEASE, вот тогда все стало нормально работать и закрываться...
Вот Вам и разница, как говорится - "на пальцах"...

Поэтому, для "выписки рецепта" необходимо, сначала, "обдумать" всю связку удаляемых форм и основного модуля(или формы, если хотите)...


KSergey   (2002-05-15 16:11:00) [4]

2 Producer
А если много - зачем его увеличиваете?

и опять же тема окаазлась интересной, нек. тонкости выискались, так что погорячились вы, Producer.

К тому же никто не ответил пока: правомочно ли использовать Free в такой конструкции

with TAbout_Form.Create (Self) do
try
ShowModal;
finally
Free;
end;

или это приведет таки к возможным ошибкам?
Хоят вот мне как кажется: ну уничтожил я форму, за ней уничтожилось окно, хендл его пропал для системы (неактуален), но сообщения остались. Ну и что? Они проигнорируются - вот и все. Если послать сообщение с отфонарным хендлом - неужели винды AV выкинут? Как-то я сильно сомневаюсь в том... (а вот проверить лень, признаю)

К слову, не поленился сейчас глянул как реализовано Release: как то не совсем понятно на мой вкус...

// 1. Шлет сама себе CM_RELEASE, причем Post"ом - отсюда и выход из этой процедуры сразу, до собственно разрушения
procedure TCustomForm.Release;
begin
PostMessage(Handle, CM_RELEASE, 0, 0);
end;

// 2.А как там у нас реакция на CM_RELEASE устроена?
procedure TCustomForm.CMRelease;
begin
Free;
end;


О, нифига себе! просто уничтожается объект, причем Free и не взирая на оставшиеся, возможно, сообщения! Так что про сообщения, якобы обрабатываемые Relaese до конца - это выдумка, однако.
Да и само назначение/применение Release становится мне не совсем понятным: типа "разрушься на досуге".

К стати, реакция на caFree - просто вызывается Release - вот и все.

Видимо, применение Relеase (равно как и его назначение) - в возможности формы уничтожать полностью саму себя. Что, впрочем, похоже можно сделать и вызвав в любом месте Free, важно чтобы это был последний оператор в методе. Ну и, возможно, не во всех обработчиках так можно сделать - могут, наверное, и проблемы возникнуть, если в OnCreate прям сразу Free вызвать ;)

Прощу прощения, если кого утомил. Буду рад конструктивной критике, коли чего недопонимаю.


Producer   (2002-05-15 13:47:00) [5]

Не много-ли шума вокруг простого вопросика? Я думаю, что VetMlg отнюдь не с "бронепоезда" и уже давно "в проблеме".


KilkennyCat   (2002-05-15 11:16:00) [6]

Тысяча извинений, с хайд и шоу я переборщил :)
Разумеется, визибле нот визибле.


KilkennyCat   (2002-05-15 11:00:00) [7]

А вот так делаю я:

При вызове какой либо формы из главной:
begin
About := TAbout.Create(self);
try
About.ShowModal;
Main.hide;
finally
About.Free;
Main.Show;
end;
end;

Разумеется, эта форма не должна создаваться в проекте (кинуть ее в секцию Available forms)

Закрытие формы About
modalresult := mrCancel;
Хотя и не обязательно, если в дальнейшем не обрабатывать это.


KSergey   (2002-05-15 10:42:00) [8]

2 Zemal
Чем философски умничать - лучше бы выспался. Полезнее бы оно как-то было для всех - меньше подбирать


KSergey   (2002-05-15 10:42:00) [9]

2 Zemal
Чем филосовски умничать - лучше бы выспался. Полезнее бы оно как-то было для всех - меньше подбирать


Zemal   (2002-05-15 10:20:00) [10]

VetMlg, ну ты дал! Когда код пишешь мысли практично, представляй как будет работать программа, представляй образно объекты и всё будет хорошо. А в твоём случае, после уничтожения формы как будут работать её события если их нет??? Если кнопка в событии которой выполняются инструкции уже разрушена?
И кстати, метод Free во многих случаях работает без помех, если вы сами не посылаете сообщение окну формы какой-нить "нитью", которая страшно подтормаживает из-за низкого приоритета и не проверяя существование формы шлёт ей месаги. Это называется безолаберность. Пишите процедуры и функции так, что бы потом не думать какой метод вызвать Free или Release. :))) Просто соблюдайте правила хорошего тона в программировании - проверяйте (не ленитесь) все VCL компоненты перед обращением к ним, если есть вероятность, что их нет. :)))
И ещё, VetMlg, как ты думаешь? Объект себя "вешает", потом "встаёт из могилы" и "прощается с роднёй"? Если уж форма себя унечтожает, то позаботься о том, чтобы: во-первых, были унечтожены все объекты в классе этой формы (если ты что-то создаёшь сам), дело всё в том, что если ты создаёшь объект в классе формы, то ты его и должен уничтожить, само приложение не будет разрушать такие объекты и они остаются висеть в памяти, а ты уже не можешь ничего с ними поделать, т.к. теряешь указатель на эти объекты, во-вторых, старайся думать так, как "думает" приложение, пока не научишься представлять как оно работает - ничего из тебя не получется (в смысле: программист ты будешь "примерочный" - который ищет примеры где только можно и составляет приложение из этих кусков, немного их подправив, а потом удивляется откуда ошибки и беспомощно разводит руками).
Мой совет: начинайте с основ, т.е. с объектной модели. Не усвоив это не переходите к изучению методов и т.д., потому что это бесполезно. Без понятия философии классов (наследование и т.д.), нечего дальше даже нос совать. Жаль, что мало в каких книгах хорошо это описывают... сразу начинают учить за "21 день"... и начинаются вопросы в форумах, которые показывают совершенное незнание основ (времени жизни объектов, области видимости и т.д.). Печально смотреть на программеров подготовленных за "21 день", которые потом засыпают форумы вопросами типа "знаю как пользоваться ноздрями, а дышать не могу! почему?"... ДА ПОТОМУ! Лезь в учебники!!!
Блин... бардак... извините друзья! Я просто не выспался сегодня! :) Бошка трещит, а триггера не ждут... :)
Извиняюсь, если лабуду написал, что было в голове то и написал :)... даже перечитывать не охото, тем более исправлять :)... типа: версия "как-есть". гы-гы.
:)))


Alex M.A.   (2002-05-15 09:54:00) [11]

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

procedure TForm1.AboutMenuClick(Sender: TObject);
begin
AboutBox:=TAboutBox.Create(Application);
AboutBox.ShowModal;
end;

procedure TAboutBox.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;


caFree - The form is closed and all allocated memory for the form is freed.


leshy   (2002-05-15 09:49:00) [12]

А почему в TAbout_Form.OnCloseнельзя просто поставить Action := caFree, и не задумываться больше над этим. Туда же можно вставить About_Form := nil, чтобы не делать этого где то ещё. Туда же, кстати, можно и Main_Form.Show, вместо Visibleи SetFocus.
Хотя, если быть до конца корректным, обнуление переменной формы лучше делать в BeforeDestruction.
Соответственно, закрытие формы производить простым Close.


KSergey   (2002-05-15 09:44:00) [13]

2 koks

А если модальная - то что? Какая разница?


KSergey   (2002-05-15 09:42:00) [14]

Скобочка одна выпала:

procedure TAbout_Form.FormClose(Sender: TObject; var Action: TCloseAction);


koks   (2002-05-15 09:41:00) [15]

procedure TAbout_Form.Image3Click(Sender: TObject);
begin
PlaySound("sound\menu_back.wav", 0, Snd_FileName);
Close;
Main_Form.Visible:= True;
Main_Form.SetFocus;
end;

procedure TAbout_Form.About_FormOnClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;

Это если у тебя About_Form - не модальная...

Да, кстати, интересно было бы найти, при установки Action := caFree форма РЕАЛЬНО удаляется методом Free или Realease...


KSergey   (2002-05-15 09:40:00) [16]

Все что вам отвечено - абсолютно верно (как будто кто-то в том сомневался ;)
Я бы посоветовал сделать так:

procedure TAbout_Form.Image3Click(Sender: TObject);
begin
PlaySound("sound\menu_back.wav", 0, Snd_FileName);
Close;
// а вот цель след. вдух строк не ясна:
// а что, MainForm была скрыта в момент показа About?
// А зачем?! Ну впрочем есть надо - можно и оставить эти строки
// Main_Form.Visible:= True;
// Main_Form.SetFocus;
end;

// и обязательно далее: облаботчик OnClose формы About:

procedure TAbout_Form.FormCloseSender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;


В моем понятии все это очень корректно сработает. Или есть возражения?

Хотя вообще-то я бы вообще все это сделал не так. Где-то же, как я понимаю, форма About создается? Вот в этом месте я бы сделал так (предположим, что это нажатие на кнопку в главной форме):

// внимание: здесь не присваивается значение переменной About_Form
// А оно вообще-то надо?! Обычно и без этого можно обойтись
with TAbout_Form.Create (Self) do
try
ShowModal;
finally
Free;
end;


Тогда и обработчик клика на картинке преобразуется в

procedure TAbout_Form.Image3Click(Sender: TObject);
begin
PlaySound("sound\menu_back.wav", 0, Snd_FileName);
Close;
// ну если очень надо - можно раскомментировать две след. строчки
// Main_Form.Visible:= True;
// Main_Form.SetFocus;
end;


Вот и все!
К стати, в приведенной конструции, которую я везде использую, так же никогда не пользовал Release. Пока везло.. Возможно, этому есть объяснение, но я его не знаю. Может кто-либо просветит? (т.к. вроде как аргументы в пользу Release выглядят вполне разумными, но может именно в такой конструкции это принципиально уже не важно, т.к. все сообщения уже проехали в момент ShowModal?)


Мальфет   (2002-05-15 08:54:00) [17]

VetMIg, извини, но над стилем тебе надо поработать...

По сабжу: Абсолютно неправомощно использовать процедуры освобождения объекта из самого объекта.


Alx2   (2002-05-15 08:07:00) [18]

Free из самого себя - не выход. Release?


Slym   (2002-05-15 06:51:00) [19]

Гасишь форму, а в его методе продолжаешь -
Main_Form.Visible:= True;
Main_Form.SetFocus;
попробуй фри вставить в конец :)


Fay   (2002-05-15 02:20:00) [20]

Круто !!!


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо