Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.05;
Скачать: CL | DM;

Вниз

Application.ProcessMessages, модальная форма и длительный цикл   Найти похожие ветки 

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

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


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

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

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;


 
TUser ©   (2004-08-15 01:17) [2]

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


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

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


 
Andy BitOff ©   (2004-08-15 02:04) [4]

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


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

> European

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


 
sniknik ©   (2004-08-15 10:55) [6]

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

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

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


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


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

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


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


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


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


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


 
TeNY ©   (2004-08-15 12:42) [9]

Я тоже встречался с подобной проблемой и при закрытии и  при других обстоятельствах к примеру при вставка 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 может снижать производительность но на глаз и спомощью секундомера я этого не заметил :)


 
TeNY ©   (2004-08-15 12:46) [10]

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


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

> European   (15.08.04 12:38) [7]

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

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


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

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


 
TeNY ©   (2004-08-21 15:35) [13]

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


 
QuasiLamo ©   (2004-08-21 15:47) [14]


> European   (15.08.04 14:45) [12]

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



Страницы: 1 вся ветка

Текущий архив: 2004.09.05;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.036 c
3-1092223644
DmitryMN
2004-08-11 15:27
2004.09.05
Ошибка в UDF


1-1092735261
Aleksandr.
2004-08-17 13:34
2004.09.05
Непонятная утечка памяти


14-1092582660
Дмитрий12
2004-08-15 19:11
2004.09.05
Пожалуйста, помогите перевести код на C++:


1-1092988683
tp
2004-08-20 11:58
2004.09.05
DLL


1-1092998820
Jiuraasdasd
2004-08-20 14:47
2004.09.05
Как создать собственный тип данных?