powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / закрытие нескольких форм
59 сообщений из 59, показаны все 3 страниц
закрытие нескольких форм
    #35484479
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброе утро!

Помогите пожалуйста разобраться! В окне имеется класс с кнопками ("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

В результате закрывается только последняя форма, а форма (или несколько) предыдущая остается открытой, но при этом никаких ошибок не выдается, все зацикливается и виснет.

Подскажите пожалуйста что я делаю не так.
Заранее благодарю
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484495
2 AnnaSPB

в фокспро есть
bindevents

в инит формы можно передать ссылку на предыдущую форму
и подписать событие

если руками это делать,
то также передаете ссылку, кладете ее в св-во формы
и в нужно месте выполняете релиз формы-ссылки
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484498
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
for x = _SCREEN.FORMCOUNT to  1  step - 1 
  IF !(ALLTRIM(UPPER(_SCREEN.FORMS(x).NAME))=="BUTTONS")
     _SCREEN.FORMS(x).RELEASE
   ENDIF
endif
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484515
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
я пробовала уже разные варианты, ничего не получается :(
Не закрывается только форма, в которой производились какие-то действия, такое ощущение, что где-то это прописывается и именно это и мешает.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484530
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
пробовала и так через ActiveForm закрывать:
_screen.ActiveForm.release()
результат один и тот же - последняя из открытых форм закрывается, остальные нет
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484565
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AnnaSPBя пробовала уже разные варианты, ничего не получается :(
Не закрывается только форма, в которой производились какие-то действия, такое ощущение, что где-то это прописывается и именно это и мешает.
Мешает то что формы модальные. Такой способ закрытия только для немодальных форм подходит. В твоем случае все модальные. Вот и закрывается только самая верхняя.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484587
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T, спасибо. Я попробовала если формы немодальные, все получилось. Но проблема в том, что мне нужно. чтобы формы были модальными. как закрыть модальные окна с внешней кнопки?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484608
AnnaSPBDima T, спасибо. Я попробовала если формы немодальные, все получилось. Но проблема в том, что мне нужно. чтобы формы были модальными.
1. Хорошенько подумать, действительно ли это так. В подавляющем числе случаев это далеко не так при кажущейся необходимости.
как закрыть модальные окна с внешней кнопки?
2. Думать над порядком активизации форм при последовательном удалении форм. Может оказаться труднее первого варианта.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484613
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
кстати, а почему тогда верхнее окно закрывалось? эта форма ведь тоже модальная
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484622
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
проходящий, мне тоже этот вариант не нравится и я уже столкнулась с массой проблем из-за этого, но не хотят люди понять этого! вот им так удобнее и все!
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484767
Samvel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Раз окна модальные, значит можно закрыть только активную форму т.е последнюю?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484789
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
так что нет способа закрыть окна, если они модальные?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484812
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AnnaSPBтак что нет способа закрыть окна, если они модальные?
Из одного места нет.
Каждая форма должна закрыть сама себя.
Например форма1 вызвала форму2 та форму3 и в форме 3 дали команду закрыть все формы:
Форма 3 должна как-то известить форму 2 (установить флаг глобальный или что-то вернуть) и закрыться
Форма 2 после "do form Форма3" должна проверить есть ли команда на закрытие и закрыться если есть и известить об этом форму 1
Форма 1 аналогично Форме 2
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484882
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
задача несколько иная - команда на закрытие форм дается не из одной из форм, а с внешней кнопки. Наблюдения такие:
1) если открыта одна форма - она закрывается без проблем;
2) если открыто две формы (форма1 -> форма2) - закрывается форма2, форма1 висит что не делаю;
3) если открыто 3 формы (форма1 -> форма2 -> форма3) - форма3 закрывается, остальные висят.

Может есть какой-нибудь признак, свойство, незнаю.... что-то, что ставится глобально в VFP и не дает закрыть форму?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484960
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AnnaSPBМожет есть какой-нибудь признак, свойство, незнаю.... что-то, что ставится глобально в VFP и не дает закрыть форму?
Есть Form.WindowType = 1 (Modal) оно и не дает.

Если это кнопка "Выход" то выдай сообщение "Закройте все окошки" и все.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35484993
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
это идея! спасибо! :)
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485212
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Форма остается модальной до тех пор пока она видима. Если форму сделать невидимой (скрытой), то она теряет модальность. Поэтому можно чуть-чуть изменить код.

Код: plaintext
1.
2.
_SCREEN.FORMS(x).Hide()
_SCREEN.FORMS(x).RELEASE()

Хотя, в общем случае, процесс закрытия всех открытых форм не такой простой как может показаться. Тут много "подводных камней" и в общем случае эта задача не решается. Каждое решение является "частным случаем". Под конкретное приложение.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485235
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВладимирМ

Я пробовала так. Релиз проходит, не ругается, но _SCREEN.FORMCOUNT все равно возвращает то же количество форм, как-будно он "не видит", что она закрылась. да и судя по объектам она действительно не закрылась
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485290
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разумеется. Ведь проблема еще в том, что форма не может быть закрыта пока не завершится метод этой формы. А вызов подчиненных форм, вероятно, происходит из каких-то методов главной формы (по нажатию кнопки, например).

Вот и получается, метод Hide() делает форму не модальной, но тот метод, в котором эта форма была вызвана не может завершиться, пока работает процедура с циклом закрытия форм. Нужно "пропихнуть" очередь накопившихся событий.

Простейший вариант - это вынести две эти команды в отдельную процедуру или метод

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
For x = _SCREEN.FORMCOUNT to  1  step - 1 
	IF !(ALLTRIM(UPPER(_SCREEN.FORMS(x).NAME))=="BUTTONS")
		DO FormRelease WITH x
		* Здесь еще можно попробовать организовать задержку
		*=InKey( 0 . 1 )
	ENDIF
EndFor

PROCEDURE FormRelease
LPARAMETERS nIndex

	_SCREEN.Forms(m.nIndex).Hide()
	_SCREEN.Forms(m.nIndex).Release()
RETURN
ENDPROC

Здесь "фишка" в том, что процедура - это отдельный модуль в стеке (очереди) процессов на исполнение. Соответственно, он будет иметь определенный приоритет и есть вероятность, что перед очередным шагом цикла он пропустит перед собой процедуру завершения того метода в котором была вызвана модальная форма.

Хотя, повторюсь. Без гарантий. Это может сработать, но может и НЕ сработать. При определенных условиях.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485338
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМВот и получается, метод Hide() делает форму не модальной, но тот метод, в котором эта форма была вызвана не может завершиться, пока работает процедура с циклом закрытия форм. Нужно "пропихнуть" очередь накопившихся событий.
Приведенным кодом сменить порядок в очереди врядли не удасться. Надо тогда таймер задействовать чтобы он запускал код по мере освобождения очереди.
Тут обсуждали похожую проблему, только формы немодальные были.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485496
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовала метод предложенный ВладимиромМ, получились не очень обнадеживающие результаты:
- во-первых, при таком алгоритме формы закрываются сначала, т.е. если запуск был форма1 -> форма2, то закрывается сначало форма1, а потом форма2. Но это исправить не проблема.
- проблема остается в том, что даже если закрываю формы в правильном порядке (форма2, форма1), то на форме1 не срабатывает метод unload и все открытые курсоры висят. Чего не хотелось бы.
- а при последовательном вызове 3 форм - на двух формах кроме последней не отрабатывает метод unload

В чем может быть причина?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485664
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может кому-нибудь поможет...
У меня решилась проблема таким образом:

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.
Вроде работает стабильно.

Спасибо всем за участие
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485784
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Повторюсь.

Форма не может быть закрыта, пока выполняется какой-либо ее метод или событие или существуют внешние ссылки на эту форму.

Раз форма не закрывается (не выполняется 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.
DO HideForm
DO ReleaseForm

* Все формы делаются невидимыми
PROCEDURE HideForm
LOCAL loForm
IF _SCREEN.FormCount >  0 
	For each loForm in _SCREEN.forms
		loForm.Hide()
	endfor
ENDIF

RETURN
ENDPROC

* Все формы удаляются
* При этом предполагается, что они уже невидимы
PROCEDURE ReleaseForm
LOCAL loForm
IF _SCREEN.FormCount >  0 
	For each loForm in _SCREEN.forms
		loForm.Release()
	endfor
ENDIF

RETURN
ENDPROC

Хотя опять же нет никакой гарантии, что этого окажется достаточно.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485822
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВладимирМ

Да, Вы правы, к сожалению, правы :( И в этом я убедилась, когда стала как следует тестировать все это. То что я сделала оказалось мало. Попробую сделать две разные процедуры. Подумаю может еще что-нибудь "умное" придет в голову.

Если есть какие-то соображения, пожалуйста пишите
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35485961
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Этого оказалось не достаточно. Не закрывается форма, из которой была вызвана другая форма, не отрабатывает Unload, все равно держит его что-то. И _screen.FormCount возвращает 2, и курсоры открыты.

Может есть какие-нибудь мысли по этому поводу? Как это обойти?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35486019
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дело в том, что у формы должен быть свой собственный метод, который обеспечивает коррекное закрытие этой и именно этой формы. Ну, например, при закрытии некоторой формы возникает дополнительный запрос на какие-либо дополнительные модификации.

При этом, есть различие "штатного" закрытия (самим пользователем) и "аварийного" (по нажатию на крестик в правом верхнем углу приложения).

Лично у меня, вызов этого метода по закрытию формы происходит из штатного метода Form.QueryUnload.

Например, на форме есть кнопка "Выход" в событии Click() которой и прописано закрытие формы (после соответсвующих проверок дается команда ThisForm.Release()). Тогда в событии Form.QueryUnload() будет примерно такой код

Код: plaintext
1.
2.
3.
*Form.QueryUnload()
NODEFAULT
ThisForm.CmdExit.Click()

Соответственно, метод по закрытию всех открытых форм заключается не в вызове события Release() форм, а в вызове события QueryUnload() которое и берет на себя всю работу по корректному закрытию формы.

При этом надо учитывать последовательность форм. Т.е. закрывать формы в "правильном" порядке. Начиная с самой последней. В коллекции _SCREEN.Forms() самая последняя открытая форма имеет индекс 1, предпоследняя - 2 и т.д. Т.е. закрывать надо всегда 1 форму, поскольку после закрытия первой формы индекс 1 получит та, которая была второй.

Код: plaintext
1.
2.
3.
4.
FOR lnI =  1  TO _SCREEN.FormCount
	* Индекс ВСЕГДА  1 , а не значение счетчика
	_SCREEN.Forms( 1 ).QueryUnload()
ENDFOR

Но в этом случае есть опасность зацикливания, если форма по каким-то причинам не может быть закрыта. Точнее, не зацикливания, а нескольких попыток закрытия только одной формы, не закрывая все остальные.

В общем, вот один из вариантов, который, впрочем, тоже ничего не гарантирует

Код: 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.
* Данный метод предпринимает попытку закрыть ВСЕ формы текущего проект
* В случае успеха возвращает .T. и .F. в случае неудачи.

LOCAL IsDoing, loForm, lnHideForms, lnFormSet, lcOnError
*!* Для отладки
*!*	lcOnError = ON("ERROR")
*!*	ON ERROR *		&& подавляю выдачу сообщений об ошибках
IsDoing = .T.
lnHideForms =  0 
lnFormSet =  0 
DO WHILE _SCREEN.FormCount>m.lnHideForms AND m.IsDoing=.T.
	lnCount=_SCREEN.FormCount		&& запоминаю количество существующих форм
	loForm=_SCREEN.Forms( 1 +m.lnHideForms+m.lnFormSet)
	
	* В моих проектах закрытию ЛЮБОЙ формы можно вызвать из метода QueryUnload
	m.loForm.QueryUnload()

	* Если форма успешно удалилась, то переменная loForm должна принять значение NULL
	IF TYPE('m.loForm')='O' AND IsNull(m.loForm)=.F. 
		* Т.е. форма не удалилась
		IF loForm.Visible=.T.
			* Если форма не удалилась и осталась видимой - это значит
			* что в результате диалога с пользователем было решено прервать выход
			IsDoing=.F.
		ELSE
			* Это на случай существования FormSet, когда дочернии
			* формы не удаляются, а лишь делаются невидимыми
			DEACTIVATE WINDOW (m.loForm.Name)
			lnFormSet = m.lnFormSet +  1 
		ENDIF
	ELSE
		lnFormSet =  0 
		IF m.lnCount = _SCREEN.FormCount
			* т.е. это как раз тот случай, когда форма хотя и удалилась,
			* но осталась в памяти из-за не завершенного метода
			lnHideForms = m.lnHideForms+ 1 
		ENDIF
	ENDIF

ENDDO

*!*	ON ERROR &lcOnError

RETURN (_SCREEN.FormCount=m.lnHideForms)
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35486597
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВладимирМ

спасибо большое за участие. Я попробовала сделать как Вы написали, но, к сожалению, все тоже самое: форма2 закрывается, проходит unload, а на форме1 нет. :(
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35486616
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может я не права, но мне вот еще что не понятно: ведь в последней форме (форма2) отрабатывает закрытие формы по всем правилам (т.е. release, unload), значит вводе как мы должны вернуться в метод откуда было открытие формы (например, клик по кнопке) и закончить его, а потом уже все остальные действия (если таковые имеются). Разве нет?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35486926
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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(), а через методы, которые прежде, чем дать команду на закрытие проверят, а можно ли вообще закрыть форму.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35486964
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВладимирМ

Да я в этом уже убедилась. Я пробовала сделать как Вы рекомендовали, через QueryUnload(), но получила тотже результат. Я уже просто и не знаю что можно с этим сделать!?! И вообще можно ли с этим как-то бороться?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35487028
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
QueryUnload() - это один из вариантов. Смысл-то не в каком-то методе, а в его НАПОЛНЕНИИ. Что там внутри записано.

Как один из вариантов решения - запустить процесс самозакрытия форм через объекты-таймеры.

Т.е. на каждой форме есть объект-таймер. Который с некоторой периодичностью просматривает содержимое некой служебной таблички. Если в этой табличке выставлен некий флаг (значение поля), то этот таймер дает команду на закрытие данной, текущей формы. "По быстрому" это можно сделать не через поле таблицы, а через глобальную переменную. Хотя таблица рано или поздно все-равно понадобиться.

Если из метода формы вызывается модальная форма, то перед вызовом модальной формы этот таймер отключается и включается только после закрытия модальной формы. Ну, примерно так:

Код: plaintext
1.
2.
3.
ThisForm.TmrAutoClose.Enabled = .F.
DO FORM ChildModalForm.scx
ThisForm.TmrAutoClose.Enabled = .T.

Объект TmrAutoClose - это как раз этот таймер автозакрытия.

Тогда процесс закрытия всех открытых форм будет заключаться просто в установке флага в этой служебной таблице (или изменение занчения глобальной переменной) и запуск другого таймера, который периодически будет проверять есть ли сейчас открытые формы. Если ни одной открытой формы не осталось, то этот таймер закрывает приложение.

Обработка выполняется через таймеры именно для того, чтобы все процессы по автозакрытию форм отработали в нужной последовательности. Чтобы не возникло проблем с очередями процессов.

Да, разумеется, выставление флага блокирует открытие новых форм.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35487183
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
да это же УЖАС! В каждой форме писать обработку по таймеру, организация таблиц... а если форм в проекте десятки??? К тому же насколько я в курсе таймер "не очень хорошо" ладит с модальными формами, а в моем случае формы модальные. Замкнутый круг какой-то.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35487235
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AnnaSPBда это же УЖАС! В каждой форме писать обработку по таймеру, организация таблиц... а если форм в проекте десятки??? К тому же насколько я в курсе таймер "не очень хорошо" ладит с модальными формами, а в моем случае формы модальные. Замкнутый круг какой-то.

Для этого надо наследовать свою форму от некоторого базового класса, в которую и поместить всю общую для всех форм функциональность.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35487633
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовала закрыть формы с использованием таймеров.
На двух формах, последовательно вызываемых друг из друга поместила таймеры, которые следять за переменной lCloseFormAll, и если она равна true, закрывают форму.
На внешней кнопке такой код:
For x = _SCREEN.FORMCOUNT to 1 step -1
IF !(ALLTRIM(UPPER(_SCREEN.FORMS(x).NAME))=="BUTTONS")
lCloseFormAll = .T.
ENDIF
EndFor

* выполнение неких действий
...
...
...

Результаты аналогичные: первая форма закрывается, вторая нет.
В общем то это и логично, управление в первую форму не возвращается. Продолжают выполняться действия на внешней кнопке (при этом форма 1 не закрыта). А вот после выполнения всех действий на внешней кнопке, возвращается управление на форму 1, срабатывает таймер и форма закрывается.
Но задача стоит перед выполнением действий на форме предварительно закрыть ВСЕ открытые формы.
Посоветуйте пожалуйста как можно этого добиться?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35487712
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
proc Кнопка.Click()
lCloseFormAll = .T.
Timer.Interval =  10 
return

proc Timer.Timer()
this.Interval =  0 
For x = _SCREEN.FORMCOUNT to  1  step - 1 
   IF !(ALLTRIM(UPPER(_SCREEN.FORMS(x).NAME))=="BUTTONS")
      * Есть еще формы, ждем дальше
      this.Interval =  10 
      return
   ENDIF
EndFor

* выполнение неких действий
...
...
...
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35487723
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если формы хоть по одной но закрываются, то можно одним таймером попробовать обойтись. Там же где и кнопка:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
proc Кнопка.Click()
Timer.Interval =  10 
return

proc Timer.Timer()
this.Interval =  0 
llFormOpen = .F.
For x = _SCREEN.FORMCOUNT to  1  step - 1 
   IF !(ALLTRIM(UPPER(_SCREEN.FORMS(x).NAME))=="BUTTONS")
      * Есть еще формы, ждем дальше
      llFormOpen = .T.
      _SCREEN.FORMS(x).Hide()
      _SCREEN.FORMS(x).Release()
   ENDIF
EndFor

if llFormOpen
      this.Interval =  10 
      return
endif
* выполнение неких действий
...
...
...
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35487731
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
кнопка находится не на форме, это тулбар с несколькими кнопками
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35487826
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
кнопка находится не на форме, это тулбар с несколькими кнопками
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35488211
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во-первых, таймеры должны быть привязаны к формам. Каждой отдельно взятой форме соответствует свой собственный таймер. Через классы это легко делается. Никакого ужаса.

Т.е. открытие каждой формы сопровождается запуском таймера, расположенного на этой форме.

Во-вторых, запуск процесса закрытия всех открытых форм сам по себе ничего не удаляет. Он только выставляет флаг - закрыть формы. Затем запускается таймер, который анализирует, во-первых, состояние флага (он может быть отменен в процессе закрытия какой-либо формы), а, во-вторых, количество открытых форм.

Другими словами, невозможно сделать процесс закрытия всех форм "одноразовым" . Т.е. дать команду и тут же все закроется. Необходимо периодически проверять процесс закрытия.

Выставили флаг и ждем. Через некоторое время проверям - есть флаг? Формы закрыты? Если флаг есть, а формы не закрыты, опять ждем. Через некоторое время опять проверяем - есть флаг? Формы закрыты? ...

И так до тех пор пока флаг не окажется сброшенным или все формы не окажутся закрытыми.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35488328
Galyamov Rinat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaT, а зачем каждый раз передергиваешь свойство таймера this.Interval = 10


Это лишнее.

PS для запуска таймера надо использовать его свойство enabled


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35488396
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотри простой пример во вложении. Я поставил интервал в 5 секунд. Запускаешь main.prg и открываешь несколько вложенных модальных форм. Для закрытия всех форм нажимаешь кнопку Close в ToolBar и ждешь 5..10 секунд пока не появится сообщение о том, что все формы закрыты.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35488444
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Galyamov Rinat
DimaT, а зачем каждый раз передергиваешь свойство таймера this.Interval = 10
Это лишнее.

PS для запуска таймера надо использовать его свойство enabled

Не знал что enabled у таймера есть и работает, при Interval = 0 таймер не работает. По большому счету оба способа запуска/остановки равнозначны - объем кода одинаковый.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35488845
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал с одним таймером на тулбаре. Вроде работает.
Только еще надо проверять лишние срабатывания таймера, а то полезный код может дважды отработать.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35489754
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
спасибо большое всем за участие.

но, честно говоря, задача так до конча и не решена.
Как я уже не однократно писала, проблема в том, что помимо закрытия предыдущих форм, на этом тулбаре прописаны некие действия (это не кнопка закрыть), там может идти вызов какой-нибудь программы или формы и т.д. Так вот проблема заключается в том, что все формы кроме последней не МОГУТ быть закрыты пока не выполняться все действия на кнопке тулбара. А нужно перед выполнением этих действий сначало закрыть всё, что открыто к этому моменту, а потом выполнять некие действия.
Например, открываем форму1, из нее форму2 и кликаем по кнопке тулбара, на которой прописано закрытие всех открытых к этому моменту форм и открытие некой формы3. И получается, что форма2 (последняя из двух открытых) закрывается корректно, а форма1 не может быть закрыта, т.к. выполняется код на кнопке тулбара и мы не можем завершить клик, на котором прописано открытие формы2. Т.е. открывается форма3 (поверх формы1), там что-то делается и когда мы закрываем форму3, происходит unload формы3, далее завершение действий на клике в форме1 и unload формы1.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35489859
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AnnaSPBно, честно говоря, задача так до конча и не решена.

Нами задача решена до конца и полностью :)

Внимательно перечитай что я и ВладимирМ предлагали и приложенные файлы позапускай.

Прилагаю еще один пример (запускать main.prg). Добавил MessageBox() в Unload() чтобы понятно было что нужный код выполнится ПОСЛЕ закрытия всех форм. Смотри на порядок мессаджбоксов.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35489918
AnnaSPB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T

СПАСИБО! все понятно, это я уже туплю. работает все супер!

Спасибо большое :)
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35520697
MikhailB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Жалко что закончисля этот флейм, но хочется всетаки добавить свои пять копеек...


Эту проблему можно решить еще вот так, используя простые немодальные формы:

1.Запуская новую "модальную" форму устанавливаешь ей свойство AlwaysOnTop=.T., а у элементов запущеной до этого "модальной" формы ты просто выставляешь свойство Enabled=.F.
и выключаешь свойство формы AlwaysOnTop=.F.

2.Перед запуском новой "модальной" формы нужна процедурка, которая бы искала предыдущию "модальную" форму и запоминала бы куда-нибудь ее имя

3.Когда ты закрываешь текущую "модальную" форму, ты востанавливаешь для запомненной предыдущей "модальной" формы свойство AlwaysOnTop=.T.


Закрыть ты эти формы можешь в любое время простым скриптом

FOR i01=1 TO _SCREEN.FORMCOUNT
_SCREEN.FORMS(1).Release
next i01

Как все это реализовать уже дело техники...
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35520903
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MikhailB

Вы бы сначала данную тему почитали. Проблема именно в том, что закрытие перебором массива _SCREEN.Forms для более чем 2 одновременно открытых модальных форм - не всегда работает.

Запоминать предыдущую форму нет никакой необходимости, поскольку индекс активной в данный момент формы автоматически устанавливается равным 1, а индексы всех прочих формы также автоматически "сдвигаются".

Другими словами, активная в данный момент модальная форма всегда будет иметь индекс 1, а та модальная форма из которой ее вызвали всегда будет иметь индекс 2 в массиве _SCREEN.Forms. Разумеется, если вызов происходит из событий формы, а не через пункты меню или ToolBar.

"Игры" с AlwaysOnTop в отношении модальных форм просто опасны. Вы можете получить "мертвое" зависание случайно вытащив на верх предыдущую форму. Переключится на активную модальную форму невозможно и закрыть вытащенную форму - тоже.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35522570
MikhailB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, тему прочитал и ничего противоречивого ей в своем посте не нашел.

Хочу только поправиться от вероятно возникшего недопонимания...

В моем предыдущем сообщении под "модальной" формой, имется в виду простая немодальная форма.
То есть при запуске новой формы которая должна быть якобы модальной, но таковой не является необходимо определить ей свойство AlwaysOnTop=.T., а у предыдущей "модальной" формы его сбросить AlwaysOnTop=.F. и установить Enabled=.F.

Для того чтобы избежать коллизий для всех прочих запущеных "модальных" и немодальных форм мы должны каким-то образом установить их свойство Enabled=.F. тоже.

В данном случае нет никакой опасности в "играх" с AlwaysOnTop, так как нет модальных форм.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #35522669
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MikhailBСпасибо, тему прочитал и ничего противоречивого ей в своем посте не нашел.

...так как нет модальных форм.

Читай самый первый пост:
AnnaSPB... последовательно одна из другой открываются формы ( все модальные )...

Если уж хочется доказать свою правоту - возьми выше пример (мой или Владимира), замени код в кнопке на тулбаре на свой и продемонстрируй что все у тебя отлично работает.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36008669
Внесу свою лепту в уже неактивный топик
Таким образом можно закрыть несколько модальных форм:

ФОРМА: 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

Таким образом можем закрыть сколько угодно модальных форм!
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36008710
К. АлександрВнесу свою лепту в уже неактивный топик
Таким образом можно закрыть несколько модальных форм:

ФОРМА: 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 для каких-то других целей и все формы посыпались при попытке их активизировать. Оно надо?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36011454
проходящий.,

неужели фокс такой не предсказуемый, что может где то случайно присвоиться единица? )
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36011522
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К. Александрнеужели фокс такой не предсказуемый, что может где то случайно присвоиться единица? )
Причем здесь Fox? Вы хотя бы вспомните, что вы сами писали? Спотыкались буквально на ровном месте.

И что предлагаете сейчас? Создать некую глобальную переменную, которая будет видна из любого места приложения. Вы вообще вспомните о ее существовании через пару недель такого кодинга? Вряд ли. Как следствие, полезут совершенно не предсказуемые ошибки, когда вы попытаетесь использовать переменную с тем же именем, но с другой целью.

Глобальные переменные - это то, чего должно быть в программе как можно меньше. В идеале, вообще одна (глобальный объект с кучей свойств). Работа с такими переменными должна быть строжайше регламентирована. А это, в свою очередь, требует определенной самодисциплины от программиста. Нет программных средств контроля, как следствие, повышенный риск возникновения ошибок.

Кроме того, модальные формы - это то, чего в программе также должно быть как можно меньше. Поэтому описанная иерархия модальных форм - это скорее исключение, чем правило.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36024293
Zander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВладимирМ,

простите, а почему в приложении должно быть как можно меньше модальных форм?
я - новичок в VFP. Но почему -то мне казалось, что это очень удобный инструмент - посмотрим на винды. или вы предлагаете, как и всегда в фокспро, шаманить и танцевать с бубном, чтобы организовать подобный инструмент для ввода данных из обычной (немодальной) формы.

И простой вопрос - как закрыть модальную форму по клику кнопки на этой форме?
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36024438
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zanderкак закрыть модальную форму по клику кнопки на этой форме?
Zander,
тремя постами выше
кнопка.click()
Код: plaintext
1.
thisform.release()
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36024448
Zander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglir,

к сожалению, если бы было так просто, я бы не спрашивал...
в каких случаях релиз не выполняется?
форму создаю
Код: plaintext
1.
2.
3.
oEditForm = CREATEOBJECT(EditForm)
...
oEditForm.Show( 1 )   && вызываю как модальную 

кнопка есть, с обработчиком клика, она же Cancel=.T.

-------------------
на самом деле, я решил проблему - кнопка мне вообщем-то не нужна, делаю по KeyPress Visible = .F. , а после делаю релиз.

но все же...
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36024461
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZanderВладимирМ,

простите, а почему в приложении должно быть как можно меньше модальных форм?
я - новичок в VFP. Но почему -то мне казалось, что это очень удобный инструмент - посмотрим на винды. или вы предлагаете, как и всегда в фокспро, шаманить и танцевать с бубном, чтобы организовать подобный инструмент для ввода данных из обычной (немодальной) формы.
Windows - это многозадачная система. Вы в любой момент можете переключится с одного приложения на другое (поэтому аргументация "посмотрим на винды" - не понятна).

Любое достаточно сложное приложение строится точно также внутри себя. Т.е. в любой момент можно переключится в любой модуль этого приложения. Одновременно смотреть документы на приходы товара, на расходы, карточки контрагентов и карточки товаров. Да мало ли, что с чем надо сопоставить!

Приложение ведь это не только ввод и модификация, но еще и сопоставление (сравнение) данных. Не на уровне сводных (статистических) отчетов, а на уровне отдельных документов. Модальность - это запрет подобного сопоставления.

Другими словами, модальность оправдана тогда, когда вам необходимо запретить подобное сопоставление. Когда это может быть оправдано? Только тогда, когда изменяемая информация оказывает существенное влияние на все приложение. Например, некоторые глобальные настройки; ввод логина/пароля; выполнение служебных (административных) мероприятий и т.п.

Однако обычно модальность используют при редактировании справочников или документов. Почему? Да потому, что так проще для программиста . Точнее, программисту кажется , что так проще!

Правда, никто в этом не сознается . Обычно такую стратегию аргументируют "тупостью" пользователей или некой служебной необходимостью. В лучшем случае, говорят, что в процессе внесения модификаций нет необходимости смотреть что-то вне контекста данной формы. Т.е. косвенно все-таки соглашаются, что облегчают работу прежде всего себе.

На самом деле, если просто расписать (перечислить) какие проблемы возникают, если отказаться от модальности при редактировании документов, оказывается, что все эти проблемы вполне преодолимы. И даже не очень большими усилиями.

А вот использование модальности, как ни странно, приводит к сильному усложнению приложения в целом. С точки зрения пользователя, работать становится сложнее. Программисту приходится выдумывать разные хитроумные трюки для обхода им же сами наложенной модальности, чтобы удовлетворить потребности приложения.

Отсюда и вывод: модальные формы - это инструмент для некоторых исключительных ситуаций. Как следствие, их не должно быть много. Хотя и совсем от них отказываться не стоит.
...
Рейтинг: 0 / 0
закрытие нескольких форм
    #36024475
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zandertanglir,

к сожалению, если бы было так просто, я бы не спрашивал...
в каких случаях релиз не выполняется?
форму создаю
Код: plaintext
1.
2.
3.
oEditForm = CREATEOBJECT(EditForm)
...
oEditForm.Show( 1 )   && вызываю как модальную 

кнопка есть, с обработчиком клика, она же Cancel=.T.

-------------------
на самом деле, я решил проблему - кнопка мне вообщем-то не нужна, делаю по KeyPress Visible = .F. , а после делаю релиз.

но все же...
Любой объект не может быть уничтожен, если:

1. Не завершился какой-либо метод этого объекта (например, где-то продублировали ThisForm.Show(1), что привело к "зависанию" того метода, где эта команда была дана)

2. Невозможно удалить ссылки на другие объекты, созданные внутри данного объекта (обычно результат "игр" с ActiveX-компонентами)

Т.е. если ничто не мешает, то ThisForm.Release() нормально удаляет модальную форму. Раз этого не происходит, значит что-то мешает. Что-то у вас "висит" внутри формы.
...
Рейтинг: 0 / 0
59 сообщений из 59, показаны все 3 страниц
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / закрытие нескольких форм
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]