Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / закрытие нескольких форм / 25 сообщений из 59, страница 1 из 3
13.08.2008, 10:00
    #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
13.08.2008, 10:09
    #35484495
закрытие нескольких форм
2 AnnaSPB

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

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

если руками это делать,
то также передаете ссылку, кладете ее в св-во формы
и в нужно месте выполняете релиз формы-ссылки
...
Рейтинг: 0 / 0
13.08.2008, 10:09
    #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
13.08.2008, 10:16
    #35484515
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
я пробовала уже разные варианты, ничего не получается :(
Не закрывается только форма, в которой производились какие-то действия, такое ощущение, что где-то это прописывается и именно это и мешает.
...
Рейтинг: 0 / 0
13.08.2008, 10:22
    #35484530
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
пробовала и так через ActiveForm закрывать:
_screen.ActiveForm.release()
результат один и тот же - последняя из открытых форм закрывается, остальные нет
...
Рейтинг: 0 / 0
13.08.2008, 10:35
    #35484565
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
AnnaSPBя пробовала уже разные варианты, ничего не получается :(
Не закрывается только форма, в которой производились какие-то действия, такое ощущение, что где-то это прописывается и именно это и мешает.
Мешает то что формы модальные. Такой способ закрытия только для немодальных форм подходит. В твоем случае все модальные. Вот и закрывается только самая верхняя.
...
Рейтинг: 0 / 0
13.08.2008, 10:41
    #35484587
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
Dima T, спасибо. Я попробовала если формы немодальные, все получилось. Но проблема в том, что мне нужно. чтобы формы были модальными. как закрыть модальные окна с внешней кнопки?
...
Рейтинг: 0 / 0
13.08.2008, 10:46
    #35484608
закрытие нескольких форм
AnnaSPBDima T, спасибо. Я попробовала если формы немодальные, все получилось. Но проблема в том, что мне нужно. чтобы формы были модальными.
1. Хорошенько подумать, действительно ли это так. В подавляющем числе случаев это далеко не так при кажущейся необходимости.
как закрыть модальные окна с внешней кнопки?
2. Думать над порядком активизации форм при последовательном удалении форм. Может оказаться труднее первого варианта.
...
Рейтинг: 0 / 0
13.08.2008, 10:47
    #35484613
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
кстати, а почему тогда верхнее окно закрывалось? эта форма ведь тоже модальная
...
Рейтинг: 0 / 0
13.08.2008, 10:50
    #35484622
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
проходящий, мне тоже этот вариант не нравится и я уже столкнулась с массой проблем из-за этого, но не хотят люди понять этого! вот им так удобнее и все!
...
Рейтинг: 0 / 0
13.08.2008, 11:37
    #35484767
Samvel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
Раз окна модальные, значит можно закрыть только активную форму т.е последнюю?
...
Рейтинг: 0 / 0
13.08.2008, 11:45
    #35484789
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
так что нет способа закрыть окна, если они модальные?
...
Рейтинг: 0 / 0
13.08.2008, 11:51
    #35484812
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
AnnaSPBтак что нет способа закрыть окна, если они модальные?
Из одного места нет.
Каждая форма должна закрыть сама себя.
Например форма1 вызвала форму2 та форму3 и в форме 3 дали команду закрыть все формы:
Форма 3 должна как-то известить форму 2 (установить флаг глобальный или что-то вернуть) и закрыться
Форма 2 после "do form Форма3" должна проверить есть ли команда на закрытие и закрыться если есть и известить об этом форму 1
Форма 1 аналогично Форме 2
...
Рейтинг: 0 / 0
13.08.2008, 12:14
    #35484882
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
задача несколько иная - команда на закрытие форм дается не из одной из форм, а с внешней кнопки. Наблюдения такие:
1) если открыта одна форма - она закрывается без проблем;
2) если открыто две формы (форма1 -> форма2) - закрывается форма2, форма1 висит что не делаю;
3) если открыто 3 формы (форма1 -> форма2 -> форма3) - форма3 закрывается, остальные висят.

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

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

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

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

Я пробовала так. Релиз проходит, не ругается, но _SCREEN.FORMCOUNT все равно возвращает то же количество форм, как-будно он "не видит", что она закрылась. да и судя по объектам она действительно не закрылась
...
Рейтинг: 0 / 0
13.08.2008, 14:06
    #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
13.08.2008, 14:22
    #35485338
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
ВладимирМВот и получается, метод Hide() делает форму не модальной, но тот метод, в котором эта форма была вызвана не может завершиться, пока работает процедура с циклом закрытия форм. Нужно "пропихнуть" очередь накопившихся событий.
Приведенным кодом сменить порядок в очереди врядли не удасться. Надо тогда таймер задействовать чтобы он запускал код по мере освобождения очереди.
Тут обсуждали похожую проблему, только формы немодальные были.
...
Рейтинг: 0 / 0
13.08.2008, 15:06
    #35485496
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
Попробовала метод предложенный ВладимиромМ, получились не очень обнадеживающие результаты:
- во-первых, при таком алгоритме формы закрываются сначала, т.е. если запуск был форма1 -> форма2, то закрывается сначало форма1, а потом форма2. Но это исправить не проблема.
- проблема остается в том, что даже если закрываю формы в правильном порядке (форма2, форма1), то на форме1 не срабатывает метод unload и все открытые курсоры висят. Чего не хотелось бы.
- а при последовательном вызове 3 форм - на двух формах кроме последней не отрабатывает метод unload

В чем может быть причина?
...
Рейтинг: 0 / 0
13.08.2008, 15:53
    #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
13.08.2008, 16:30
    #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
13.08.2008, 16:43
    #35485822
AnnaSPB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
закрытие нескольких форм
ВладимирМ

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

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

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


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