Форум: "WinAPI";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];
ВнизТеоретический вопрос по PeekMessage Найти похожие ветки
← →
Суслик © (2005-08-25 17:42) [0]Как работает PeekMessage?
Вопрос вызван следующим.
Если окну посылать post сообщение, то PeekMessage перенаправляет его оконной функции и возвращает true.
Если окну посылать send сообщение, то PeekMessage перенаправляет его оконной функции и возвращает false.
Я что-то не погу понять, где указанное поведение PeekMessage описано в MSDN. Конкретно я не понимаю след. фразу:
The PeekMessage function dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).
Я так понимаю, что dispatch значит вызов оконной функции. Но здесь вроде не написано dispatch для post messages.
Так почему для также вызывается оконная функция?
← →
Alexander Panov © (2005-08-25 18:11) [1]Суслик © (25.08.05 17:42)
Так почему для также вызывается оконная функция?
Если окну посылать...
Странный вопрос.
Если посылаем сообщение окну, то кто ж его еще должен обработать?
← →
Суслик © (2005-08-25 18:13) [2]
> [1] Alexander Panov © (25.08.05 18:11)
Странный?
А ты попробуй окну послать post сообщение и обработать его GetMessage?
Но с GetMessage все ясно, т.к. в msdn про нее сказано следующее:The function dispatches incoming sent messages until a posted message is available for retrieval.
А вот с PeekMessage не пойму, где в msdn описано указанное в исходном вопросе поведение.
← →
Alexander Panov © (2005-08-25 18:19) [3]Не могу понять вопроса.
Вот полные цитаты из MSDN:The GetMessage function retrieves a message from the calling thread"s message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.
The PeekMessage function dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).
В чем загвоздка, не пойму?
← →
Суслик © (2005-08-25 18:22) [4]
> В чем загвоздка, не пойму?
В том, что в GetMessage явно сказано, что dispatch делается только для sent сообщений, а для post сообщений нет.
А в PeekMessage ясно сказано, что dispatch делается для sent сообщений, я для Post сообщений сказано, что они retrieves the message (if any exist).
Про то, что PeekMessage делает dispatch для post сообщений не сказано.
← →
Alexander Panov © (2005-08-25 18:26) [5]Суслик © (25.08.05 18:22) [4]
В том, что в GetMessage явно сказано, что dispatch делается только для sent сообщений, а для post сообщений нет.
Говорится, что GetMessage выбирает посланные в очередь сообщений сообщения. Каким методом посланные - МСДН умалчивает.
То же самое и про PeekMessage.
← →
Игорь Шевченко © (2005-08-25 18:27) [6]Суслик © (25.08.05 17:42)
> The PeekMessage function dispatches incoming sent messages,
> checks the thread message queue for a posted message, and
> retrieves the message (if any exist).
>
> Я так понимаю, что dispatch значит вызов оконной функции.
> Но здесь вроде не написано dispatch для post messages.
>
> Так почему для также вызывается оконная функция?
В мире сообщений Windows существует две очереди - одна для сообщений, посланных по PostMessage, другая для сообщений, посланных по SendMessage. И GetMessage и PeekMessage выбирают сообщения из обоих очередей, посланные по SendMessage обрабатываются оконной процедурой сразу же, посланные по PostMessage и выбранные одной из этих функций возращаются в структуру Message, переданную параметром этим функциям и их обработка вызывается пользователем(программистом), путем вызова DispatchMessage. Результатом работы PeekMessage является булево значение, означающее, заполнена ли переданная функции структура Message, то есть, выбрано ли сообщение из Posted Message Queue.
Функция GetMessage ждет, пока в Posted Message Queue не появится сообщение. Если в момент ожидания будет послано сообщение по SendMessage, то функция вызовет оконную процедуру нужного окна и снова перейдет в режим ожидания.
← →
Суслик © (2005-08-25 18:40) [7]
> [6] Игорь Шевченко © (25.08.05 18:27)
Спасибо за ответ, Игорь.
Я ровно так до сего дня и думал. Да и сейчас так думаю.
Но! Что-то меня сегодня удивило странное поведение следующего кода:// все в главном потоке
const
WM_MY = WM_USER + 1;
type
TMyForm = class(TForm)
procedure WmMy(var Message: TMessage); message WM_MY;
end;
procedure TMyForm.WmMy(var Message: TMessage);
begin
MessageBox(0, "message", "", 0);
end;
procedure TForm1.Button6Click(Sender: TObject);
var
kMsg: TMsg;
kMyForm: TMyForm;
begin
kMyForm := TMyForm.CreateNew(Application);
PostMessage(kMyForm.Handle, WM_MY, 0, 0);
if PeekMessage(kMsg, kMyForm.Handle, 0, 0, PM_NOREMOVE) then
MessageBox(0, "", "", 0);
Sleep(2000);
end;
При нажатии на кнопку сообщение "message" появляется сразу, а не через 2 сек.
Если поставить коментарий около строки
MessageBox(0, "", "", 0);
то появится через 2 сек.
Ну в общем я, наверное, понял в чем дело. Наверное, MessageBox делает DispatchMessages и тем самым оно попадает в WmMy сразу же.
← →
Игорь Шевченко © (2005-08-25 18:43) [8]
> Наверное, MessageBox делает DispatchMessages
MessageBox много чего делает, например, перенаправляет на себя выбор сообщений из очереди потока.
Spy++ тебе поможет :)
← →
Суслик © (2005-08-25 18:48) [9]С другой стороны какого фига MessageBox обрабатывает мои сообщения?
Игорь, а кстати факт изложенный в [8] документирован в msdn?
Или это знание из опыта?
← →
alpet © (2005-08-25 23:00) [10]Суслик © (25.08.05 18:48) [9]
Он имеет развитой Modal Message Loop (и не только он, GetOpenFileName к примеру тоже). Например если у тебя таймер установлен, на некотором окне - сообщения WM_TIMER будут приходить в соответствующую оконную процедуру. Это в отладке программ на Visual C++ доставляет некоторые неудобства - если в коде работающем по обработке WM_TIMER, срабатывает ASSERT (отображается диалог - продолжить или прервать), то этот код выполняется еще несколько раз. Такие случаи иногда возникают и в Delphi программах, но реже.
← →
palva © (2005-08-26 00:30) [11]Может быть, помогут такие пояснения.
Функции PeekMessage и GetMessage обе выбирают сообщение из очереди потока. Только PeekMessage при отсутствии сообщения сразу возвращает управление потоку, а GetMessage не возвращает управление, пока в очереди не появится какое-нибудь сообщение.
В реальном Windows приложении имеется цикл обработки сообщений, который постоянно выбирает сообщения из очереди потока и передает часть из них соответствующему окну. Модальное диалоговое окно (MessageBox) имеет свой цикл обработки сообщений, которое опустошает очередь потока, и мешает вам понять ситуацию.
PostMessage посылает сообщение В ОЧЕРЕДЬ ПОТОКА и сразу возращает управление, а SendMessage посылает сообщение ОКНУ минуя очередь потока. Фактически это обращение к оконной функции обработки сообщений.
Извините, если не очень понял обсуждаемый вопрос и ответил не по делу.
← →
Игорь Шевченко © (2005-08-26 10:06) [12]palva © (26.08.05 00:30) [11]
Все верно за одним небольшим исключением: если поток, окну которого послано сообщение по SendMessage не в состоянии обработать сообщение (например, занят вычислениями), то сообщение помещается в отдельную очередь, Sent Message Queue, из которой очереди сообщение будет выбрано при вызове функций GetMessage, PeekMessage или WaitMessage.
← →
Суслик © (2005-08-26 10:20) [13]Всем спасибо. Вцелом так я все и понимаю.
КРОМЕ следующих слов ИШ
> если поток, окну которого послано сообщение по SendMessage
> не в состоянии обработать сообщение (например, занят вычислениями),
> то сообщение помещается в отдельную очередь, Sent Message
> Queue, из которой очереди сообщение будет выбрано при вызове
> функций GetMessage, PeekMessage или WaitMessage.
Этого я не знал. Я думал, что сообщение в любом случае диспатчица (т.е. пересылается в оконную процедуру) только при явной обработке очереди либо функцией GetMessage, либо функцией PeekMessage.
Спасибо. Интересная была беседа.
ЗЫ. Кто что читал по обсуждаемому предмету? РУссиновича знаю, Рихтера знаю. Что еще?
← →
Leonid Troyanovsky © (2005-08-26 10:32) [14]
> Суслик © (26.08.05 10:20) [13]
> знаю, Рихтера знаю.
Плохо ты, брат, Рихтера знаешь.
--
Regards, LVT.
← →
Суслик © (2005-08-26 10:39) [15]
> [14] Leonid Troyanovsky © (26.08.05 10:32)
Знаю книги, а не содержание. Это первое.
Второе, на вопрос ты как-то не ответил :)
← →
Суслик © (2005-08-26 10:48) [16]
> Плохо ты, брат, Рихтера знаешь.
И потом, в Рихтере мне нужны были потоки и синхронизация. Чем собственно и пользуюсь каждый день. Все остальное не использую, потому, возможно, и не держу в памяти. Но иногда освежить в памяти хочется.
К тому же Рихтер слишком толстая книга, чтобы держать ее как "быстрый" справочник по концепциями. Потому и спросил, кто что еще по win читает.
← →
Игорь Шевченко © (2005-08-26 10:48) [17]Суслик © (26.08.05 10:20) [13]
По обсуждаемому предмету пишут Рихтер и Петцольд. Про то, что сообщения, посланные по SendMessage, помещаются в очередь, пишет Рихтер в книге: "Windows для профессионалов", в третьем и четвертом издании этот вопрос неплохо освещен.
← →
Игорь Шевченко © (2005-08-26 10:49) [18]Суслик © (26.08.05 10:48) [16]
> Потому и спросил, кто что еще по win читает.
Очень любопытно читать MSDN Magazine
← →
Суслик © (2005-08-26 10:51) [19]всем спасибо
← →
Leonid Troyanovsky © (2005-08-26 11:24) [20]
> Суслик © (26.08.05 10:39) [15]
> Второе, на вопрос ты как-то не ответил :)
А тебе Игорь уже все рассказал. (Кстати, MSDNJ есть
и в русской редакции, но там про win32 уже редко пишут).
Кстати, Чарльз Калверт тоже доходчиво пишет,
тем более, что на Delphi.
Ну, а Руссиновича надо читать вкупе с Соломоном, бо
он обогатил восприятие (с другой, так сказать, стороны).
Также, с несколько другой позиции, интересно почитать
Танненбаум "Современные операционные системы".
--
Regards, LVT.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.042 c