ПрограммированиеФорумОбщее

Какая разница между GetMessage и PeekMessage

#0
7:33, 26 окт 2007

Я так понимаю что обе функции берут сообщении из очереди и отправляют их на обработку оконной функции. Но работают они немного по разному. Знаю, их описания есть в Win SDK но я мало че понял. Какая функцмя и чему передает управление?

#1
8:56, 26 окт 2007

GetMessage ждет сообщение и выходит только если окно получило сообщение. PeekMessage выходит сразу в не зависимости от того есть сообщение или нет

#2
10:55, 26 окт 2007

GetMessage ждёт сообщение, возвращает его, и удаляет из очереди.
PeekMessage не ждёт, и не удаляет из очереди.

#3
11:43, 26 окт 2007

Nikopol
>GetMessage ждёт сообщение, возвращает его, и удаляет из очереди.
>PeekMessage не ждёт, и не удаляет из очереди.
Не совсем так. Во первых, есть PM_NOREMOVE/PM_REMOVE
Во вторых, можно задавать опции - сообщения какого типа надо выбирать из очереди.

#4
15:50, 26 окт 2007

Ну я просто обобщил и упростил :)

#5
15:59, 28 окт 2007

Вопрос в тему!!! Есть случаи в моей практике, когда у меня не использует обработка в цикле. Например работает один GUI, при этом использовать PeekMessage не рационально - потому что  он грузит на 100 % проц. В таком случае рациональне было бы юзать, как мне кажется, GetMessage.

Собственно вопрос можно ли это как-нить совместить и рационально ли это? Делает ли так кто-нить или мне забить?

#6
16:37, 28 окт 2007

Osiris
ну посмотри исходники того же квейка - там все это есть.

#7
1:50, 29 окт 2007

1. Обе функции - не отправляют сообщение оконной процедуре. Это делает DispatchMessage.
2. PeekMessage в любом случае (независимо от PM_REMOVE / PM_NOREMOVE) не ждет прихода сообщений, если их нет - она возвращает ложь. GetMessage - ждет.
3. PeekMessage не обязательно будет грузить на 100%. Можно обрабатывать сообщения, пока они есть - примерно так:
while (PeekMessage (.....))
{
  if (msg.message == WM_QUIT)
    break;
  DispatchMessage (....);
};
К тому же есть такие функции, как MsgWaitForMultipleObjects.

Вот упрощенный отрывок кода из моей игрушки:

HANDLE objects [2] =
{
  timer_handle,
  mouse_event
};
// Запуск таймера
LARGE_INTEGER due;
SetWaitableTimer (......);
// Основной цикл
while (true)
{
        DWORD result;
        MSG msg;
        // Обработаем имеющиеся сообщения
  while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  {
    if (msg.message == WM_QUIT)
      return;
    ::DispatchMessage(&msg);
  }
  result = MsgWaitForMultipleObjects (......);
  if (result == WAIT_OBJECT_0)
  {
                  // Сработал таймер. Рендерим картинку, возможны другие действия.
        }
          else
        {
                  // Обработаем мышь (DirectInput)
        }
}

С загрузкой процессора проблем нет...

#8
1:55, 29 окт 2007

Черт возьми, как тут оформляются теги...

#9
7:01, 29 окт 2007

BOOL bEnd = FALSE;
  DWORD M = 0;
  UpdateFrame = TRUE;
  while(!bEnd)
    {
      M = MsgWaitForMultipleObjects(2,DIevents,FALSE,0, QS_ALLINPUT);
    switch (M)
    {
    case WAIT_OBJECT_0:
        event1();
      break;
    case WAIT_OBJECT_0+1:
        event2();
      break;
    case WAIT_OBJECT_0+2:
    while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
      {
      if (msg.message == WM_QUIT) bEnd = TRUE;
      else
      {TranslateMessage(&msg);
      DispatchMessage(&msg);}
      }
    break;
    default:
    if (Active && UpdateFrame) DX_timer_do();
  }
  }

DIevents - массив из указателей на события DirectInput.

#10
9:31, 29 окт 2007

ARIS
mrbus
Понял - спасибо!

#11
11:13, 29 окт 2007

mrbus
> Черт возьми, как тут оформляются теги...

[cоdе=срр]
extern "C" int printf(const char* format,...);
[/cоdе]

выглядит так:

extern "C" int printf(const char* format,...);
#12
21:25, 29 окт 2007

Спасибо.

ПрограммированиеФорумОбщее

Тема в архиве.