![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
MDI правильное закрытие окон и исчезновением их [D6]
tio © (2006-05-27 08:17:00)Уважаемые, Мастера.
Кто-нибудь может дать пример, который правильно реализовывал
закрытие дочерних окон MDI c cообщением, и чтобы окна
исчезали, а не висели (окна остаются).
Заранее спасибо.
Игорь Шевченко (2006-05-31 13:23:00) [1]
while ActiveMDIChild <> nil do begin
ActiveMDIChild.Release;
Application.ProcessMessages;
end;
ЮЮ (2006-05-31 09:15:00) [2]На это можно не смотреть === Это можно выкинуть
Это собственный обработчик события.
Если тоже хочется, то делается элементарно, например:
TDocumentForm = class(TForm)
private
FOnBeforeSave: TNotifyEvent;
...
Если одного параметра Sender мало можно "придумать" свой тип, например
TDialogEvent =
procedure(Sender: TObject; out ModalResult: TModalResult) of object;
тогда будет
FOnBeforeSave: TDialogEvent ;
и public property
OnBeforeSave: TDialogEvent
read FOnBeforeSave write FOnBeforeSave;
теперь в другой форме после создания экземпляра TDocumentForm я назначу собственный обработчик.
tio (2006-05-31 08:53:00) [3]Еще раз извиняюсь.
А что такое FOnBeforeSave?
ЮЮ (2006-05-30 11:58:00) [4]На это можно не смотреть:
if Assigned(FOnBeforeSave) then
FOnBeforeSave(Self, mbr)
просто форма используется во многих приложениях и кое-где требовались некоторые доп. проверки (манипуляции)
ЮЮ (2006-05-30 11:48:00) [5]>Ведь цикл только с первым членом массива по Вашему. MdiChild[0]
А кто, интересно, станет первым членом массива (хотя это и не массив, а индексное свойство) после уничтожения экземпляра, который раньше был как MdiChild[0]?
>Я посмотрел Access - там такая же фигня.
Исходники? :)
А наверное решение есть.
Надо подвергнуть этот вопрос коллегиальному обсуждению.
Зачем вообще какие то циклы?
Мы закрываем главную форму MDI приложения.
Оно само попытвется закрыть все дочерние формы.
Остется в FormCloseQuery дочерней формы все разрулить, например
procedure TDocumentForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
mbr: TModalResult;
begin
if <есть изменеия> then begin
mbr :=
Application.MessageBox(
PChar(
'Документ ''' + Caption + ''' был изменен! Сохранить изменения ?'
),
'Закрытие документа',
MB_YESNOCANCEL + MB_DEFBUTTON3 + MB_ICONQUESTION
);
if mbr = IDYES then begin
if Assigned(FOnBeforeSave) then
FOnBeforeSave(Self, mbr)
else
mbr := mrOk;
CanClose := (mbr = mrOk) or (mbr = mrYes);
if CanClose then
try
<попытка сохраниться>
CanClose := true;
except
CanClose := false;
end
else
CanClose := false;
end
else
CanClose := (mbr = IDNO);
end
else
CanClose := true;
if CanClose then OnResize := nil;
end;
tio (2006-05-30 11:24:00) [6]А если несколько MDIChild,то тогда как?
Ведь цикл только с первым членом массива по Вашему. MdiChild[0]
По моему и этот пример не удачен.
Я посмотрел Access - там такая же фигня.
А наверное решение есть.
Надо подвергнуть этот вопрос коллегиальному обсуждению.
ЮЮ (2006-05-30 11:12:00) [7]Хотя и так нельзя.
Лучше просто
While Application.MainForm.MdiChildCount > 0 do
Application.MainForm.MdiChild[0].Close
разрулив выход из цикла, если нажали Отмена
ЮЮ (2006-05-30 11:08:00) [8]Оба кода работают некорректно, если
потому, что цикл организован неверно, хотя бы так сделай:
for i:= Application.MainForm.MdiChildCount-1 downto 0do
Application.MainForm.MdiChild[i].Close;
tio (2006-05-30 10:49:00) [9]Уважаемые мастера.
Вы немного не поняли.
В главном окне, когда закрываешь приложение или
в функции закрыть все MDIChild окна, когда
нажимаешь ДА в сообщении о закрытии, они все равно
висят.
Как из главного окна закрывать дочерние с закрытием и
исчезновением их, когда нажимаешь ДА или НЕт диалога о закрытии
данного MDIChild окна.
Жуков Олег (2006-05-27 18:04:00) [10]В OnCloseQuery:
var
QueryResult: Integer;
if SilentMode then // SilentMode: Boolean - глобально объявленная переменная-флаг. Если её установить в True, вопросов при сохранении не будет.
QueryResult := ID_YES; // или ID_NO, смотря что нужно
else
QueryResult := Application.Messagebox(0, 'Сохранить изменения?', 'Сообщение', mb_YesNOCancel);
case QueryResult of
ID_NO: CanClose:=True;
ID_Cancel: CanClose:= False;
ID_Yes:
begin
CanClose:=True;
вставить код сохранения
end;
end;
tio (2006-05-27 15:16:00) [11]в процедуре закрытия окно более 1 имеем:
for i:=0 to Screen.Forms.Count-1 do
Screen.Forms[i].Close;
И с Action:=cafree в OnClose;
Или
for i:=0 to Application.MainForm.MdiChildCount-1 do
Application.MainForm.MdiChild[i].Close;
Оба кода работают некорректно, если
спрашивать onCloseQuery
case Application.Messagebox(0,'Закрыть окно?','Сообщение',mb_YesNOCancel) of
ID_no:CanClose:=true;
ID_Cancel:Abort;
ID_Yes: вставить код закрытия с охранением
//
во здесь окна и остаются, даже если окна были закрыты с "Да" - они висят, как ни в чем не бывало.
Как быть, а нужно выдать сообщение о закрытии многих окон?
Loginov Dmitry (2006-05-27 09:03:00) [12]
>чтобы окна
> исчезали, а не висели
procedure TForm1Close(...);
begin
Action := acFree;
end;
> Кто-нибудь может дать пример, который правильно
>реализовывал
> закрытие дочерних окон MDI c cообщением
Здесь бы не мешало расшифровать смысл сказанного.