Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как закрыть иерархию модальных форм?


Автор: altarasjuk 6.9.2003, 20:17
Привет!
Вот собственно говоря какая штука:
Из одной формы открывается другая модальная и так несколько раз. т.е
Form1
Form2
Form3
Form4

И такой вопрос, как при желании с Form4 закрыть всё это безобразие smile.gif ? Вариант типа
Код
procedure TForm4.Button1Click(...);
begin
  Self.Close;
  Form3.Close;
  Form2.Close;
  Form1.Close;
end;
не подхотит. т.к. Form4 незачем знать о своём владельце больше, чем то, что он TComponent, и уж тем более им управлять. Он остаётся как бы на крайняк.

Автор: <Spawn> 6.9.2003, 20:39
Так сканает(Закроет все кроме главной формы)?
Код
for i:=0 to Screen.FormCount-1 do
if Screen.Forms[i]<>Application.MainForm then
 Screen.Forms[i].Close;

Автор: dm9 6.9.2003, 20:47
А чем не нравится оценка в i-1 форме результата вызова ShowModal(Form_i) и вызов Close?

Автор: altarasjuk 6.9.2003, 20:55
Цитата
CODE
for i:=0 to Screen.FormCount-1 do
if Screen.Forms[i]<>Application.MainForm then
Screen.Forms[i].Close;
Дык наверное стоит попробовать, но опять же Form4 будет знать о Main form что не есть очень хорошо... Тут бы как-то через Owner, ну типа TForm(Owner).Close; но так нельзя, т.к. после close его надо free. а там метод до конца не отработал и получим Access voilation, не хорошо....
А мысль себя закрывать и бросать Exception по цепочке, и в "владельце" его обрабатывать... (у меня формы открываются статическими методами, и из них буду бросать). Вот что значит щють-щють подумать smile.gif . Попробую скажу что получилось.

Автор: <Spawn> 6.9.2003, 21:04
А чем TForm(Owner).Close не нравится? Ставишь в OnClose его для всех этих форм и все(кроме первоначальной, а то он главную форму закроет smile.gif ). А формы создаешь таким путем:
Код
try
Form:=TForm.Create(Self);
Form.ShowModal;
finally
FreeAndNil(Form);
end;


И будет тебе счастье smile.gif

Автор: dm9 6.9.2003, 21:22
Об этом уже, кажется, говорилось. Разве можно закрывать владельца, если метод ещё не отработал? Или я что-то не понимаю?

Автор: <Spawn> 6.9.2003, 21:26
dm9 Я проверил и все закрылось без каких либо ошибок.

Автор: <Spawn> 6.9.2003, 21:39
Цитата
Дык наверное стоит попробовать, но опять же Form4 будет знать о Main form что не есть очень хорошо...

Не знаю чем тебе не нравится то, что четвертая форма будет знать о главной, в поток тогда что ли все помести))) :
Код
unit Unit4;

interface

uses
 Classes, Forms;

type
 TCloseFormsThread = class(TThread)
 private

 protected
   procedure Execute; override;
 end;

implementation


procedure TCloseFormsThread.Execute;
var
i:integer;
begin
for i:=0 to Screen.FormCount-1 do
if Screen.Forms[i]<>Application.MainForm then
 Screen.Forms[i].Close;
end;

end.


И из нужной формы запусти его :

Код
with TCloseFormsThread.Create(True) do
begin
 FreeOnTerminate:=True;
 Resume;
end;

Автор: dm9 6.9.2003, 21:54
Цитата
А чем TForm(Owner).Close не нравится? Ставишь в OnClose его для всех этих форм и все(кроме первоначальной, а то он главную форму закроет smile.gif ). А формы создаешь таким путем:
Код
try
Form:=TForm.Create(Self);
Form.ShowModal;
finally
FreeAndNil(Form);
end;


И будет тебе счастье smile.gif


Что-то торможу... у меня так не выходит. Не кинешь исходник, если ещё не удалил? Интересно уже стало smile.gif

Автор: altarasjuk 6.9.2003, 22:04
<Spawn>б задестрой объект когда метод в нём ещё не отработал, и в этом методе подёргай поля и методы этого объекта:
Код
procedure TForm1.Button1....
var
 frm2: TFrom2;
begin
 frm2:= TFom2.Create(self);
 frm2.ShowModal;
 self.Caption:= 'Gm.....'; // где - то тут будет ошибка.
 self.<Some>
 .....
 frm2.Free;
end;

2. Я решил остановиться на Exception - самый нечерезжопный вариант. И работает smile.gif

З.Ы. Не все Access voilation отлавливаются траями smile.gif . Проверено на горьком опыте.

Автор: maxim1000 6.9.2003, 22:21
можно создать какой-нибудь флажок
когда модальной форме стало известно, что нужно закрыться и закрыть предыдущие формы она его установит в true, если нет - false
каждая форма после использования другой модальной формы должна будет проверять этот флажок и закрываться, если он true (ну, может не каждая, главной форме так поступать не стоит)
таким образом вызванная форма ничего не знает о своем владельце, а просто дает ему информацию для размышлений smile.gif

Автор: dm9 6.9.2003, 22:36
А флажок этот где будет? Правильно, или в общем доп. модуле, или где? В том самом модуле главной формы, от чего мы и уходили smile.gif В общем, тут уже пошёл немножко флуд smile.gif

Автор: maxim1000 7.9.2003, 08:48
вместо флажка можно использовать значеие ModalResult
оно возвращается функцией ShowModal
тогда форма, которая вдруг решила, что нужно много чего закрыть, возвращает в ModalResult, какое-нибудь специальное значение
другие формы проверяют результат функции ShowModal, если он равен этому значению, то закрывают себя и в ModalResult себе пишут то же самое

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)