Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
14-1128962020
vertal
2005-10-10 20:33
2005.10.30
Тестирование программы-словаря, кому это интересно, конечно


6-1120773405
viktorovich
2005-07-08 01:56
2005.10.30
Логин и пароль из Outlook Express


1-1128966963
serg128
2005-10-10 21:56
2005.10.30
Как поднять окно со строкой ввода...?


14-1128701922
X9
2005-10-07 20:18
2005.10.30
Вопрос знатокам XML (и Delph :) )


1-1128756784
ShotGun
2005-10-08 11:33
2005.10.30
Как разархивировать программно зип файл?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский