![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
заNILить форму после Close;
ничтожная козявка © (2008-08-21 12:37:00)
Страницы: < 1 2 3 4 5 6 7 8 9 10 >
В некой dll есть функция, показывающая форму. Перед созданием формы, она проверяет ее на NIL:
if not Assigned(Form1) then Form1 := TForm1.Create(AOwner);
также требуется, что бы после закрытия (Close) форма была уничтожена:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
...
Action := caFree;
...
end;
ВОПРОС: как сделать так, чтоб она была не только уничтожена, но и переменная Form1 приняла значение NIL. Т.к. поскольку эта переменная не NIL, при повторной попытке создать форму, ее конструктор
if not Assigned(Form1) then Form1 := TForm1.Create(AOwner);
не вызывается, и в последствии сыпятся AV.
Юрий Зотов (2008-08-22 17:30:00) [101]> @!!ex © (22.08.08 17:20) [86]
Я, конечно, плохо понимаю указатели. Еще хуже - указатели на указатели. О чем было сказано еще в самом первом моем посте [8].
LOL.
Вы все равно используете все ту же самую глобальную переменную. Так и используйте ее ЯВНО, зачем извращаться?
И что мы тогда получим? Все тот же код в [8], но без чесания правого уха левой рукой.
@!!ex (2008-08-22 17:26:00) [102]Кстати, Юрий, я дал ссылку на код. Попробуйте там просто выбросить весь код относящийся к FormLinkPointer и удивитесь...
Блин, я в шоке.
@!!ex (2008-08-22 17:23:00) [103]> [85] {RASkov} © (22.08.08 17:16)
Да не.
Если бы я не был уверен в своей правоте, то с ЮЗ спорсить бы никогда не стал.
Просто в данном случае ЮЗ видимо устал в конце недели и плохо понимает код.
@!!ex (2008-08-22 17:20:00) [104]> 1. В [75] для проверки существования формы Вы никаким образом
> не задействовали ни поле FormLinkPointer, ни относящийся
> к нему код. Если поле FormLinkPointer и относящийся к нему
> код, просто выбросить то ничего не изменится. А раз это
> поле и ВЕСЬ сопряженный с ним код нигде не используются,
> тогда зачем они вообще нужны? Низачем.
Юрий, вы меня нафиг поражаете. Вы в курсе, что такое указатель на указатель??
Вот именно такой и используется.
Меня FornLinkPOinter^ мы меняем Form2 в примере. Можете в дебагере проверить.
Честное слово, я не ожидал что вы так плохо понимаете указатели...
{RASkov} (2008-08-22 17:16:00) [105]Всё, @!!ex "влип" :)
Юрий Зотов (2008-08-22 17:09:00) [106]> @!!ex © (22.08.08 16:01) [75]
Зачем мухлевать? Некрасиво. Все прекрасно видят, что код в [75] по сравнению с кодом в [1] не "немного измененный", а измененный В ПРИНЦИПЕ. И вот почему.
1. В [75] для проверки существования формы Вы никаким образом не задействовали ни поле FormLinkPointer, ни относящийся к нему код. Если поле FormLinkPointer и относящийся к нему код, просто выбросить то ничего не изменится. А раз это поле и ВЕСЬ сопряженный с ним код нигде не используются, тогда зачем они вообще нужны? Низачем.
2. Для проверки существования формы Вы использовали все ту же самую тривиальную глобальную переменную, которую предлагали и другие, но против использования которой Вы столь активно возражали ("Мы все таки с использованием ООП пишем, или только вид делаем?").
3. Таким образом, от кода [1] Вы попросту отказались (что и понятно, поскольку код в [1] действительно ничего не дает и поэтому совершенно не нужен) и заменили его другим кодом. Что и означает - "изменили в принципе".
4. Но даже и тут Вы все равно ошиблись. Поскольку даже самую элементарную проверку - и ту умудрились сделать неверно. После закрытия формы она будет уничтожена, а Ваша проверка покажет, что она существует.
5. Попытки хоть как-нибудь выкрутиться не прокатят. Не стоило и пробовать.
============================================
Для того, чтобы существование формы можно было вообще хоть как-нибудь проверить, нужно при ее создании какой-то флажок взвести, а при уничтожении этот флажок сбросить. Таким флажком может служить, вообще говоря, любая и хранящаяся где угодно переменная, но ОДНО недопустимо - эта переменная НЕ ИМЕЕТ ПРАВА БЫТЬ ПОЛЕМ ТОЙ ЖЕ ФОРМЫ. Иначе при уничтожении формы она исчезнет, а вместе с ней исчезнет и та информация, которая нужна для следующей проверки.
А в [1] как раз ПОЛЕ ФОРМЫ и введено (причем еще и введено кривовато, ну да ладно, не в том суть). Вот почему код в [1] для проверки существования формы не дает (И НЕ МОЖЕТ ДАТЬ!) абсолютно ничего.
Anatoly Podgoretsky (2008-08-22 16:53:00) [107]> @!!ex (22.08.2008 16:50:22) [82]
А о другом тебе ответит ЮЗ
@!!ex (2008-08-22 16:50:00) [108]> [81] Anatoly Podgoretsky © (22.08.08 16:35)
Согласен. Но уже о другом речь.
Anatoly Podgoretsky (2008-08-22 16:35:00) [109]> @!!ex (22.08.2008 16:23:19) [79]
Я же указал единственно правильный и надежный путь.
Зачем же мучаться с глобальными переменными, которые ничего не гарантирую, кроме получения AV
@!!ex (2008-08-22 16:24:00) [110]>>Когда Form1 присваиваЮт какое то некорректное значение - можно?
@!!ex (2008-08-22 16:23:00) [111]> [78] Anatoly Podgoretsky © (22.08.08 16:22)
Так это применимо и к коду ЮЗ.
Давайте тогда вообще флаги не использовать? Они же сломатся могут...
реальный пример, когда Form1 ghbcdfbdf.n rfrjt nj ytrjhhtrnyjt pyfxtybt - vj;yj&
Anatoly Podgoretsky (2008-08-22 16:22:00) [112]> @!!ex (22.08.2008 16:01:15) [75]
Я уже писал
Form1 := nil;
Form1 := AnyValue;
@!!ex (2008-08-22 16:17:00) [113]> Добавьте к примеру [1] ЛЮБУЮ такую проверку - и я ДОКАЖУ
> Вам (причем, вполне конкретно, как Вы и хотели), что работать
> она НЕ будет. Потому что никакая проверка, основанная на
> коде [1] работать не может уже в самом ПРИНЦИПЕ этого кода
И ведь работает... У меня в компиляторе ошибка, да?
С нетерпением жду доказательства неработоспособности работающего кода. :))
@!!ex (2008-08-22 16:14:00) [114]Вот тоже самое в коде:
http://www.mediafire.com/?btmj4ydyxgn
@!!ex (2008-08-22 16:01:00) [115]То, что уже было написано в [1] и немного измененный.
TForm1 = class
public
FormLinkPointer:^TForm1;
end;
....
Form1:TForm;
Form1:=TForm.Create();
Form1.FormLinkPointer:=@Form1;
procedure TForm1.FormClose(...);
begin
Action := caFree;
end;
procedure TForm1.OnDestroy(...);
begin
FormLinkPointer^:=nil;
end;
Собственно проверка:
if Form1<>nil then
//Значит существует
else
//Значит не существует
Юрий Зотов (2008-08-22 15:11:00) [116]> @!!ex © (22.08.08 14:15) [63]
Как уже справедливо заметил Анатолий, в примере [1] нет никакой проверки существования формы - то есть, нет никакого решения сабжа вообще.
Добавьте к примеру [1] ЛЮБУЮ такую проверку - и я ДОКАЖУ Вам (причем, вполне конкретно, как Вы и хотели), что работать она НЕ будет. Потому что никакая проверка, основанная на коде [1] работать не может уже в самом ПРИНЦИПЕ этого кода.
Вы хотели конкретики? ОК, я жду ее. И теперь уже от Вас просто так не остану, поверьте. Извините, но сами напросились.
Итак - либо к примеру [1] Вы добавляете конкретный, неопровержимый и работающий код проверки существования формы, либо признаете (явным или неявным образом - неважно), что код в [1] для такой проверки не дает ровно ничего.
После чего сможем перейти к другим "конкретностям" в коде [1]. Они там тоже имеются.
Leonid Troyanovsky (2008-08-22 14:54:00) [117]
> DVM © (22.08.08 14:50) [70]
> А в SysInit сколько глобальных переменнных. Их тоже в классы
> загонять?
Чего их гнать, раз уж они уже случились.
Речь-то шла о собс-ручных переменных.
--
Regards, LVT.
Юрий Зотов (2008-08-22 14:54:00) [118]> Leonid Troyanovsky © (22.08.08 13:49) [56]
> Необходимость первого нуждается в отдельном обосновании.
Необходимость второго и третьего - тоже. Таким обоснованием (причем, железобетонным) может служить, например, ТЗ.
> А, в остальном, изволь: пусть это будет, например,
> web service & client.
Что тоже нуждается в обосновании. Причем, не менее.
PS
Леонид, как известно, многие (если не все) задачи можно решить разными способами. Естественно, выбор того или иного решения ВСЕГДА должен быть обоснован. Проектируя архитектуру (структуру кода и т.п.) будущей программы, конечно, НИКОГДА не следует забывать о необходимости обоснования выбранного решения, но точно так же и НИКОГДА не следует априори отметать то или иное из прочих возможных решений.
PPS
Пресловутые "советы" предназначены для совсем уж начинающих и хороши лишь тем, что позволяют НАЧИНАЮЩИМ уберечься от распространенных ошибок. Но не стоит превращать их в догмы - иначе они станут столь же вредны, сколь и полезны. Программист просто должен понимать, что, как и зачем он делает, чем это хорошо и плохо, какие могут быть подводные камни и как их не допустить - и т.д.
DVM (2008-08-22 14:52:00) [119]
> Ну, и не нужны глобальные переменные.
> Есть нужда - пользуй объекты, со свойствами только для чтения.
>
> Это вопрос проектирования.
> А Application мог бы пригодиться хоть и в консольном приложении.
>
> Это вопрос проектирования.
> А Application мог бы пригодиться хоть и в консольном приложении.
>
Может и мог бы, только зачем усложнять настолько простые вещи? Почему то программисты на Делфи стремятся обернуть элементарное в кучу классов с огромной иерархией и сложными взаимосвязями вместо того чтобы просто написать сотню строчек делающих то же самое, но без лишних сложностей.
Leonid Troyanovsky (2008-08-22 14:50:00) [120]
> DVM © (22.08.08 14:44) [68]
> Но формально, они в разделе var, а не const. Да и нельзя
> присвоить именно константе из раздела const значение уже
> во время выполнения программы.
Ну, и не нужны глобальные переменные.
Есть нужда - пользуй объекты, со свойствами только для чтения.
> Выходит, с одной стороны:
> Но с другой:
Как не крути, переменные отличаются от констант.
--
Regards, LVT.