Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.035 c
3-1092299304
Diman
2004-08-12 12:28
2004.09.05
Как RTF-файл открыть в DBGrid?


1-1092826286
Lizka
2004-08-18 14:51
2004.09.05
Ширина колонок у EhLibDBGrid


4-1089953351
Сергей Ю.
2004-07-16 08:49
2004.09.05
"Снятие" экрана


14-1092401872
Prohodil Mimo
2004-08-13 16:57
2004.09.05
Где найти справочник имён?


4-1090572558
Proger
2004-07-23 12:49
2004.09.05
Позиция курсора





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский