Форум: "Основная";
Текущий архив: 2006.01.22;
Скачать: [xml.tar.bz2];
ВнизКорректное закрытие приложения ... Найти похожие ветки
← →
Asail (2005-12-13 12:25) [0]Здрасте!!!
Как можно корректно закрыть приложение, в случае, когда
открыто несколько форм (модальных)?
Грубо говоря, в определенный момент надо закрыть все, что было открыто из главной формы, а затем и саму главную форму.
Проблема в том, что таких модальных форм может быть много.
К тому-же могут оказаться в момент закрытия приложения
открытые диалоговые окна (OpenDlg, SaveDlg), message-боксы (типа ShowMessage), Preview отчетов...
Задача - корректно закрыть приложение, так, что-бы у каждой
открытой формы сработал OnClose (в обратной, относительно порядка открытия форм, последовательности).
Пардон за черезчур длинный вопрос.
Заранее, спасибо!
← →
Васяня (2005-12-13 12:36) [1]Чо за муть? зачем такой изврат? ну до ладно... может назначения для всех форм одного обработчика событий нас спасет?
Например, в главное форме делаем так:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ShowMessage("j");
end;
и в модальной форме так:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Form1.OnClose(Sender, Action);
end;
Теперь, это самое сложное определить Sender и тащиться от того что ты супер кодер :)
← →
Asail (2005-12-13 12:50) [2]Я, видимо, некорректно задал вопрос.
Нужно, при событии frmMain.OnClose, закрывалось все, что было открыто до сих пор.
Т.е. если последовательность открытия модальных форм такова:
frmMain -> frmA -> frmB -> frmC, то при frmMain.Close
надо закрыть все формы в обратной последовательности:
frmC.Close; frmB.Close; frmA.Close
и только потом окончательно убить frmMain...
← →
Васяня (2005-12-13 12:55) [3]Кхе...
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
frmA.Close();
frmB.Close();
frmC.Close();
frmD.Close();
Close();
end;
Это?
Если по каким-то причинам модальные формы не хотят умирать то ты их по темечку, перепиши процедупу закрытия, вернее воткни в нее Halt какой-нить и всЁ... аль я ни так опять чего понял?
← →
evvcom © (2005-12-13 13:00) [4]
> Васяня (13.12.05 12:36) [1]
> Чо за муть? зачем такой изврат?
Вот что за муть ты, Васяня, написал с использованием глобальных переменных и пр.? А изврат такой нужен, если ты хочешь написать надежное приложение. Например, винда закрывается по каким-либо причинам (сигнал от UPS из-за сбоя по питанию).
← →
Игорь Шевченко © (2005-12-13 13:02) [5]Васяня
" Еще не хотелось бы видеть открытого коверканья русского языка, использования уличного сленга. "
Понял, да ?
← →
Васяня (2005-12-13 13:07) [6]Удалено модератором
← →
clickmaker © (2005-12-13 13:17) [7]что-то непонятно...
если модальные формы (да и немодальные) создаются как
Form := TForm1.Create(Application)
то почему бы не сделать
for i := Application.ComponentCount-1 downto 0
if (Application.Components[i] is TForm)
TForm(Application.Components[i]).Close;
Ы?
← →
Lamer@fools.ua © (2005-12-13 13:20) [8]>>clickmaker © (13.12.05 13:17) [7]
IMHO, через Screen.Forms (либо Screen.CustomForms) удобнее и быстрее.
← →
evvcom © (2005-12-13 13:56) [9]Мне интересно другое. Каким образом у автора вызван frmMain.OnClose? Ведь когда открыта модальная форма, главная недоступна. Остаются только сообщения и прямой вызов Close из модальной. И цикл крутится где-то внутри ShowModal (не надо никому уточнять, где именно, я и сам знаю, как посмотреть). Я когда-то пытался такое сделать, но нашлись более важные дела, так и не додумал, решения не нашел. У меня была тогда проблема, что MainForm уничтожалась в этом случае раньше, чем модальная, и программа выходя из модального цикла, возвращалась в методы и обработчики MainForm, где предполагалось, что Self еще существует, с естественным AV.
← →
umbra © (2005-12-13 15:19) [10]может в Application.OnMessage сообщения перехватывать и формы закрывать?
← →
Jeer © (2005-12-13 16:34) [11]Это не поможет ? :)
with fmMain do
for i := 0 to MDIChildCount-1 do
MDIChildren[i].Close;
← →
evvcom © (2005-12-13 17:21) [12]
> Jeer © (13.12.05 16:34) [11]
Что-то я не заметил, чтобы где-нибудь говорилось об MDI-приложении.
← →
Asail (2005-12-13 18:13) [13]Поясню свою задачу...
Необходимо в определенный момент времени (например, по таймеру)
закрыть все приложение. Application.Terminate - не есть хорошо, т.к. убъет
все без разбора, а в открытых окнах могут быть открытые файлы, DataSet"ы
и т.д. Таким образом, надо закрыть все открытые окна прежде, чем
Terminate. Проблема в том, что закрывать окна желательно в обратной
их открытию последовательности. Т.е., если, frmA открыла frmB, то сначала
надо закрыть frmB и только потом - frmA. Особенно это важно если frmB
обращается к компонентам с frmA (datasets например).
← →
Jeer © (2005-12-13 18:34) [14]Asail (13.12.05 18:13) [13]
Не вижу особых проблем, если нет пожеланий интерактивности в вопросе открытых и измененных, но не записанных данных.
Но это неверное проектирование логики работы с датасет.
А так:
TSession.DatabaseCount
Databases[Index: Integer]
DataSets[Index: Integer]
State: -> TDataSetState type
← →
Jeer © (2005-12-13 18:35) [15]evvcom © (13.12.05 17:21) [12]
Может ты и не заметил, может он чего-то не договорил.
Как выясняется - не договорил:)
← →
Asail (2005-12-14 18:05) [16]Я так и не понял, как вызвать form.Close последовательно сверху вниз,
т.е. от последнего открытого окна к первому. Метод Close для всех окон
будет вызываться из главной формы (по таймеру), а после закрытия всех
окон можно вызвать и Close для главной.
← →
Alexander Panov © (2005-12-14 19:44) [17]Asail (14.12.05 18:05) [16]
Я так и не понял, как вызвать form.Close последовательно сверху вниз,
А при корректном закрытии приложения(например, на кнопку "x") модальные формы и так будут закрыты в порядке, обратном их появлению. Если у тебя что-то нужно закрыть, используй событие OnClose этих форм.
← →
Alexander Panov © (2005-12-14 19:46) [18]Добавлю, что событие OnClose основной формы срабоает после закрытия всех модальных форм.
← →
Asail (2005-12-15 09:56) [19]2Alexander Panov
> А при корректном закрытии приложения
А Application.Terminate - это корректное закрытие? И как можно нажать
кнопку "х" в главной форме, если из нее открыта хотя-бы одна модальная
форма?
← →
evvcom © (2005-12-15 11:03) [20]Кстати, то что я описывал в [9] делалось в D5 да еще и с dll. Может что-то некорректно я описал и может что-то еще. Но сейчас я попробовал в D7 аналогичное проделать, все корректно завершилось. Пробовал из открытой модальной формы (в цепочке их штук 6 было) Application.MainForm.Close; и SendMessage(Application.MainForm.Handle, WM_CLOSE, 0, 0); Все OK!
← →
Asail (2005-12-18 17:32) [21]2evvcom
> Пробовал из открытой модальной формы (в цепочке их штук
> 6 было) Application.MainForm.Close
А у меня не получается !!!
Вызавыю из последней модальной формы Application.MainForm.Close.
Все формы действительно закрываются, но событие OnClose вызывается
только для главной формы, а у модальных нет. А в этом и был вопрос!
Извиняюсь за занудство...
← →
evvcom © (2005-12-19 10:19) [22]А... Вон в чем дело! Ну дык... Смотри код TCustomForm.ShowModal
if Application.FTerminate then ModalResult := mrCancel else
if ModalResult <> 0 then CloseModal;
Видишь, если принудительное завершение приложение произошло, то CloseModal не вызывается. Корректнее, думаю, действительно было бы написать:if Application.FTerminate then ModalResult := mrCancel;
if ModalResult <> 0 then CloseModal;
Но поскольку трогать генофонд не принято, ищи другие выходы. Вешай обработчик OnDestroy, например.
← →
Asail (2005-12-19 11:32) [23]
> clickmaker © (13.12.05 13:17) [7]
> то почему бы не сделать
> for i := Application.ComponentCount-1 downto 0
> if (Application.Components[i] is TForm)
> TForm(Application.Components[i]).Close;
Попробовал так, вроде сработало!
Спасибо.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.01.22;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.049 c