Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> MDI-формы, при закрытии формы выскакивает ошибка, почти разгодал, но нужна Вашапомощь 
:(
    Опции темы
Delphist
  Дата 20.3.2010, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

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



Есть MDI-приложение. Если мы закрываем приложение, при это должно быть открыто хоть одно дочернее, то возникает ошибка: 
Cannot create form. No MDI forms are currently active. 
Начал делать отладку выяснил с чем это связано - оказывается, что FormDestroy Application.MainForm србатывает раньше чем дочернейю. 
Как засавить MDI приложение сначала уничтожить Child-формы, а уже затем MainForm?

Это сообщение отредактировал(а) Delphist - 20.3.2010, 17:40


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
bems
Дата 20.3.2010, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



Во OnClose же действие устанавливаешь в caFree?


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Delphist
Дата 20.3.2010, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

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



Цитата(bems @ 20.3.2010,  18:40)
Во OnClose же действие устанавливаешь в caFree?

В OnClose чего Child-формы?


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
Delphist
Дата 20.3.2010, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

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



Сейчас попробовал в MainForm сделать так:
Код

private
    procedure WMClose(var Message: TWMClose); message WM_CLOSE;
...
procedure
  TFMOMainForm.WMClose(var Message: TWMClose);
begin

  if (App.WindowList.CloseAllWindows) then
    inherited;
end;

Вроде все нормально, но ошибка вознекнет в том случае, если мы свернем наше приложение, а затем на TaskBar'e нажмем правой кнопкой на этом приложении и нажмем Закрыть
я так понял это связано с тем, что сообщение WM_CLOSE в этом случае не посылается. Как с этим бороться?


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
RomanEEP
Дата 20.3.2010, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 424
Регистрация: 18.5.2006
Где: Коломна

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



Все верно, MDI окно лежит на главной форме, а следовательно должно уничтожаться в самом деструкторе формы и никак не раньше.
Ошибка No MDI forms are currently active. может возникнуть при обращении к свойству Handle или методу HandleNeeded Child формы из её деструктора или из деструктора главной формы.
PM MAIL   Вверх
Delphist
  Дата 22.3.2010, 13:11 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

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



Вообщем проблема решена. Нашел косяк VCL. Заключается он в следующем - если мы создаем MDI-приложение и на событие OnDestroy Child формы напишем Child.FormDestroy, в котором содержится обращение к Self.Handle, мы в итоге получим наш exception. Я считаю что это очень большой косяк. Пока окно не уничтожено я должен иметь право и обращаться и к Handle и все что угодно. Вообщем проблема решается очень просто:

Код

TMyMDIMainForm = class(TForm)
public
  ...
  function CloseQuery: Boolean;
end;
...

function TMyMDIMainForm.CloseQuery;
begin
  
  Result := CloseAllWindows;
  if Result then
    Result := inherited CloseQuery;
end;


где CloseAllWindows; - это некая ф-ция, которая в цикле пробует закрыть все открытые child-формы.

Это сообщение отредактировал(а) Delphist - 23.3.2010, 11:08


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
pseud
Дата 23.3.2010, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

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



Цитата(Delphist @  20.3.2010,  17:30 Найти цитируемый пост)
оказывается, что FormDestroy Application.MainForm србатывает раньше чем дочернейю. 

это абсолютно естественно. удаляется главная форма, которая вызывает удаление своих "детей".

Цитата(Delphist @  22.3.2010,  13:11 Найти цитируемый пост)
сообственно чего я и добивался от гуру-данного форума

гуру данного форума не берут на себя таких громких высказываний, как:
Цитата(Delphist @  22.3.2010,  13:11 Найти цитируемый пост)
 Нашел косяк VCL

Цитата(Delphist @  22.3.2010,  13:11 Найти цитируемый пост)
Я считаю что это очень большой косяк


Добавлено через 59 секунд
извини, но не списывай свой кривой код на кривизну VCL


--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Delphist
Дата 23.3.2010, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

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



Цитата(pseud @  23.3.2010,  11:54 Найти цитируемый пост)
извини, но не списывай свой кривой код на кривизну VCL 

а где в документации vcl написано, что в OnDestroy запрещено обращаться к Self.Handle? smile 


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
pseud
Дата 23.3.2010, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

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



Цитата(Delphist @  23.3.2010,  11:35 Найти цитируемый пост)
а где в документации vcl написано, что в OnDestroy запрещено обращаться к Self.Handle? 

А кто сказал, что запрещено? 
Создал новый проект. В обработчик Form1.OnDestroy написал:
Код

procedure TForm1.FormDestroy(Sender: TObject);
var
  s: string;
begin
  s := IntToStr(Self.Handle);
end;

и никаких проблем.


--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Delphist
Дата 23.3.2010, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

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



Цитата(pseud @  23.3.2010,  12:56 Найти цитируемый пост)
А кто сказал, что запрещено? 
Создал новый проект. В обработчик Form1.OnDestroy написал:

Замечательно, а теперь сделай MDI-приложение и  в дочернем окне попробуй сделать тоже самое


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
pseud
Дата 24.3.2010, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

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



Цитата(Delphist @  23.3.2010,  15:09 Найти цитируемый пост)
Замечательно, а теперь сделай MDI-приложение и  в дочернем окне попробуй сделать тоже самое

Создал новое приложение (Delphi 6):
Цитата

File -> New -> Other... -> Projects -> MDI Application

У автоматом созданного класса дочернего окна прописал в OnDestroy
Код

procedure TMDIChild.FormDestroy(Sender: TObject);
var
  s: string;
begin
  s := IntToStr(Self.Handle);
  ShowMessage(s);
end;

Все так же прекрасно отрабатывает, как и в неMDI.


--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Delphist
  Дата 25.3.2010, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

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



Цитата(pseud @  24.3.2010,  13:56 Найти цитируемый пост)
Все так же прекрасно отрабатывает, как и в неMDI. 

Согласен отрабатывает, если 
Child := TMDIChild.Create(Application), а если  Child := TMDIChild.Create(Self), то возникнет Exception.
Но даже при этом раскладе Child := TMDIChild.Create(Application) все равно не работает как хотелось бы, а именно:
В Child-форме в событии OnCloseQuery мы размещаем код в котором проверяем были внесены изменения, если были, то пользователю выдается сообщение с вопросом сохранить их и три возможных действия: Да, Нет, Отмена т.е. сохранить, не сохранить, и оменить закрытии формы. 
К примеру пусть открыты два дочерних окна и в обоих внесены изменения (например в БД) когда мы закрываем всё приложение, то естественно будет сделана на автомате попытка закрыть все дочернии формы. При попытки закрыть первое выдается наше сообщение о надобности сохранения, пусть пользователь нажмет НЕТ, тогда вместо того, чтобы это дочернее окно закрылось без сохранения, и перешло к опросу другого, мы просто увидим, что приложение перешло к опросу другого, и если здесь пользователь на вопрос сохранить ли изменения в дочернем окне 2 нажмет Отмена, то закрытие приложения отменяется, но при этом дочернее окно №1 так и останется не закрытым, что не совсем логично.

Мой механизм с переопределением CloseQuery позволяет избежать этого.

Это сообщение отредактировал(а) Delphist - 25.3.2010, 11:49


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
pseud
Дата 25.3.2010, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

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



Цитата(Delphist @  25.3.2010,  11:48 Найти цитируемый пост)
Согласен отрабатывает, если Child := TMDIChild.Create(Application), а если  Child := TMDIChild.Create(Self), то возникнет Exception.

Вспоминается анекдот.
Некий пенсионер был чрезвычайно удручен видом из его окон соседней женской бани с мелькающими наглыми телами обнаженных женщин. 
Явилась авторитетная комиссия. Побродили, ничего не обнаружили.
- Так ведь никого не видно, – подивилась ответственная комиссия.
- Да, а вы на шкаф залезьте! – ответствовал оскорбленный пенсионер.


Это сообщение отредактировал(а) pseud - 25.3.2010, 12:58


--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Delphist
  Дата 25.3.2010, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

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



Цитата(pseud @  25.3.2010,  13:57 Найти цитируемый пост)
Вспоминается анекдот.
Некий пенсионер был чрезвычайно удручен видом из его окон соседней женской бани с мелькающими наглыми телами обнаженных женщин. 
Явилась авторитетная комиссия. Побродили, ничего не обнаружили.
- Так ведь никого не видно, – подивилась ответственная комиссия.
- Да, а вы на шкаф залезьте! – ответствовал оскорбленный пенсионер.

Тут дело даже не в том как мы создаем эти формы, а в этом (VCL - не совсем логичная задумка в VCL):
В Child-форме в событии OnCloseQuery мы размещаем код в котором проверяем были внесены изменения, если были, то пользователю выдается сообщение с вопросом сохранить их и три возможных действия: Да, Нет, Отмена т.е. сохранить, не сохранить, и оменить закрытии формы. 
К примеру пусть открыты два дочерних окна и в обоих внесены изменения (например в БД) когда мы закрываем всё приложение, то естественно будет сделана на автомате попытка закрыть все дочернии формы. При попытки закрыть первое выдается наше сообщение о надобности сохранения, пусть пользователь нажмет НЕТ, тогда вместо того, чтобы это дочернее окно закрылось без сохранения, и перешло к опросу другого, мы просто увидим, что приложение перешло к опросу другого, и если здесь пользователь на вопрос сохранить ли изменения в дочернем окне 2 нажмет Отмена, то закрытие приложения отменяется, но при этом дочернее окно №1 так и останется не закрытым, что не совсем логично.


Это сообщение отредактировал(а) Delphist - 25.3.2010, 13:38


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
pseud
Дата 25.3.2010, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

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



Цитата(Delphist @  25.3.2010,  13:37 Найти цитируемый пост)
что не совсем логично.

1. Создал первый новый документ эксель - сохранил.
2. Создал второй новый документ эксель - сохранил.
3. Открыл первый документ - внес изменения.
4. Открыл второй документ - внес изменения.
5. Жму "ЗАКРЫТЬ".
Excel спрашивает "Сохранить документ 1" - говорю ДА, 
Excel спрашивает "Сохранить документ 2" - говорю ОТМЕНА.
---------------------------------------------------
ИТОГ: Остаются открыты оба документа.

Добавлено через 2 минуты и 9 секунд
Рекомендую написать письмо в Microsoft о нелогичности. 
Хочешь логично - делай все сам, точнее дорабатывай напильником.


--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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