Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Application.ProcessMessages, модальная форма и длительный цикл [D6, Win2k]


European ©   (2004-08-14 23:48:00) 

Здравствуйте, уважаемые! Есть 2 формы, одна из них модальная. После нажатия на кнопку на 2-ой форме начинает крутиться цикл. Внутри цикла стоит Application.ProcessMessages, обновление формы происходит, однако при закрытии обработка FormClose не происходит. Попытки закрыть форму штатными способами ни к чему не приводят. Что делать?
  Пробовал сделать тот же самый цикл в 1-ой (не модальной) форме – всё ОК. Проблема в модальности или где? Что-то я торможу. Кстати, потоки для решения не предлагать.


QuasiLamo   (2004-08-21 15:47:00) [1]


> European   (15.08.04 14:45) [12]

А зачем нужна модальность? Если для того, чтобы юзер случайно не перешел к первой форме, то можно ее просто задизэйблить.


TeNY   (2004-08-21 15:35:00) [2]

а что такое  поток?


European   (2004-08-15 14:45:00) [3]

Спасибо всем. Попробую сделать форму не модальной или перенесу код в поток.


Юрий Зотов   (2004-08-15 14:42:00) [4]

> European   (15.08.04 12:38) [7]

> Подскажите, пожалуйста, как можно выйти из такой ситуации.
Все же лучший выход - это второй поток.

> А если форма будет не модальной?
Тогда ProcessMessages обработает WM_SYSCOMMAND и в FormClose выставится флаг прерывания цикла.


TeNY   (2004-08-15 12:46:00) [5]

ксати твой код использует
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
которая вообще редко работает как нужно лычше использовать event
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);


TeNY   (2004-08-15 12:42:00) [6]

Я тоже встречался с подобной проблемой и при закрытии и  при других обстоятельствах к примеру при вставка Application.ProcessMessagesв функцию поиска если случайно нажать кнопку 2 раза то этот цикл будет выполнятся 2 раза на на кнопку закрыть не реагирует я решил это путем внедрения логической переменной
пример:
до

procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
for i:=1 to maxint do
  begin
    Application.ProcessMessages;
    Sleep(1);
  end
end;

на закрытие не реагирует запускается сколько угодно раз
после

 iRun:Boolean =False;
 iExit:Boolean =False;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
if not(iRun) then
begin
iRun:=True;
for i:=1 to maxint do
  begin
    if iExit then Exit;
    Application.ProcessMessages;
    Sleep(1);
  end;
  iRun:=false;
end else
MessageBoxA(Handle,'Уже запущено','<<<STOP>>>',0)
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
iExit:=true;
end;

а этот пример нормально реагирует на закрытие и остальное так же можно и останавливать процесс обработки.Правда постоянная проверка iExit может снижать производительность но на глаз и спомощью секундомера я этого не заметил :)


European   (2004-08-15 12:40:00) [7]


> sniknik ©   (15.08.04 10:55) [6]


> кстати Repaint; лишний по моему.


Да, Repaint, действительно лишний


European   (2004-08-15 12:38:00) [8]


> Юрий Зотов ©   (15.08.04 08:02) [5]

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


sniknik   (2004-08-15 10:55:00) [9]

> Поэтому Application.ProcessMessages ничего не дает
ну чегото он всетаки делает, потому как если повесить это на кнопку оно всетаки срабатывает
вместо FormClose, это
procedure TForm2. Button2Click(Sender: TObject);
begin
bCloseForm:=true;
Close;
end;

неохота лезть в код, но похоже там цикл просто с ограниченным обработчиком сообщенией (Close в него просто не попал, дописать? как решение)

(Delphi 7! на других возможно отличия)
кстати Repaint; лишний по моему.


Юрий Зотов   (2004-08-15 08:02:00) [10]

> European

Если посмотреть код ShowModal, то увидим, что там крутится собственный цикл выборки сообщений. Поэтому Application.ProcessMessages ничего не дает, а цикл repeat-until в Button1Click не дает обрабатывать сообщения и модальной форме Form2 тоже. В итоге FormClose не отрабатывает и цикл получается бесконечным.


Andy BitOff   (2004-08-15 02:04:00) [11]

А мне лично интересно ПОЧЕМУ, а не как это реализовать. Почему представленный код не отрабатывает правильно. Вроде код верный, за исключением объявления переменных, но будем считать, что они глобальные, а в остальном... Сам не проверял, но интересно.
Где знатоки, пусть объяснят.


Андрей007   (2004-08-15 01:25:00) [12]

А почему так принципиально делать цикл на второй форме, если на первой итак всё работает? Вы не ищете лёгких путей?


TUser   (2004-08-15 01:17:00) [13]

Испотзуй потоки. Весь расчет вынеси в отдельный поток.


European   (2004-08-14 23:48:00) [14]

Приведённый код отражает описанную выше проблему.

procedure TForm1.Button1Click(Sender: TObject);
begin
 Form2:=TForm2.Create(self);
 Form2.ShowModal;
 Form2.Free;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
 repeat
   inc(i);
   Label1.Caption:=IntToStr(i);
   Repaint;
   if i>100000 then i:=0;
   Application.ProcessMessages;  
 until (bCloseForm)
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 bCloseForm:=true;
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо