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

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

Этот таинственный MessageBox... [D7]


Страницы:   1 2

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;). Почему это происходит?


Bless   (2006-10-10 17:14:00) [1]

Да, чуть не забыл.
Спасибо :)


Bless   (2006-10-10 17:13:00) [2]


> han_malign ©   (10.10.06 12:02) [20]
> > Где об этом можно четко прочитать?
>
> Help->MessageBox->Flags: MB_APPLMODAL/MB_SYSTEMMODAL/MB_TASKMODAL


Что-то я здесь не нашел информации о том, какие сообщения обрабатываются внутри MessageBox.


> default ©   (10.10.06 12:31) [22]
> у тебя MessageBox вызывается немодально, поэтому ведётся
> обработка сообщений для всех окон и потому WM_CLOSE главного
> окна и обрабатывается


Даже если я вызову его немодально, WM_CLOSE все-равно обработается.

Видимо, в [11] я угадал правильно (точнее не угадал, а переспросил сказанное в [6]). Внутри MessageBox, похоже, действительно организован свой собственный цикл выборки сообщений, который и вызвал обработчик WM_CLOSE.


default   (2006-10-10 12:49:00) [3]


> "пропускаются" циклом

пропускаются на обработку всмысле:)всмысле обрабатываются:)


default   (2006-10-10 12:44:00) [4]


> отбирая в нём сообщения относящиеся только к созданному
> окну - это получится некое подобие модального вызова MessageBox

это лишь некое подобие
на самом деле модальный показ MessageBox блокирует не все сообщения для других окон
в чём легко убедиться, например, вызвав модально MessageBox на главном окне, потом открыть другую программу и снова исходную программу - и увидим, что главное окно перерисовалось - значит сообщения по отрисовке главного окна "пропускаются" циклом выборки сообщений генерируемым модальным вызовом MessageBox
а вот сообщения по закрытию окна в модальном вызове MessageBox не  пропускаются


default   (2006-10-10 12:31:00) [5]

Bless ©   (10.10.06 12:13) [21]
представь, что вместо вызова MessageBox ты создаёшь окно для диалога с пользователем(через CreateWindow(Ex)) и запускаешь цикл выборки сообщений отбирая в нём сообщения относящиеся только к созданному окну - это получится некое подобие модального вызова MessageBox
а вот если ты принимаешь на обработку сообщения относящиеся ко всем окнам, то тогда это будет некое подобие немодального вызова MessageBox
у тебя MessageBox вызывается немодально, поэтому ведётся обработка сообщений для всех окон и потому WM_CLOSE главного окна и обрабатывается


Bless   (2006-10-10 12:13:00) [6]


> Elen ©   (10.10.06 11:35) [17]
> Чего б не поставить PostMessage или Form2.close после всех
> нужных действий в Эксцепте?


В данном примере это можно сделать. Но к сути вопроса это отношения не имеет, а пример создан лишь для иллюстрации вопроса.


han_malign   (2006-10-10 12:02:00) [7]


> Где об этом можно четко прочитать?

Help->MessageBox->Flags: MB_APPLMODAL/MB_SYSTEMMODAL/MB_TASKMODAL

модальные окна не блокируют(по умолчанию) очередь сообщений для других окон,
тут кто-то уже ставил MB на таймер и был (не)приятно удивлен...
Application.ProcessMessages
    GetMessage(MSG, 0,...)
         DispatchMessage
              <MB.ProcessMessages>
              GetMessage((MSG, зависит от флагов,...)
                    DispatchMessage
              loop
    loop


Плохиш   (2006-10-10 11:44:00) [8]


> Так внутренний цикл MessageBox-а обрабатывает только сообщения,
>  относящиеся к окну MessageBox-а или все-таки все сообщения?

MessageBox выполняется в основном потоке программы, а сообщения  обрабатываются по потокам, а не по окнам.


Bless   (2006-10-10 11:40:00) [9]


> Плохиш ©   (10.10.06 11:34) [16]


Т.е. я в [11] все верно написал?

Но меня как-то смущает:

> Игорь Шевченко ©   (10.10.06 10:52) [6]
> Bless ©   (10.10.06 10:46) [3]
> > Не совсем понимаю, что такое модальный message loop
> Выборка из очереди потока сообщений, относящихся только
> к определенному окну
. Поток-то один, в недрах MessageBox
> крутится цикл выборки сообщений, который больше никому не
> отдает управления.


Так внутренний цикл MessageBox-а обрабатывает только сообщения, относящиеся к окну MessageBox-а или все-таки все сообщения? Где об этом можно четко прочитать?


Elen   (2006-10-10 11:35:00) [10]


> Bless

Чего б не поставить PostMessage или Form2.close после всех нужных действий в Эксцепте?


Плохиш   (2006-10-10 11:34:00) [11]


> Bless ©   (10.10.06 11:22) [11]

Объясняю на пальцах. Вызвав MessageBox, который ждёт, как, надеюсь,  известно, реакции пользователя, ты передал управление из своей программы системе, а та в свою очередь включила обработку сообщений, потому что другим способом реакцию пользователя как-то узнать труднова-то. Соответственно были обработаны все сообщения пришедшие приложению. Тот же самый эффект ты получишь просто вызвав Application.ProcessMessages.


han_malign   (2006-10-10 11:33:00) [12]

MB_TASKMODAL


Bless   (2006-10-10 11:32:00) [13]


>  Замени MessageBox на любой другой оператор и будет практически
> та же реакция


Заменил на form2 := nil;. Реакция другая. Как и следовало ожидать, процедура TForm2.FormCreate отработала до конца и лишь затем был вызван TForm2.FormClose.


Bless   (2006-10-10 11:28:00) [14]


> Elen ©   (10.10.06 10:59) [9]
> Поправочка - "вызываеш" надо читать "помешаеш в очередь
> сообщений"


Вот именно. Не вызываю, а помещаю в очередь, в расчете на то, что оно будет обработано не раньше, чем произойдет очередная выборка очередного сообщения из очереди сообщений. То есть всяко после TForm2.FormCreate, а не посредине него.


Elen   (2006-10-10 11:25:00) [15]


> Bless

Нет когда ты возвал PostMessage. Ты поставил WM_Close в очередь событий. Просто перед ним были tit сообщения, ожидающие своей обработки. А когда дело дошло до WM_Close то пошло в close. Замени MessageBox на любой другой оператор и будет практически та же реакция Имхо


Bless   (2006-10-10 11:22:00) [16]

Или Вы хотите сказать, что обработчик сообщения WM_CLOSE для окна был вызван изнутри цикла MessageBox-а?


Bless   (2006-10-10 11:18:00) [17]

> Игорь Шевченко ©   (10.10.06 10:53) [8]
> Цикл выборки сообщений вызвал оконную процедуру формы для
> обработки синхронного сообщения, например.


Не понял. Где я ошибаюсь?
Вся программа по сути - это цикл обработки сообщений. В данный момент я как раз обрабатываю одно из них, которое завело меня в конечном итоге в procedure TForm2.FormCreate. Когда я закончу, то попаду  назад в цикл, который выберет следующее сообщение (которое вполне может оказаться WM_CLOSE, которое я туда поместил строчкой PostMessage(handle, WM_CLOSE,0,0);) из очереди и обработает его.
На самом деле все происходит не совсем так?


Elen   (2006-10-10 10:59:00) [18]

Поправочка - "вызываеш" надо читать "помешаеш в очередь сообщений"


Игорь Шевченко   (2006-10-10 10:53:00) [19]

Bless ©   (10.10.06 10:52) [5]


> Каким образом меня вдруг закинуло в цикл обработки сообщений,
>  а потом вернуло обратно?


Цикл выборки сообщений вызвал оконную процедуру формы для обработки синхронного сообщения, например.


Elen   (2006-10-10 10:53:00) [20]


> Bless

Ну ты ж вызываеш эту обработку через PostMessage(handle, WM_CLOSE,0,0)?
Верно ведь? Хендл то формовский


Страницы:   1 2

Наверх

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