Форум: "Основная";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.03 c