![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Игра с формами
Kostafey © (2007-04-24 17:19:00)Уважаемые Мастера!
Помогите пожалуйста разрешить следующую проблему.
Повторить ее очень просто.
Создается Form1, Form2, Form3.
На Form1размещаются 2 кнопки (вызывающие Form2 -модально и Form3):
procedure TForm1.ButtonForm2ModalCallClick(Sender: TObject);
begin
Form2.ShowModal;
end;
procedure TForm1.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Show;
end;
На Form2размещается 1 кнопка (вызывающая Form3):
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Show;
end;
На Form3размещается например Memo
Запускаем.
Жмем на кнопку, вызывающую модально Form2, Затем на Form2 нажимаем кнопку, вызывающую Form3.
Memo, находящееся на Form3 будет работать исправно.
Теперь другая ситуация.
Перезапускаем приложение.
Жмем в Form1 на кнопку, вызывающую Form3 (ее содержимое работеает исправно),
затем на Form1 нажимаем кнопку, вызывающую модально Form2. А в Form2
Вызываем уже открытую Form3. Все! Содержимое Form3, например, Memo работать не будет.
Не будут работать и другие визуальные компоненты формы.
Описанная ситуация точно копирует, ту сложность что возникла у меня.
Притом, даже если предварительно программно закрыть Form3:
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Close;
Form3.Show;
end;
Ничего не изменится.
Сделать так:
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
if Form3.Active then Form3.BringToFront
else Form3.Show;
end;
Тоже бесполезно.
Как же заставить Form3, уже открытую до этого, адекватно работать
при вызове ее из модальной формы?
{RASkov} (2007-04-24 20:37:00) [21][37] Это как раз про использование глобальных переменных....
{RASkov} (2007-04-24 20:36:00) [22]> Kostafey ©
Проделай такой эксперемент и сделай выводы. Для простоты примера обе формы в AutoCreate.
В Form2
procedure TForm2.Button1Click(Sender: TObject);
begin
Form2:=TForm2.Create(Self);
Form2.Caption:='F1'; Form2.Left:=Random(Screen.Width-Width);
Form2.Show;
Form2:=TForm2.Create(Self);
Form2.Caption:='F2'; Form2.Left:=Random(Screen.Width-Width);
Form2.Show;
Form2:=TForm3.Create(Self);
Form2.Caption:='F3'; Form2.Left:=Random(Screen.Width-Width);
Form2.Show;
FreeAndNil(Form2);
end;
В Form1
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
// if Assigned(Form2) then FreeAndNil(Form2);
// with TForm2.Create(nil) do Show;
end;
Button1 на формах нажимай более одного раза.
Затем расскомментируй втрорую и третью строку и закомментируй первую... попробуй еще раз. Обращай внимание на все и поймешь разницу.
Leonid Troyanovsky (2007-04-24 20:19:00) [23]
> Kostafey © (24.04.07 19:57) [29]
> локальными переменными главной формы.
В быту называемыми полями (формы).
Можно даже и вовсе без переменных обойтись, бо
храняться все ссылки на формы в Screen.Forms.
Ну, а основное отличие немодальных от модальных форм
в том, что неизвестен момент, когда их закроют
(т.е., когда их, собс-но, следует разрушить).
Хотя (hint), как разрушать понятно - Action := caFree
--
Regards, LVT.
Kostafey (2007-04-24 20:16:00) [24]> Когда что-то хромает, возникает потребность в костыле.
А когда кто-то летает ему и костыли ни к чему. Понял.
Спасибо за Ваши разъяснения !
Leonid Troyanovsky (2007-04-24 20:11:00) [25]
> Kostafey © (24.04.07 20:00) [31]
> Простите, это > [14] {RASkov} Вы назвали костылем ?
Когда что-то хромает, возникает потребность в костыле.
--
Regards, LVT.
Kostafey (2007-04-24 20:05:00) [26]> Аналогия только в одном - без использования глобальных переменных.
Да, понимаю. Но завтра в обед мне уже готовый вариант надо показывать.
Глобально что перестраивать сейчас что-то уже поздновато, вот я и пытаюсь
вникнуть лучше, чтобы в следующем проекте уже более грамотно делать.
> Или ты не хочешь делать домашнее задание? :)
Ну как вы такое могли подумать?! Я товарищь на такие вещи ответственный ! :)
Leonid Troyanovsky (2007-04-24 20:04:00) [27]
> Kostafey © (24.04.07 19:50) [26]
> Имеется в виду Application.CreateForm(TForm3, Form3); в
> основном файле проекта?
Вобщем-то - да. Но, лезть в dpr руками не обязательно, достаточно
Project - Options - Forms: Auto-create -> Available
--
Regards, LVT.
Kostafey (2007-04-24 20:00:00) [28]> [28] Leonid Troyanovsky © (24.04.07 19:55)
Простите, это > [14] {RASkov}Вы назвали костылем ?
Leonid Troyanovsky (2007-04-24 19:58:00) [29]
> Kostafey © (24.04.07 19:52) [27]
> Вы что же хотите сказать, что аналогично нужно и немодальные
> окна run-time создавать?
Аналогия только в одном - без использования глобальных переменных.
Или ты не хочешь делать домашнее задание? :)
--
Regards, LVT.
Kostafey (2007-04-24 19:57:00) [30]> Мы хотели лишь сказать, что использовать глобальные
> переменные типа Form1..N не следует ни для каких форм.
Ясно. В этом случае, немодальные формы могли бы стать, например,
локальными переменными главной формы.
Д.З. понял.
Leonid Troyanovsky (2007-04-24 19:55:00) [31]
> {RASkov} © (24.04.07 19:29) [23]
> Поэтому и привел в том виде как было сначала.
Каюсь, начало пропустил :(
Но, твой костыль не спасет уважаемого Kostafey.
Если же он прислушается к другим твоим более, IMHO,
полезным советам, то сможет ходить без костылей.
--
Regards, LVT.
Kostafey (2007-04-24 19:52:00) [32]> Только из AutoCreate убери(если еще не сделал этого) TFormX.
Имеется в виду Application.CreateForm(TForm3, Form3); в основном файле проекта?
> Ну, если ты так быстро схватываешь,
> немодальные оставлю в качестве домашнего задания.
Вы что же хотите сказать, что аналогично нужно и немодальные окна run-time создавать?
Извините, если посчитаете вопросы слишком глупыми. Раздел форума так и называется, да и
определение LMD я разобрал.
Kostafey (2007-04-24 19:50:00) [33]> Только из AutoCreate убери(если еще не сделал этого) TFormX.
Имеется в виду Application.CreateForm(TForm3, Form3); в основном файле проекта?
> Ну, если ты так быстро схватываешь,
> немодальные оставлю в качестве домашнего задания.
Вы что же хотите сказать, что аналогично нужно и немодальные окна run-time создавать?
Извините, если посчитаете вопросы слишком глупыми. Раздел форума так и называется, да и
определение LMD я разобрал.
Leonid Troyanovsky (2007-04-24 19:42:00) [34]
> Kostafey © (24.04.07 19:35) [24]
> То есть Вы хотите сказать, что работать с модальными окнами
> через их имена не рекомендуется ?
Мы хотели лишь сказать, что использовать глобальные
переменные типа Form1..N не следует ни для каких форм.
--
Regards, LVT.
Kostafey (2007-04-24 19:35:00) [35]То есть Вы хотите сказать, что работать с модальными окнами через их имена не рекомендуется ?
{RASkov} (2007-04-24 19:29:00) [36]> [22] Leonid Troyanovsky © (24.04.07 19:20)
> Must Die.
Согласаен.
См. [1] и далее [14] - это я чтоб не писать много слов скопировал код автора из [0]. "Ошибки" в данном случае нет. Но для "правильного" написания кода в данной ветке уже обговорены моменты, например в [16], но для НЕ модальных - этого мало. Поэтому и привел в том виде как было сначала.
Leonid Troyanovsky (2007-04-24 19:20:00) [37]
> {RASkov} (24.04.07 19:06) [20]
> > Form2, Form3 - MD.
Must Die.
See also: LMD.
--
Regards, LVT.
Leonid Troyanovsky (2007-04-24 19:17:00) [38]
> Kostafey © (24.04.07 18:57) [18]
> Материал усвоил.
Ну, если ты так быстро схватываешь,
немодальные оставлю в качестве домашнего задания.
--
Regards, LVT.
{RASkov} (2007-04-24 19:06:00) [39]> [17] Leonid Troyanovsky © (24.04.07 18:49)
> Form2, Form3 - MD.
?
> [19] Kostafey © (24.04.07 18:58)
with TFormX.Create(nil) do
....
Только из AutoCreate убери(если еще не сделал этого) TFormX.
Kostafey (2007-04-24 18:58:00) [40]> with TFormX.Create(nil) do
> try
> {подготовительная работа}
> case ShowModal of
> {анализ выбора пользователя}
> end;
> finally
> Free;
> end;
А вообще, спасибо!