| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Для новичков > Открытие новой формы и закрытие текущей. |
| Автор: Robus 4.2.2011, 06:45 |
| Здравствуйте. Столкнулся с проблемой запуска приложения на Windows-7 ... В программе есть две формы. Из первой формы вызывается вторая, при этом первая форма делается hide. Во второй форме по закрытию делался "form.close" или "HALT", который на ХР прекрасно всё закрывал, на Windows 7 в итоге получается "фаталл-еррор", и приложение остаётся висеть в задачах, при этом честно освобождаются все порты и закрываются все потоки. Каждая из форм отдельно друг от друга прекрасно работает и корректно закрывается. Так же прекрасно закрывается первая форма не загрузившая вторую. Собственно вариант делать hide первой форме мне не нравился, поскольку не вижу смысла работе на заднем фоне формы к которой уже никогда не вернусь. Но попытки закрыть первую форму приводило к полному закрытию всех форм. Как можно загрузить форму-2, и закрыть форму-1 ? Язык - Delphi 7 |
| Автор: Poseidon 4.2.2011, 09:35 |
| Что-то мне подсказывает, что первая форма - главная. |
| Автор: chip_and_dayl 4.2.2011, 10:02 |
| Тогда сделать вторую форму главной, а перед запуском главной формы уже второй формы грузить первую. Тогда можно спокойно закрывать то окно которое не нужно |
| Автор: Keeper89 4.2.2011, 12:49 |
| Похоже на мастер, почему бы не сделать на одной форме? |
| Автор: Robus 4.2.2011, 13:11 |
При создании (FormCreate) запускается два три потока. И так всё устроено, что форма не должна показаться пользователю до создания этих потоков. Иначе придётся наворачивать код всякими IF'ами, где они совсем не нужны. Допустим у меня есть в форме список устройство в одной из подсетей. Само появление формы гласит о том, что одно из устройств есть в подсети, и мне нужно постоянно его пере-запрашивать. Каждый пере-запрос или конфигурация на той стороне ведётся учётом. Вообщем программа начнёт обрастать лишним кодом лишь от того, что нельзя в нужный момент времени загрузить форму. Да и не хочется затыкать код "костылями". Если язык программирования позволяет, а я думаю, что он позволяет выгрузить одну форму и загрузить вторую, то грех не научиться это делать. |
| Автор: Poseidon 4.2.2011, 14:22 |
| Ну тогда ты должен понимать, что закрытие (Close) этой формы будет означать завершение работы программы. Тебе именно это надо? |
| Автор: Robus 4.2.2011, 17:39 | ||
Мне нужно закрытие обеих форм действием к закрытию программы. Или эту же проблему решит вопрос - "как сделать главной другую форму" ? |
| Автор: Robus 4.2.2011, 18:44 | ||
| Ура ... Ура !!! Уря ... Проблему решил, поковыряв цикл делфи, там всего-то для главной формы созданный поинтер, где лежит адрес главной формы ... В цикле проверяется на nil. Итак делается это так ... Допустим, что Form1 это главная форма, а Form2 должна стать главной в зависимости от результата выполнения в Form1 ... Код в Form1 пытающийся передать "главность" Form2:
И всё честно ... Вторая форма становится активной, первая честно закрывается освобождая память !!! Спасибо за помощь, кому приятно, не просто убирать видимость форме а честно её выгружать, - пользуйтесь на здоровье ! Может памяти у меня и гиг, но когда-то и 48к было то же океаном ... |
| Автор: V1Ray 31.5.2013, 14:09 |
| Robus, спасибо, реально классная штука!!! Не зря провисела 2 года))) |
| Автор: superVad 31.5.2013, 18:44 |
| V1Ray, я не уверен, что это корректный код. Т.к. Application.MainForm это не указатель, а свойство возвращающее указатель. Буду рад если кто то объяснит, что там под капотом происходит при таких присваиваниях. На самом деле - это все лишнее. Надо просто убрать из автосоздания форм - все формы. Тогда вообще не будет главной формы. И в файле проекта, вместо Application.Run запустить свою процедуру или объект (http://ins911.blogspot.com/2008/12/singletone-delphi.html) управляющие окнами. Ну и там же Application.Title что то присвоить. |
| Автор: V1Ray 8.6.2013, 23:24 |
| superVad,http://www.cyberforum.ru/delphi-beginners/thread124078.html ссылка. Проще уже некуда Комментарий STRATEG-а. Там ссылка на толковый пример. |
| Автор: Illusion Dolphin 8.6.2013, 23:36 |
| Поддержу superVad, это грязный хак. Можно просто сделать форму невидимую, она будет главной для приложения, но видна не будет, а остальные показывай-закрывай уже в любом порядке без проблем. |
| Автор: northener 9.6.2013, 01:20 | ||||||
Хм. А где в ответах STRATEG-а применялся этот "грязный фак" с подменой значения ссылки Application.MainForm? Посмотрел несколько примеров STRATEG-а. Везде всё как предложил
P.S.
Возможно этот вариант не сочетается с не так давно появившемся (ИМХО в Д2005) свойством TApplication.MainFoirmOnTaskBar |
| Автор: bems 9.6.2013, 04:51 |
| да, это хак. но с другой стороны можно понять людей которые это применяют. нехватает в vcl возможности сделать сабж без хаков, чо уж там |
| Автор: БелАмор 9.6.2013, 07:38 |
Не могу я понять таких людей. Это примерно как лезть в окно, вырезая решётку автогеном только из-за того, что дверь открывается не внутрь, а наружу. Человеку говоришь: "Ну потяни ты на себя дверь, и всё, никаких проблем..." А он гордо заявляет, что его задача решена, и посему такое решение его вполне устраивает, и добавляет: "Классная штука - автоген, что бы я без него делал? Спасибо тому парню, который мне его дал..." В чем состоит проблема? В том, что первая создаваемая форма в приложении назначается главной, а потом нельзя назначить главной формой другую? Ну, так, Application.CreateForm как раз и предназначена для автоматического назначения главной формы. Т.е. человек сначала сам, своими собственными руками назначает главную форму, а потом думает, как бы её переназначить... Это какой-то мазохизм... Если создавать форму через конструктор, например TPasswordForm.Create, то форма не назначается главной - создавай, отображай, закрывай, уничтожай хоть десяток, а первая созданная через Application.CreateForm будет назначена главной. И переназначать главную форму просто нет необходимости. |
| Автор: Illusion Dolphin 9.6.2013, 09:13 | ||||||
Это исправляется без проблем.
Согласен, тут отнюдь не гибкое решение, которое не всегда приминимо, могли бы это уже и исправить.
У меня в приложении нет главной формы |
| Автор: bems 9.6.2013, 12:06 | ||||||
вторая половина
да знают тут все для чего оно предназначено. но работает неудобно. |
| Автор: БелАмор 9.6.2013, 19:59 | ||
Я ни в коем случае не отрицаю, что бывают какие-то специфические ситуации, но большинство вопросов по поводу переназначения главной формы связаны с заставками и запросами логинов/паролей, т.е. в большинстве случаев реальной необходимости переназначения нет. Однако, я практически не встречаю советов создавать форму через конструктор, чтобы она не назначалась главной. |
| Автор: Illusion Dolphin 9.6.2013, 21:27 | ||
Заставку хорошо бы делать на винапи (т.к. VCL не многопоточный) в отдельном потоке, чтобы не мешать загрузке приложения. Переназначение главной формы это всегда специфическая задача, и очень прескорбно, что до сих пор приходится людям писать костыли чтобы обойти "стандартное решение". |
| Автор: Poseidon 9.6.2013, 23:04 |
| А по-моему, возникновение необходимости переназначить главную форму - это ошибка в архитектуре. В хорошо продуманных программах такой необходимости нет. Заставка? Она создается и уничтозается отдельно, пока главная форма грузится. Форма логинов? Так эту форму нужно показывать после загрузки главной. В голову вообще не приходят варианты, когда может понадобится переназначение главной формы и что бы это ну никак нельзя было обойти. |
| Автор: northener 10.6.2013, 01:24 | ||||||
Вот с этим никак не согласен. Приложения требующие проверку учетной записи своего пользователя как правило довольно большие и их загрузка занимает довольно заметное время. Так зачем его тратить, если проверка даст отрицательный результат? Представте себе Winlogon, который проверяет учетную запись пользователя после полной загрузки ОС! Это конечно не полностью адекватный пример, но почти. Ведь трудно себе представить Дельфи-приложение, которое после "загрузки" главной формы ещё не готово выполнять все свои функции, если авторизация пройдет успешно.
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1411 уже почти 4 года. (А может быть и больше).
Ещё при царе горохе в демках в поставке Дельфи появился пример создания Splash Screen. В проекте MastApp.dpr И советы посмотреть этот пример я встречал неоднократно. И сам советовал. Но воз и ныне там. Гугль и иже с ним возвращает только советы кульхацкеров уровня песочницы. :( Хотя этот пример даже содержит хелп файл (правда на аглицком), в котором чёрным по белому написано: The Splash screen appears when MASTAPP starts. MASTAPP.DPR calls TSplashForm.Create to create the splash screen and the instance of the application, calls SplashForm.Show to display the form while all other MASTAPP forms are created, and calls SplashForm.Update to display the application's "Loading ..." message on the form. When all MASTAPP forms are created, MASTAPP.DPR calls SplashForm.Hide to hide the Splash screen display. И никаких проблем с MainForm. |
| Автор: bems 10.6.2013, 08:39 | ||
|
| Автор: Poseidon 10.6.2013, 10:40 | ||
|
| Автор: northener 10.6.2013, 12:47 | ||
Ну не скажи. Раз главное окно программы показано, то среднестатистический пользователь считает, что ему уже можно нажимать на всякие пупочки в этом окне чтобы получить желаемый результат. А если основной функционал программы ещё не загружен, то вышеуказанный пользователь очень огорчится когда у него ничего не выйдет |
| Автор: northener 11.6.2013, 01:07 | ||
Или я неправильно понял:
Где в таком случае размещаем создание и показ формы ввода логина? |
| Автор: Poseidon 11.6.2013, 09:05 | ||||||||
northener, шутки шутим?
|