|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Доброе утро! Помогите пожалуйста разобраться! В окне имеется класс с кнопками ("Buttons"), далее последовательно одна из другой открываются формы (все модальные), по клику на какую-нибудь кнопку из класса, нужно закрыть все открытые формы (если таковые имеются). пишу такой код: x=_SCREEN.FORMCOUNT DO WHILE x>1 IF ALLTRIM(UPPER(_SCREEN.FORMS(x).NAME))=="BUTTONS" ELSE _SCREEN.FORMS(x).RELEASE ENDIF x=_SCREEN.FORMCOUNT ENDDO В результате закрывается только последняя форма, а форма (или несколько) предыдущая остается открытой, но при этом никаких ошибок не выдается, все зацикливается и виснет. Подскажите пожалуйста что я делаю не так. Заранее благодарю ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:00 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
2 AnnaSPB в фокспро есть bindevents в инит формы можно передать ссылку на предыдущую форму и подписать событие если руками это делать, то также передаете ссылку, кладете ее в св-во формы и в нужно месте выполняете релиз формы-ссылки ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:09 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Код: plaintext 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:09 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
я пробовала уже разные варианты, ничего не получается :( Не закрывается только форма, в которой производились какие-то действия, такое ощущение, что где-то это прописывается и именно это и мешает. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:16 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
пробовала и так через ActiveForm закрывать: _screen.ActiveForm.release() результат один и тот же - последняя из открытых форм закрывается, остальные нет ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:22 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
AnnaSPBя пробовала уже разные варианты, ничего не получается :( Не закрывается только форма, в которой производились какие-то действия, такое ощущение, что где-то это прописывается и именно это и мешает. Мешает то что формы модальные. Такой способ закрытия только для немодальных форм подходит. В твоем случае все модальные. Вот и закрывается только самая верхняя. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:35 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Dima T, спасибо. Я попробовала если формы немодальные, все получилось. Но проблема в том, что мне нужно. чтобы формы были модальными. как закрыть модальные окна с внешней кнопки? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:41 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
AnnaSPBDima T, спасибо. Я попробовала если формы немодальные, все получилось. Но проблема в том, что мне нужно. чтобы формы были модальными. 1. Хорошенько подумать, действительно ли это так. В подавляющем числе случаев это далеко не так при кажущейся необходимости. как закрыть модальные окна с внешней кнопки? 2. Думать над порядком активизации форм при последовательном удалении форм. Может оказаться труднее первого варианта. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:46 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
кстати, а почему тогда верхнее окно закрывалось? эта форма ведь тоже модальная ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:47 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
проходящий, мне тоже этот вариант не нравится и я уже столкнулась с массой проблем из-за этого, но не хотят люди понять этого! вот им так удобнее и все! ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 10:50 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Раз окна модальные, значит можно закрыть только активную форму т.е последнюю? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 11:37 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
так что нет способа закрыть окна, если они модальные? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 11:45 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
AnnaSPBтак что нет способа закрыть окна, если они модальные? Из одного места нет. Каждая форма должна закрыть сама себя. Например форма1 вызвала форму2 та форму3 и в форме 3 дали команду закрыть все формы: Форма 3 должна как-то известить форму 2 (установить флаг глобальный или что-то вернуть) и закрыться Форма 2 после "do form Форма3" должна проверить есть ли команда на закрытие и закрыться если есть и известить об этом форму 1 Форма 1 аналогично Форме 2 ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 11:51 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
задача несколько иная - команда на закрытие форм дается не из одной из форм, а с внешней кнопки. Наблюдения такие: 1) если открыта одна форма - она закрывается без проблем; 2) если открыто две формы (форма1 -> форма2) - закрывается форма2, форма1 висит что не делаю; 3) если открыто 3 формы (форма1 -> форма2 -> форма3) - форма3 закрывается, остальные висят. Может есть какой-нибудь признак, свойство, незнаю.... что-то, что ставится глобально в VFP и не дает закрыть форму? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 12:14 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
AnnaSPBМожет есть какой-нибудь признак, свойство, незнаю.... что-то, что ставится глобально в VFP и не дает закрыть форму? Есть Form.WindowType = 1 (Modal) оно и не дает. Если это кнопка "Выход" то выдай сообщение "Закройте все окошки" и все. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 12:38 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
это идея! спасибо! :) ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 12:45 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Форма остается модальной до тех пор пока она видима. Если форму сделать невидимой (скрытой), то она теряет модальность. Поэтому можно чуть-чуть изменить код. Код: plaintext 1. 2.
Хотя, в общем случае, процесс закрытия всех открытых форм не такой простой как может показаться. Тут много "подводных камней" и в общем случае эта задача не решается. Каждое решение является "частным случаем". Под конкретное приложение. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 13:44 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
ВладимирМ Я пробовала так. Релиз проходит, не ругается, но _SCREEN.FORMCOUNT все равно возвращает то же количество форм, как-будно он "не видит", что она закрылась. да и судя по объектам она действительно не закрылась ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 13:50 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Разумеется. Ведь проблема еще в том, что форма не может быть закрыта пока не завершится метод этой формы. А вызов подчиненных форм, вероятно, происходит из каких-то методов главной формы (по нажатию кнопки, например). Вот и получается, метод Hide() делает форму не модальной, но тот метод, в котором эта форма была вызвана не может завершиться, пока работает процедура с циклом закрытия форм. Нужно "пропихнуть" очередь накопившихся событий. Простейший вариант - это вынести две эти команды в отдельную процедуру или метод Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Здесь "фишка" в том, что процедура - это отдельный модуль в стеке (очереди) процессов на исполнение. Соответственно, он будет иметь определенный приоритет и есть вероятность, что перед очередным шагом цикла он пропустит перед собой процедуру завершения того метода в котором была вызвана модальная форма. Хотя, повторюсь. Без гарантий. Это может сработать, но может и НЕ сработать. При определенных условиях. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 14:06 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
ВладимирМВот и получается, метод Hide() делает форму не модальной, но тот метод, в котором эта форма была вызвана не может завершиться, пока работает процедура с циклом закрытия форм. Нужно "пропихнуть" очередь накопившихся событий. Приведенным кодом сменить порядок в очереди врядли не удасться. Надо тогда таймер задействовать чтобы он запускал код по мере освобождения очереди. Тут обсуждали похожую проблему, только формы немодальные были. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 14:22 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Попробовала метод предложенный ВладимиромМ, получились не очень обнадеживающие результаты: - во-первых, при таком алгоритме формы закрываются сначала, т.е. если запуск был форма1 -> форма2, то закрывается сначало форма1, а потом форма2. Но это исправить не проблема. - проблема остается в том, что даже если закрываю формы в правильном порядке (форма2, форма1), то на форме1 не срабатывает метод unload и все открытые курсоры висят. Чего не хотелось бы. - а при последовательном вызове 3 форм - на двух формах кроме последней не отрабатывает метод unload В чем может быть причина? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 15:06 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Может кому-нибудь поможет... У меня решилась проблема таким образом: For x = _SCREEN.FORMCOUNT TO 1 step -1 IF !(ALLTRIM(UPPER(_SCREEN.FORMS(x).name))=="BUTTONS") DO FormRelease WITH x ENDIF ENDFOR C процедурой FormRelease почему-то работать отказалось, я сделала одноименную программу: LPARAMETERS nIndex _SCREEN.Forms(m.nIndex).Hide() _SCREEN.Forms(m.nIndex).Release() RETURN Но проблема с "не закрытием" открытых рабочих областей осталась. Поэтому я после закрытия всех форм делаю CLOSE DATABASES. Вроде работает стабильно. Спасибо всем за участие ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 15:53 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Повторюсь. Форма не может быть закрыта, пока выполняется какой-либо ее метод или событие или существуют внешние ссылки на эту форму. Раз форма не закрывается (не выполняется unload), значит, что-то ей не дает это сделать. Какой-то не завершенный метод или ссылка. Сценарий простой: Форма 1 имеет кнопку по нажатии которой запускается модальная Форма 2 В этом состоянии закрыть Форму 1 невозможно, поскольку событие Click() кнопки еще не завершено. Его "держит" открытая модальная Форма 2. После закрытия Формы 2 событие Click() отработает до конца и Форма 1 после этого может быть закрыта. Однако если в процедуре дается две команды подряд Форма_2.Release() Форма_1.Release() то Форма 2, конечно, закрывается, но Форма 1 хотя и получает команду на закрытие, но закрыта быть не может поскольку у нее по прежнему "висит" не завершенное событие Click() кнопки. Дело в том, что FoxPro - это однопоточное приложение. Все процессы выполняются последовательно. Никакой процесс не может быть "разорван", чтобы где-то в его середине выполнить отложенные процессы. Кроме тех случаев, когда это предусматривается самой программой. В данном случае, событие Click() формы не может завершиться до окончания работы кода по закрытию форм. Это событие не может "разорвать" основной код Если открыто всего 2 формы, то по завершении процедуры закрытия отработает оставшееся событие Click() первой формы и первая форма тоже закроется. Но если форм больше, то для третьей формы этого уже не хватит. Можно попробовать сделать закрытие форм в 2 отдельные процедуры. Первая процедура сканирует все формы и делает их не видимыми. Вторая процедура закрывает все формы. Но это должны быть именно отдельные процедуры или методы, чтобы между их выполнением отработали все не завершенные события форм. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.
Хотя опять же нет никакой гарантии, что этого окажется достаточно. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 16:30 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
ВладимирМ Да, Вы правы, к сожалению, правы :( И в этом я убедилась, когда стала как следует тестировать все это. То что я сделала оказалось мало. Попробую сделать две разные процедуры. Подумаю может еще что-нибудь "умное" придет в голову. Если есть какие-то соображения, пожалуйста пишите ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 16:43 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Этого оказалось не достаточно. Не закрывается форма, из которой была вызвана другая форма, не отрабатывает Unload, все равно держит его что-то. И _screen.FormCount возвращает 2, и курсоры открыты. Может есть какие-нибудь мысли по этому поводу? Как это обойти? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 17:28 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Дело в том, что у формы должен быть свой собственный метод, который обеспечивает коррекное закрытие этой и именно этой формы. Ну, например, при закрытии некоторой формы возникает дополнительный запрос на какие-либо дополнительные модификации. При этом, есть различие "штатного" закрытия (самим пользователем) и "аварийного" (по нажатию на крестик в правом верхнем углу приложения). Лично у меня, вызов этого метода по закрытию формы происходит из штатного метода Form.QueryUnload. Например, на форме есть кнопка "Выход" в событии Click() которой и прописано закрытие формы (после соответсвующих проверок дается команда ThisForm.Release()). Тогда в событии Form.QueryUnload() будет примерно такой код Код: plaintext 1. 2. 3.
Соответственно, метод по закрытию всех открытых форм заключается не в вызове события Release() форм, а в вызове события QueryUnload() которое и берет на себя всю работу по корректному закрытию формы. При этом надо учитывать последовательность форм. Т.е. закрывать формы в "правильном" порядке. Начиная с самой последней. В коллекции _SCREEN.Forms() самая последняя открытая форма имеет индекс 1, предпоследняя - 2 и т.д. Т.е. закрывать надо всегда 1 форму, поскольку после закрытия первой формы индекс 1 получит та, которая была второй. Код: plaintext 1. 2. 3. 4.
Но в этом случае есть опасность зацикливания, если форма по каким-то причинам не может быть закрыта. Точнее, не зацикливания, а нескольких попыток закрытия только одной формы, не закрывая все остальные. В общем, вот один из вариантов, который, впрочем, тоже ничего не гарантирует Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44.
... |
|||
:
Нравится:
Не нравится:
|
|||
13.08.2008, 17:48 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
ВладимирМ спасибо большое за участие. Я попробовала сделать как Вы написали, но, к сожалению, все тоже самое: форма2 закрывается, проходит unload, а на форме1 нет. :( ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 09:36 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Может я не права, но мне вот еще что не понятно: ведь в последней форме (форма2) отрабатывает закрытие формы по всем правилам (т.е. release, unload), значит вводе как мы должны вернуться в метод откуда было открытие формы (например, клик по кнопке) и закончить его, а потом уже все остальные действия (если таковые имеются). Разве нет? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 09:47 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
AnnaSPBМожет я не права, но мне вот еще что не понятно: ведь в последней форме (форма2) отрабатывает закрытие формы по всем правилам (т.е. release, unload), значит вводе как мы должны вернуться в метод откуда было открытие формы (например, клик по кнопке) и закончить его, а потом уже все остальные действия (если таковые имеются). Разве нет? FoxPro - это однопоточное приложение. Вернуться-то он должен. Весь вопрос в том КОГДА. Он не может прервать выполнение текущей процедуры, чтобы обработать закрытие формы "по всем правилам". Т.е. завершение обработки клика кнопки произойдет только после того, как будет закончена процедура закрытия всех открытых форм. А к этому моменту эта форма уже может быть безнадежно испорчена попытками ее закрыть. И завершение события Click() кнопки уже ничего не исправит. У нас есть программа (инструкция) соержащая примерно такую последовательность команд: Инструкция 1 1. Закрыть форму 1 2. Закрыть Форму 2 Вот он ее "тупо" и выполняет. От начала и до конца. То, что после выполнения команды "Закрыть форму 1" теоретически должна выполнится еще одна инструкция вида Инструкция 2 1. Завершить событие Click() кнопки на форме 2 Вовсе не означает, что "Инструкция 2" будет выполнена сразу после команды "Закрыть форму 1". Эта инструкция будет поставлена в очередь инструкций. В данном случае сразу за "Инструкцией 1". В результате получаем такой список: Инструкция 1 1. Закрыть форму 1 (выполнено) 2. Закрыть Форму 2 Инструкция 2 1. Завершить событие Click() кнопки на форме 2 Получаем неразрешимое противоречие. В данный конкретный момент времени выполняется вторая команда Инструкции 1 (закрыть Форму 2), а в очереди процессов ждет своего часа еще одна инструкция на завершение метода этой закрываемой формы. Хуже всего то, что FoxPro может "частично" закрыть Форму 2 в такой ситуации. Т.е. уничтожить часть объектов свойств и методов этой формы. И последующее выполнение Инструкции 2 уже ничего не рашает. Форма 2 оказывается в таком состоянии, что ее невозможно уничтожить уже никакими способами. Именно поэтому, закрытие формы должно выполняться не через прямые команды ThisForm.Release(), а через методы, которые прежде, чем дать команду на закрытие проверят, а можно ли вообще закрыть форму. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 11:36 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
ВладимирМ Да я в этом уже убедилась. Я пробовала сделать как Вы рекомендовали, через QueryUnload(), но получила тотже результат. Я уже просто и не знаю что можно с этим сделать!?! И вообще можно ли с этим как-то бороться? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 11:47 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
QueryUnload() - это один из вариантов. Смысл-то не в каком-то методе, а в его НАПОЛНЕНИИ. Что там внутри записано. Как один из вариантов решения - запустить процесс самозакрытия форм через объекты-таймеры. Т.е. на каждой форме есть объект-таймер. Который с некоторой периодичностью просматривает содержимое некой служебной таблички. Если в этой табличке выставлен некий флаг (значение поля), то этот таймер дает команду на закрытие данной, текущей формы. "По быстрому" это можно сделать не через поле таблицы, а через глобальную переменную. Хотя таблица рано или поздно все-равно понадобиться. Если из метода формы вызывается модальная форма, то перед вызовом модальной формы этот таймер отключается и включается только после закрытия модальной формы. Ну, примерно так: Код: plaintext 1. 2. 3.
Объект TmrAutoClose - это как раз этот таймер автозакрытия. Тогда процесс закрытия всех открытых форм будет заключаться просто в установке флага в этой служебной таблице (или изменение занчения глобальной переменной) и запуск другого таймера, который периодически будет проверять есть ли сейчас открытые формы. Если ни одной открытой формы не осталось, то этот таймер закрывает приложение. Обработка выполняется через таймеры именно для того, чтобы все процессы по автозакрытию форм отработали в нужной последовательности. Чтобы не возникло проблем с очередями процессов. Да, разумеется, выставление флага блокирует открытие новых форм. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 12:03 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
да это же УЖАС! В каждой форме писать обработку по таймеру, организация таблиц... а если форм в проекте десятки??? К тому же насколько я в курсе таймер "не очень хорошо" ладит с модальными формами, а в моем случае формы модальные. Замкнутый круг какой-то. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 12:31 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
AnnaSPBда это же УЖАС! В каждой форме писать обработку по таймеру, организация таблиц... а если форм в проекте десятки??? К тому же насколько я в курсе таймер "не очень хорошо" ладит с модальными формами, а в моем случае формы модальные. Замкнутый круг какой-то. Для этого надо наследовать свою форму от некоторого базового класса, в которую и поместить всю общую для всех форм функциональность. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 12:40 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Попробовала закрыть формы с использованием таймеров. На двух формах, последовательно вызываемых друг из друга поместила таймеры, которые следять за переменной lCloseFormAll, и если она равна true, закрывают форму. На внешней кнопке такой код: For x = _SCREEN.FORMCOUNT to 1 step -1 IF !(ALLTRIM(UPPER(_SCREEN.FORMS(x).NAME))=="BUTTONS") lCloseFormAll = .T. ENDIF EndFor * выполнение неких действий ... ... ... Результаты аналогичные: первая форма закрывается, вторая нет. В общем то это и логично, управление в первую форму не возвращается. Продолжают выполняться действия на внешней кнопке (при этом форма 1 не закрыта). А вот после выполнения всех действий на внешней кнопке, возвращается управление на форму 1, срабатывает таймер и форма закрывается. Но задача стоит перед выполнением действий на форме предварительно закрыть ВСЕ открытые формы. Посоветуйте пожалуйста как можно этого добиться? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 14:26 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
AnnaSPBНа внешней кнопке такой код А кнопка где расположена? Если формы модальные, то на верхней форме должна быть, т.к. все остальное недоступно. AnnaSPBFor x = _SCREEN.FORMCOUNT to 1 step -1 IF !(ALLTRIM(UPPER(_SCREEN.FORMS(x).NAME))=="BUTTONS") lCloseFormAll = .T. ENDIF EndFor * выполнение неких действий ... ... ... Сделай таймер там же где кнопка. Для ожидания отработки остальных таймеров :) Код раздели так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 14:49 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Если формы хоть по одной но закрываются, то можно одним таймером попробовать обойтись. Там же где и кнопка: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 14:53 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
кнопка находится не на форме, это тулбар с несколькими кнопками ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 14:56 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
кнопка находится не на форме, это тулбар с несколькими кнопками ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 15:18 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Во-первых, таймеры должны быть привязаны к формам. Каждой отдельно взятой форме соответствует свой собственный таймер. Через классы это легко делается. Никакого ужаса. Т.е. открытие каждой формы сопровождается запуском таймера, расположенного на этой форме. Во-вторых, запуск процесса закрытия всех открытых форм сам по себе ничего не удаляет. Он только выставляет флаг - закрыть формы. Затем запускается таймер, который анализирует, во-первых, состояние флага (он может быть отменен в процессе закрытия какой-либо формы), а, во-вторых, количество открытых форм. Другими словами, невозможно сделать процесс закрытия всех форм "одноразовым" . Т.е. дать команду и тут же все закроется. Необходимо периодически проверять процесс закрытия. Выставили флаг и ждем. Через некоторое время проверям - есть флаг? Формы закрыты? Если флаг есть, а формы не закрыты, опять ждем. Через некоторое время опять проверяем - есть флаг? Формы закрыты? ... И так до тех пор пока флаг не окажется сброшенным или все формы не окажутся закрытыми. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 17:26 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
DimaT, а зачем каждый раз передергиваешь свойство таймера this.Interval = 10 Это лишнее. PS для запуска таймера надо использовать его свойство enabled Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 18:02 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Посмотри простой пример во вложении. Я поставил интервал в 5 секунд. Запускаешь main.prg и открываешь несколько вложенных модальных форм. Для закрытия всех форм нажимаешь кнопку Close в ToolBar и ждешь 5..10 секунд пока не появится сообщение о том, что все формы закрыты. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 18:27 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Galyamov Rinat DimaT, а зачем каждый раз передергиваешь свойство таймера this.Interval = 10 Это лишнее. PS для запуска таймера надо использовать его свойство enabled Не знал что enabled у таймера есть и работает, при Interval = 0 таймер не работает. По большому счету оба способа запуска/остановки равнозначны - объем кода одинаковый. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2008, 18:53 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Попробовал с одним таймером на тулбаре. Вроде работает. Только еще надо проверять лишние срабатывания таймера, а то полезный код может дважды отработать. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.08.2008, 09:04 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
спасибо большое всем за участие. но, честно говоря, задача так до конча и не решена. Как я уже не однократно писала, проблема в том, что помимо закрытия предыдущих форм, на этом тулбаре прописаны некие действия (это не кнопка закрыть), там может идти вызов какой-нибудь программы или формы и т.д. Так вот проблема заключается в том, что все формы кроме последней не МОГУТ быть закрыты пока не выполняться все действия на кнопке тулбара. А нужно перед выполнением этих действий сначало закрыть всё, что открыто к этому моменту, а потом выполнять некие действия. Например, открываем форму1, из нее форму2 и кликаем по кнопке тулбара, на которой прописано закрытие всех открытых к этому моменту форм и открытие некой формы3. И получается, что форма2 (последняя из двух открытых) закрывается корректно, а форма1 не может быть закрыта, т.к. выполняется код на кнопке тулбара и мы не можем завершить клик, на котором прописано открытие формы2. Т.е. открывается форма3 (поверх формы1), там что-то делается и когда мы закрываем форму3, происходит unload формы3, далее завершение действий на клике в форме1 и unload формы1. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.08.2008, 13:58 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
AnnaSPBно, честно говоря, задача так до конча и не решена. Нами задача решена до конца и полностью :) Внимательно перечитай что я и ВладимирМ предлагали и приложенные файлы позапускай. Прилагаю еще один пример (запускать main.prg). Добавил MessageBox() в Unload() чтобы понятно было что нужный код выполнится ПОСЛЕ закрытия всех форм. Смотри на порядок мессаджбоксов. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.08.2008, 14:26 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Dima T СПАСИБО! все понятно, это я уже туплю. работает все супер! Спасибо большое :) ... |
|||
:
Нравится:
Не нравится:
|
|||
15.08.2008, 14:43 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Жалко что закончисля этот флейм, но хочется всетаки добавить свои пять копеек... Эту проблему можно решить еще вот так, используя простые немодальные формы: 1.Запуская новую "модальную" форму устанавливаешь ей свойство AlwaysOnTop=.T., а у элементов запущеной до этого "модальной" формы ты просто выставляешь свойство Enabled=.F. и выключаешь свойство формы AlwaysOnTop=.F. 2.Перед запуском новой "модальной" формы нужна процедурка, которая бы искала предыдущию "модальную" форму и запоминала бы куда-нибудь ее имя 3.Когда ты закрываешь текущую "модальную" форму, ты востанавливаешь для запомненной предыдущей "модальной" формы свойство AlwaysOnTop=.T. Закрыть ты эти формы можешь в любое время простым скриптом FOR i01=1 TO _SCREEN.FORMCOUNT _SCREEN.FORMS(1).Release next i01 Как все это реализовать уже дело техники... ... |
|||
:
Нравится:
Не нравится:
|
|||
03.09.2008, 15:52 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
MikhailB Вы бы сначала данную тему почитали. Проблема именно в том, что закрытие перебором массива _SCREEN.Forms для более чем 2 одновременно открытых модальных форм - не всегда работает. Запоминать предыдущую форму нет никакой необходимости, поскольку индекс активной в данный момент формы автоматически устанавливается равным 1, а индексы всех прочих формы также автоматически "сдвигаются". Другими словами, активная в данный момент модальная форма всегда будет иметь индекс 1, а та модальная форма из которой ее вызвали всегда будет иметь индекс 2 в массиве _SCREEN.Forms. Разумеется, если вызов происходит из событий формы, а не через пункты меню или ToolBar. "Игры" с AlwaysOnTop в отношении модальных форм просто опасны. Вы можете получить "мертвое" зависание случайно вытащив на верх предыдущую форму. Переключится на активную модальную форму невозможно и закрыть вытащенную форму - тоже. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.09.2008, 16:49 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Спасибо, тему прочитал и ничего противоречивого ей в своем посте не нашел. Хочу только поправиться от вероятно возникшего недопонимания... В моем предыдущем сообщении под "модальной" формой, имется в виду простая немодальная форма. То есть при запуске новой формы которая должна быть якобы модальной, но таковой не является необходимо определить ей свойство AlwaysOnTop=.T., а у предыдущей "модальной" формы его сбросить AlwaysOnTop=.F. и установить Enabled=.F. Для того чтобы избежать коллизий для всех прочих запущеных "модальных" и немодальных форм мы должны каким-то образом установить их свойство Enabled=.F. тоже. В данном случае нет никакой опасности в "играх" с AlwaysOnTop, так как нет модальных форм. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2008, 14:35 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
MikhailBСпасибо, тему прочитал и ничего противоречивого ей в своем посте не нашел. ...так как нет модальных форм. Читай самый первый пост: AnnaSPB... последовательно одна из другой открываются формы ( все модальные )... Если уж хочется доказать свою правоту - возьми выше пример (мой или Владимира), замени код в кнопке на тулбаре на свой и продемонстрируй что все у тебя отлично работает. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2008, 14:54 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Внесу свою лепту в уже неактивный топик Таким образом можно закрыть несколько модальных форм: ФОРМА: 1 метод: init PUBLIC il as Integer il=0 метод: activate IF il=1 thisform.release ENDIF ФОРМА: 2 метод: activate IF il=1 thisform.release ENDIF ФОРМА: 3 кнопка: событие клик: il=1 thisform.Release Таким образом можем закрыть сколько угодно модальных форм! ... |
|||
:
Нравится:
Не нравится:
|
|||
26.05.2009, 17:17 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
К. АлександрВнесу свою лепту в уже неактивный топик Таким образом можно закрыть несколько модальных форм: ФОРМА: 1 метод: init PUBLIC il as Integer il=0 метод: activate IF il=1 thisform.release ENDIF ФОРМА: 2 метод: activate IF il=1 thisform.release ENDIF ФОРМА: 3 кнопка: событие клик: il=1 thisform.Release Таким образом можем закрыть сколько угодно модальных форм!Можно то можно... Но вот нужно ли так? 1. Так как уничтожение стоит в activate, то момента активизации формы она будет висеть на экране. 2. Где-то в программе присвоили il=1 для каких-то других целей и все формы посыпались при попытке их активизировать. Оно надо? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.05.2009, 17:32 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
проходящий., неужели фокс такой не предсказуемый, что может где то случайно присвоиться единица? ) ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2009, 17:26 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
К. Александрнеужели фокс такой не предсказуемый, что может где то случайно присвоиться единица? ) Причем здесь Fox? Вы хотя бы вспомните, что вы сами писали? Спотыкались буквально на ровном месте. И что предлагаете сейчас? Создать некую глобальную переменную, которая будет видна из любого места приложения. Вы вообще вспомните о ее существовании через пару недель такого кодинга? Вряд ли. Как следствие, полезут совершенно не предсказуемые ошибки, когда вы попытаетесь использовать переменную с тем же именем, но с другой целью. Глобальные переменные - это то, чего должно быть в программе как можно меньше. В идеале, вообще одна (глобальный объект с кучей свойств). Работа с такими переменными должна быть строжайше регламентирована. А это, в свою очередь, требует определенной самодисциплины от программиста. Нет программных средств контроля, как следствие, повышенный риск возникновения ошибок. Кроме того, модальные формы - это то, чего в программе также должно быть как можно меньше. Поэтому описанная иерархия модальных форм - это скорее исключение, чем правило. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2009, 17:48 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
ВладимирМ, простите, а почему в приложении должно быть как можно меньше модальных форм? я - новичок в VFP. Но почему -то мне казалось, что это очень удобный инструмент - посмотрим на винды. или вы предлагаете, как и всегда в фокспро, шаманить и танцевать с бубном, чтобы организовать подобный инструмент для ввода данных из обычной (немодальной) формы. И простой вопрос - как закрыть модальную форму по клику кнопки на этой форме? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2009, 18:18 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Zanderкак закрыть модальную форму по клику кнопки на этой форме? Zander, тремя постами выше кнопка.click() Код: plaintext 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2009, 20:12 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
tanglir, к сожалению, если бы было так просто, я бы не спрашивал... в каких случаях релиз не выполняется? форму создаю Код: plaintext 1. 2. 3.
кнопка есть, с обработчиком клика, она же Cancel=.T. ------------------- на самом деле, я решил проблему - кнопка мне вообщем-то не нужна, делаю по KeyPress Visible = .F. , а после делаю релиз. но все же... ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2009, 20:25 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
ZanderВладимирМ, простите, а почему в приложении должно быть как можно меньше модальных форм? я - новичок в VFP. Но почему -то мне казалось, что это очень удобный инструмент - посмотрим на винды. или вы предлагаете, как и всегда в фокспро, шаманить и танцевать с бубном, чтобы организовать подобный инструмент для ввода данных из обычной (немодальной) формы. Windows - это многозадачная система. Вы в любой момент можете переключится с одного приложения на другое (поэтому аргументация "посмотрим на винды" - не понятна). Любое достаточно сложное приложение строится точно также внутри себя. Т.е. в любой момент можно переключится в любой модуль этого приложения. Одновременно смотреть документы на приходы товара, на расходы, карточки контрагентов и карточки товаров. Да мало ли, что с чем надо сопоставить! Приложение ведь это не только ввод и модификация, но еще и сопоставление (сравнение) данных. Не на уровне сводных (статистических) отчетов, а на уровне отдельных документов. Модальность - это запрет подобного сопоставления. Другими словами, модальность оправдана тогда, когда вам необходимо запретить подобное сопоставление. Когда это может быть оправдано? Только тогда, когда изменяемая информация оказывает существенное влияние на все приложение. Например, некоторые глобальные настройки; ввод логина/пароля; выполнение служебных (административных) мероприятий и т.п. Однако обычно модальность используют при редактировании справочников или документов. Почему? Да потому, что так проще для программиста . Точнее, программисту кажется , что так проще! Правда, никто в этом не сознается . Обычно такую стратегию аргументируют "тупостью" пользователей или некой служебной необходимостью. В лучшем случае, говорят, что в процессе внесения модификаций нет необходимости смотреть что-то вне контекста данной формы. Т.е. косвенно все-таки соглашаются, что облегчают работу прежде всего себе. На самом деле, если просто расписать (перечислить) какие проблемы возникают, если отказаться от модальности при редактировании документов, оказывается, что все эти проблемы вполне преодолимы. И даже не очень большими усилиями. А вот использование модальности, как ни странно, приводит к сильному усложнению приложения в целом. С точки зрения пользователя, работать становится сложнее. Программисту приходится выдумывать разные хитроумные трюки для обхода им же сами наложенной модальности, чтобы удовлетворить потребности приложения. Отсюда и вывод: модальные формы - это инструмент для некоторых исключительных ситуаций. Как следствие, их не должно быть много. Хотя и совсем от них отказываться не стоит. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2009, 20:32 |
|
закрытие нескольких форм
|
|||
---|---|---|---|
#18+
Zandertanglir, к сожалению, если бы было так просто, я бы не спрашивал... в каких случаях релиз не выполняется? форму создаю Код: plaintext 1. 2. 3.
кнопка есть, с обработчиком клика, она же Cancel=.T. ------------------- на самом деле, я решил проблему - кнопка мне вообщем-то не нужна, делаю по KeyPress Visible = .F. , а после делаю релиз. но все же... Любой объект не может быть уничтожен, если: 1. Не завершился какой-либо метод этого объекта (например, где-то продублировали ThisForm.Show(1), что привело к "зависанию" того метода, где эта команда была дана) 2. Невозможно удалить ссылки на другие объекты, созданные внутри данного объекта (обычно результат "игр" с ActiveX-компонентами) Т.е. если ничто не мешает, то ThisForm.Release() нормально удаляет модальную форму. Раз этого не происходит, значит что-то мешает. Что-то у вас "висит" внутри формы. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.06.2009, 20:50 |
|
|
start [/forum/topic.php?all=1&fid=41&tid=1586371]: |
0ms |
get settings: |
12ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
38ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
111ms |
get tp. blocked users: |
1ms |
others: | 322ms |
total: | 516ms |
0 / 0 |