![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Этот таинственный MessageBox... [D7]
Bless © (2006-10-10 10:21:00)Сперва приведу тестовый пример.
Итак, создаем новое приложение с двумя формами. На form1 бросаем кнопку и пишем обработчик OnClick:
procedure TForm1.Button1Click(Sender: TObject);
begin
form2 := tform2.create(self);
end;
У form2 есть такие обработчики:
procedure TForm2.FormCreate(Sender: TObject);
begin
try
raise Exception.Create('my exception');
except
PostMessage(handle, WM_CLOSE,0,0);
Windows.MessageBox(0, '11', '22', mb_ok); //!!!!!!!!!!!!!!!!!!!!!!!
end;{try}
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
action := caFree;
end;
Если поставить точку останова на выделенную строчку в TForm2.FormCreate и нажать f8, то меня заносит в обработчик TForm2.FormClose (!?!), после чего возвращает назад в TForm2.FormCreate (на последний end;). Почему это происходит?
Игорь Шевченко (2006-10-10 10:52:00) [21]Bless © (10.10.06 10:46) [3]
> Не совсем понимаю, что такое модальный message loop
Выборка из очереди потока сообщений, относящихся только к определенному окну. Поток-то один, в недрах MessageBox крутится цикл выборки сообщений, который больше никому не отдает управления.
Bless (2006-10-10 10:52:00) [22]Вдогонку [4]
Приложение-то однопоточное, я сейчас нахожусь в обработчике FormCreate. Каким образом меня вдруг закинуло в цикл обработки сообщений, а потом вернуло обратно?
Bless (2006-10-10 10:49:00) [23]
> Плохиш © (10.10.06 10:38) [2]
> Потому что происходит обработка оереди сообщений.
А как я в эту обработку тогда попал, не расскажешь?
Bless (2006-10-10 10:46:00) [24]
> ors_archangel © (10.10.06 10:34) [1]
Не совсем понимаю, что такое модальный message loop, но ты уверен, что он имеет какое-то отношение к Windows.MessageBox, к тому же с параметром hWnd (который Identifies the owner window) = 0?
То, что FormClose вызвался как результат обработки сообщения WM_CLOSE, это понятно.
Непонятно только, кто его сгенерировал.
Причем (тут я могу ошибаться, конечно), впечатление такое, что WM_CLOSE попало к Form2 не из очереди сообщений (такое впечатление сложилось потому, что в Application.ProcessMessages по F8 на выделенной строчке не попало, а ведь должно бы?), а через прямой вызов оконной процедуры (DispatchMessage?). Но кто этот вызов сделал, что-то не пойму.
Плохиш (2006-10-10 10:38:00) [25]
> Почему это происходит?
Потому что происходит обработка оереди сообщений.
ors_archangel (2006-10-10 10:34:00) [26]Думаю, появление MessageBox вызывает обработку сообщения WM_CLOSE (у него там модальный message loop, видимо) приложением, а так как мы трейсимся, то мы и трейсимся в WM_CLOSE-обработчик, но Делфи останавливается по Ф8 только на коде нашего проекта, поэтому мы попадаем, я так думаю, в FormClose. После присвоения в этом обработчике, сообщение WM_CLOSE мы больше не увидим (больше негде) и поэтому возвращаемся к коду FormCreate. Код FormCreate в блоке except по любому выполняется, даже если мы и присваиваем action = caFree, мы не убиваем этим форму (и тем более нить) сейчас же. Когда отлаживаешь multithread-проги, тоже весело бывает очень :)