Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.07.16;
Скачать: CL | DM;

Вниз

MDI правильное закрытие окон и исчезновением их   Найти похожие ветки 

 
tio   (2006-05-27 08:17) [0]

Уважаемые, Мастера.
Кто-нибудь может дать пример, который правильно реализовывал
закрытие дочерних окон MDI c cообщением, и чтобы окна
исчезали, а не висели (окна остаются).
Заранее спасибо.


 
Loginov Dmitry ©   (2006-05-27 09:03) [1]


>чтобы окна
> исчезали, а не висели


procedure TForm1Close(...);
begin
 Action := acFree;
end;


> Кто-нибудь может дать пример, который правильно
>реализовывал
> закрытие дочерних окон MDI c cообщением


Здесь бы не мешало расшифровать смысл сказанного.


 
tio   (2006-05-27 15:16) [2]

в процедуре закрытия окно более 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: вставить код закрытия с охранением
//
во здесь окна и остаются, даже если окна были закрыты с "Да" - они висят, как ни в чем не бывало.

Как быть, а нужно выдать сообщение о закрытии многих окон?


 
Жуков Олег   (2006-05-27 18:04) [3]

В 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-30 10:49) [4]

Уважаемые мастера.
Вы немного не поняли.
В главном окне, когда закрываешь приложение или
в функции закрыть все MDIChild окна, когда
нажимаешь ДА в сообщении о закрытии, они все равно
висят.
Как из главного окна закрывать дочерние с закрытием и
исчезновением их, когда нажимаешь ДА или НЕт диалога о закрытии
данного MDIChild окна.


 
ЮЮ ©   (2006-05-30 11:08) [5]

Оба кода работают некорректно, если

потому, что цикл организован неверно,  хотя бы так сделай:
for i:= Application.MainForm.MdiChildCount-1 downto 0 do
 Application.MainForm.MdiChild[i].Close;


 
ЮЮ ©   (2006-05-30 11:12) [6]

Хотя и так нельзя.
Лучше просто
 While Application.MainForm.MdiChildCount > 0 do
    Application.MainForm.MdiChild[0].Close

разрулив выход из цикла, если нажали Отмена


 
tio   (2006-05-30 11:24) [7]

А если несколько MDIChild,то тогда как?
Ведь цикл только с первым членом массива по Вашему. MdiChild[0]
По моему и этот пример не удачен.
Я посмотрел Access - там такая же фигня.
А наверное решение есть.
Надо подвергнуть этот вопрос коллегиальному обсуждению.


 
ЮЮ ©   (2006-05-30 11:48) [8]

>Ведь цикл только с первым членом массива по Вашему. 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;


 
ЮЮ ©   (2006-05-30 11:58) [9]

На это можно не смотреть:

if Assigned(FOnBeforeSave) then
      FOnBeforeSave(Self, mbr)


просто форма используется во многих приложениях и кое-где требовались некоторые доп. проверки (манипуляции)


 
tio   (2006-05-31 08:53) [10]

Еще раз извиняюсь.
А что такое FOnBeforeSave?


 
ЮЮ ©   (2006-05-31 09:15) [11]

На это можно не смотреть === Это можно выкинуть

Это собственный обработчик события.
Если тоже хочется, то делается элементарно, например:

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 я назначу собственный обработчик.


 
Игорь Шевченко ©   (2006-05-31 13:23) [12]

 while ActiveMDIChild <> nil do begin
   ActiveMDIChild.Release;
   Application.ProcessMessages;
 end;



Страницы: 1 вся ветка

Текущий архив: 2006.07.16;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.038 c
2-1151290269
Тоха
2006-06-26 06:51
2006.07.16
Как нажать кнопку чужого приложения.


2-1151389275
Kain-Lord
2006-06-27 10:21
2006.07.16
Помогите с мерцанием!


10-1121847387
serjufa
2005-07-20 12:16
2006.07.16
в листе excel нарисовать стрелки


15-1150294537
JUS
2006-06-14 18:15
2006.07.16
Как закинуть свой готовый сайт в интернет?


2-1151579681
fast2
2006-06-29 15:14
2006.07.16
Как проверить, что переменная типаTDate "пустая", т.е....