[Решено]Как выполнить что-либо в модальном окне?
Модератор: Модераторы
-
SilverShadow
- новенький
- Сообщения: 22
- Зарегистрирован: 10.03.2010 16:48:59
[Решено]Как выполнить что-либо в модальном окне?
И не изобрёл ли я велосипед?
Суть вопроса: в программе есть достаточно длительная процедура(импорт данных из файла(ов)). Я вынес её в отдельный модуль, к нему - форма с отображением процесса(прогрессбар, лейблы с именем файла/количеством строк в нём/номером текущей(обрабатываемой) строки/количеством ошибок данных(если они есть)). Никаких кнопок управления или меню на форме нет, да и не нужны они там.
Если показывать форму через .Show, то всё нормально. Импорт идёт, данные обновляются. Но окно немодальное со всеми вытекающими.
В случае .ShowModal - всё виснет после отрисовки формы и дальше процесс не идёт. Я понимаю - код основной формы прерывается, а вот вызываемую-то за что?
После долгих мыканий решил проблему так: по созданию формы присваиваю переменной FirstRun значение True, а в событии onActivate - если FirstRun, то FirstRun := False и затем DoSomething (собственно процедура импорта).
Видел в сетях вариант с таймером, но это то же, что делаю я, только в профиль и сложнее.
Нет ли более простого/правильного способа сделать искомое? Ещё раз подчеркну - на вызываемой форме нет элементов управления. Форма создаётся динамически перед вызовом, по завершению операции - уничтожается.
Суть вопроса: в программе есть достаточно длительная процедура(импорт данных из файла(ов)). Я вынес её в отдельный модуль, к нему - форма с отображением процесса(прогрессбар, лейблы с именем файла/количеством строк в нём/номером текущей(обрабатываемой) строки/количеством ошибок данных(если они есть)). Никаких кнопок управления или меню на форме нет, да и не нужны они там.
Если показывать форму через .Show, то всё нормально. Импорт идёт, данные обновляются. Но окно немодальное со всеми вытекающими.
В случае .ShowModal - всё виснет после отрисовки формы и дальше процесс не идёт. Я понимаю - код основной формы прерывается, а вот вызываемую-то за что?
После долгих мыканий решил проблему так: по созданию формы присваиваю переменной FirstRun значение True, а в событии onActivate - если FirstRun, то FirstRun := False и затем DoSomething (собственно процедура импорта).
Видел в сетях вариант с таймером, но это то же, что делаю я, только в профиль и сложнее.
Нет ли более простого/правильного способа сделать искомое? Ещё раз подчеркну - на вызываемой форме нет элементов управления. Форма создаётся динамически перед вызовом, по завершению операции - уничтожается.
Последний раз редактировалось SilverShadow 12.12.2015 17:30:35, всего редактировалось 1 раз.
Насколько я понимаю, всю логику в случае показа модального диалогового окна надо делать в нём - событие OnShow - это то, что должно быть перед её отображением, а дальше да, лучше всего получить управление либо по таймеру или по нажатию чего-то на модальной форме.
-
SilverShadow
- новенький
- Сообщения: 22
- Зарегистрирован: 10.03.2010 16:48:59
Оно даже не диалоговое, скорее - информационное. И прерывать его я не даю, ибо нефиг.
По нажатию(клавиши или мышки) - не вариант, а вдруг не нажмут? Ну и таймер - излишен, зачем огород городить? Моё решение с on_activate изящнее выходит.
По нажатию(клавиши или мышки) - не вариант, а вдруг не нажмут? Ну и таймер - излишен, зачем огород городить? Моё решение с on_activate изящнее выходит.
SilverShadow писал(а):Нет ли более простого/правильного способа сделать искомое?
Пару строк - завести счетчик и через каждую, к примеру, сотню считанных строк вызывать отклик
Код: Выделить всё
if (Count div 1000) = 0 then Application.ProcessMessages;з.ы. К счетчику и прогрессбар можно прикрутить, если есть возможность оценить общее количество.
-
SilverShadow
- новенький
- Сообщения: 22
- Зарегистрирован: 10.03.2010 16:48:59
А где этот счётчик прописать? Как он управление получит?
P.S. Наверное, всё-таки (iCycle mod 100) = 0 ?
P.S. Наверное, всё-таки (iCycle mod 100) = 0 ?
SilverShadow писал(а):Оно даже не диалоговое, скорее - информационное. И прерывать его я не даю, ибо нефиг.
Может быть, для таких целей больше подойдёт что-то вроде ToolWindow? Тогда как главную форму можно на время расчётов сделать нерабочей (Disable).
Вопрос про Application.ProcessMessages тоже важен, но он касается не столько ShowModal, сколько логики расчётов.
SilverShadow писал(а):А где этот счётчик прописать?
где
SilverShadow писал(а):данные обновляются
********
SilverShadow писал(а):P.S. Наверное, всё-таки (iCycle mod 100) = 0 ?
да
-
SilverShadow
- новенький
- Сообщения: 22
- Зарегистрирован: 10.03.2010 16:48:59
resident писал(а):гдеSilverShadow писал(а):данные обновляются
daesher писал(а):ToolWindow? Тогда как главную форму можно на время расчётов сделать нерабочей
Проблема в том, что после .ShowModal ни счётчик прописать, ни сделать главную форму нерабочей(я это и безо всяких инструментов могу) не-по-лу-чит-ся!
А Application.ProcessMessages я и так каждый цикл считывания строки делаю, так что избыточно эту процедуру вызывать нет никакой необходимости.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
SilverShadow, а кто мешает это сделать перед показом формы?
И да, кстати, модальное окно оно и должно блокировать вызывающую форму. Так что, если хотите работать в окне ее вызывающем, то выберете другой метод показа формы. А что блокируется модальная форма... видимо, придется переделать ее обработчик.
И да, кстати, модальное окно оно и должно блокировать вызывающую форму. Так что, если хотите работать в окне ее вызывающем, то выберете другой метод показа формы. А что блокируется модальная форма... видимо, придется переделать ее обработчик.
-
SilverShadow
- новенький
- Сообщения: 22
- Зарегистрирован: 10.03.2010 16:48:59
Я не хочу работать в основном окне - не для того я импорт делал отдельным модулем. Я добился того, что мне требовалось получить от модального окна. Просто у меня возникли сомнения, правильно ли(оптимально ли) я это делаю. Судя по ответам, сомнения были напрасны.
Всем спасибо большое за ответы!
Всем спасибо большое за ответы!
SilverShadow писал(а):Я добился того, что мне требовалось получить от модального окна.
Как?
SilverShadow писал(а):Проблема в том, что после .ShowModal ни счётчик прописать, ни сделать главную форму нерабочей(я это и безо всяких инструментов могу) не-по-лу-чит-ся!
В случае с ToolWindow ShowModal не нужно. Оно будет всегда висеть поверх вызывающей формы.
С другой стороны, зачем Вам модальность? Её главная задача - получить ModalResult от окна после нажатия соответствующей кнопки, отображая модальное окно всегда поверх (правда, бывают казусы, если модальное окно свернуть). Второстепенная задача - заблокировать вызывающее окно, пока открыто модальное. В вашем случае ModalResult не нужен, остаётся блокировка вызывающего окна, которую можно сделать и так. Или я что-то упустил?
SilverShadow писал(а):Нет ли более простого/правильного способа сделать искомое?
Изучи TThread, станет намного легче и удобнее. Через PostMessage посылай переменные(или сигналы состояния) на форму. Так работают все серьезные визуальные компоненты.
SilverShadow писал(а):В случае .ShowModal - всё виснет после отрисовки формы и дальше процесс не идёт. Я понимаю - код основной формы прерывается, а вот вызываемую-то за что?
Потому что принято работать с одним потоком, и этот поток тормозится на принятие решений в модальном режиме от пользователя(нужно ему выбрать что дальше делать).. - так принято в мире форм..
TTimer прямой потомок от TThread.SilverShadow писал(а):Видел в сетях вариант с таймером, но это то же, что делаю я, только в профиль и сложнее.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Имитация модального поведения диалога
при вызове формы form1.Enable:=false;
в обработчике события onClose form1.Enable:=True;
формы показывать как обычно.
при вызове формы form1.Enable:=false;
в обработчике события onClose form1.Enable:=True;
формы показывать как обычно.
-
SilverShadow
- новенький
- Сообщения: 22
- Зарегистрирован: 10.03.2010 16:48:59
resident писал(а):SilverShadow писал(а):Я добился того, что мне требовалось получить от модального окна.
Как?
по созданию формы присваиваю переменной FirstRun значение True, а в событии созданной формы onActivate - если FirstRun, то FirstRun := False и затем DoSomething (собственно процедура импорта).
Добавлено спустя 14 минут 50 секунд:
daesher писал(а):В вашем случае ModalResult не нужен, остаётся блокировка вызывающего окна, которую можно сделать и так. Или я что-то упустил?
Нет, всё именно так. Но имитация модального окна через Form.Enabled := False работает не совсем так, как истинно модальное окно, даже с установленным свойством Form.FormStyle fsStayOnTop
Добавлено спустя 10 минут 18 секунд:
olegy писал(а):Изучи TThread, станет намного легче и удобнее.
Ну, собственно, по этому пути и придётся идти. Просто из-за одной формы огород городить не хотелось.
