Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Закрытие дочерних окон при закрытии главного окна, не получается так, как надо :) 
:(
    Опции темы
NightWishMaster
Дата 21.7.2008, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 14.4.2006

Репутация: нет
Всего: нет



Помогите, пожалуйста в решении следующей на первый взгляд простой проблемы. Для демонстрации ее сути создал простенькое приложение. Есть главная форма MainForm (fsMDIForm), в которой можна создавать дочерние формы ChildForm (fsMDIChild). При закрытии отдельно взятой дочерней формы в обработчике события OnCloseQuery у пользователя спрашивается, закрывать ли эту дочернюю форму или оставить открытой. При закрытии главной формы сначала запускаются по очереди обработчики события OnCloseQuery для всех дочерних окон, спрашивают, закрывать ли соответствующее дочернее окно и только в случае подтверждения закрытия ВСЕХ дочерних окон дочерние окна по очереди закрываются, после чего зарывается главная форма. Если же пользователь подтвердил, например, закрытия первых двох дочерних форм, а для третьей нажал "Нет", то ничего не закроется и все три дочерние формы останутся открытыми, что явно не логично. 

На сколько я понял, то при закрытии главной формы события разворачиваются так:
1) срабатывают по очереди OnCloseQuery дочерних окон;
2) если после всех OnCloseQuery дочерних окон переменная CanClose остается true, то срабатывает OnCloseQuery главного окна;
3) если и после этого CanClose == true, то срабатывает событие OnClose ГЛАВНОЙ ФОРМЫ, событие же OnClose дочерних окон при этом не срабатывают.

Мне же нужна следующая ситуация: 
1) при закрытии главной формы для каждой дочерней формы спрашивается разрешение на ее закрытие;
2) если для даной дочерней формы пользователь подтвердил закрытие, она сразу закрывается;
3) если пользователь запретил закрытие дочерней формы, то больше ничего не закрывается вообще.
По-моему так выглядит логично. Я пробовал в обработчике OnCloseQuery дочерней формы в случае подтверждения закрытия сразу закрывать дочернюю форму, но вылазит ошибка. На сколько я понимаю, пока при попытке закрытия главной формы не будут опрошены все дочерние формы закрывать дочерние формы нельзя. Так ли это? И как быть? Думаю не я первый с таким столкнулся.

Заранее благодарен за советы smile

ПС. Код главной формы:

Код

TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::N2Click(TObject *Sender)
{
  TChildForm* NewChildForm = new TChildForm(Application);
  NewChildForm->Caption = "Окно " + IntToStr(MDIChildCount);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::N3Click(TObject *Sender)
{
  if (MDIChildCount)
    (dynamic_cast<TChildForm*>(MainForm->ActiveMDIChild))->Close();
}


Код дочерней формы:

Код

TChildForm *ChildForm;
//---------------------------------------------------------------------------
__fastcall TChildForm::TChildForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TChildForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  CanClose = (Application->MessageBox(("Закрыть " + Caption + "?").c_str(), "Внимание", MB_YESNO + MB_ICONWARNING) == IDYES);
}
//---------------------------------------------------------------------------
void __fastcall TChildForm::FormClose(TObject *Sender,
      TCloseAction &Action)
{
  Action = caFree;
}


Проект прикреплен к теме.

Это сообщение отредактировал(а) NightWishMaster - 21.7.2008, 16:15

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  Project.zip 46,78 Kb
PM MAIL   Вверх
Rrader
  Дата 21.7.2008, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 13
Всего: 191



Дочерние формы не получают события OnClose. Нужно вызывать вручную.

Это сообщение отредактировал(а) Rrader - 21.7.2008, 17:53


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
NightWishMaster
Дата 21.7.2008, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 14.4.2006

Репутация: нет
Всего: нет



Цитата

Дочерние формы не получают события OnClose. Нужно вызывать вручную.

Я это понимаю. Откуда их вызывать - вот в чем вопрос.
PM MAIL   Вверх
NightWishMaster
Дата 22.7.2008, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 14.4.2006

Репутация: нет
Всего: нет



А может кто подскажет, как отловить событие, когда пользователь выбирает команду "Закрыть" для главной формы (т.е. щелкает на крестик). Дело в том, что сразу после этого вначале идут события OnCloseQuery дочерних окон и только после этого OnCloseQuery главной формы. А мне хотелось бы в событиях OnCloseQuery дочерних форм отличить, вызвано оно в результате закрытия пользователем конкретно этой формы или же главной формы. В таком случае можно было бы в событиях OnCloseQuery дочерних форм, если они вызваны при закрытии главной формы, проигнорировать их код, а в событии OnCloseQuery главной формы вызвать поочереди для всех дочерних форм метод Close() и после его вызова для каждой формы проверять - закрылась ли форма. Если нет, то CanClose = false и песенка спета smile
PM MAIL   Вверх
NightWishMaster
Дата 22.7.2008, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 14.4.2006

Репутация: нет
Всего: нет



Проблему решил, отказавшись от использования события OnCloseQuery дочерних форм.
Вот код, все работает, как и должно:

Главная форма:

Код

TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::MCreateChildFormClick(TObject *Sender)
{
  TChildForm* NewChildForm = new TChildForm(Application);
  NewChildForm->Caption = "Окно " + IntToStr(MDIChildCount);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::MCloseChildFormClick(TObject *Sender)
{
  if (MDIChildCount)
    (dynamic_cast<TChildForm*>(ActiveMDIChild))->Close();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  TCloseAction CurrentAction;
  while (MDIChildCount)
    {
      (dynamic_cast<TChildForm*>(ActiveMDIChild))->FormClose(ActiveMDIChild, CurrentAction);
      if (CurrentAction == caFree) delete ActiveMDIChild;
      else
        {
          CanClose = false;
          return;
        }
    }
}


Дочерняя форма:

Код

TChildForm *ChildForm;
//---------------------------------------------------------------------------
__fastcall TChildForm::TChildForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TChildForm::FormClose(TObject *Sender,
      TCloseAction &Action)
{
  Action = Application->MessageBox(("Закрыть " + Caption + "?").c_str(), "Внимание", MB_YESNO + MB_ICONWARNING) == IDYES ? caFree : caNone;
}


Проект прикреплен.

Это сообщение отредактировал(а) NightWishMaster - 22.7.2008, 14:06

Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  CloseMDIFormProject.zip 47,65 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0441 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.