SendMessage vs PostMessage
От: DrMom  
Дата: 20.02.03 22:53
Оценка:
Почему когда я из одного потока посылаю в др. WM_QUIT при помощи SendMessage, то GetMessage не возвращает 0, а когда использую PostMessage, то все нормально??? В чем разница? Самое интерестное, что Spy++ пишет что сообщение послано — принято. Помогите плиз.
Re: SendMessage vs PostMessage
От: Алексей Владимирович Миронов Россия  
Дата: 21.02.03 01:06
Оценка: 7 (2)
Здравствуйте, DrMom, Вы писали:

DM>Почему когда я из одного потока посылаю в др. WM_QUIT при помощи SendMessage, то GetMessage не возвращает 0, а когда использую PostMessage, то все нормально??? В чем разница? Самое интерестное, что Spy++ пишет что сообщение послано — принято. Помогите плиз.


Это Вам только кажется, что все нормально.

MSDN, например, утверждает следующее (тема WM_QUIT):

The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.

Do not post the WM_QUIT message using the PostMessage function; use PostQuitMessage.

Re[2]: SendMessage vs PostMessage
От: DrMom  
Дата: 21.02.03 03:46
Оценка:
Здравствуйте, Алексей Владимирович Миронов, Вы писали:

АВМ>Это Вам только кажется, что все нормально.




АВМ>MSDN, например, утверждает следующее (тема WM_QUIT):


АВМ>

АВМ>The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.

АВМ>Do not post the WM_QUIT message using the PostMessage function; use PostQuitMessage.


Весьма занимательно!!! А где это написано, если точнее? Такие вещи надо в избранное добавлять.

ЗЫ Почему я MSDN ом пользоваться не умею?!
Re[3]: SendMessage vs PostMessage
От: IceHand  
Дата: 21.02.03 04:04
Оценка: -3
SendMessage, PostMessage отличие этих функций в том, что send посылает сообщение и не ждет обработано оно или нет, а post ждет пока сообщение обработается
Re[4]: SendMessage vs PostMessage
От: Аноним  
Дата: 21.02.03 05:04
Оценка:
Здравствуйте, IceHand, Вы писали:

IH>SendMessage, PostMessage отличие этих функций в том, что send посылает сообщение и не ждет обработано оно или нет, а post ждет пока сообщение обработается


Наоборот.
Re[5]: SendMessage vs PostMessage
От: DrMom  
Дата: 21.02.03 06:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, IceHand, Вы писали:


IH>>SendMessage, PostMessage отличие этих функций в том, что send посылает сообщение и не ждет обработано оно или нет, а post ждет пока сообщение обработается


А>Наоборот.


Господа, не надо заниматься пустой болтовней. Вы бы хоть посмотрели, что я спрашивал. Чем объяснять мне разницу между SM и PM, лучше ответили бы на мой вопрос. За полезный ответ готов балами отблагодарить.
Re[6]: SendMessage vs PostMessage
От: algod Украина  
Дата: 21.02.03 06:50
Оценка:
DM>Господа, не надо заниматься пустой болтовней. Вы бы хоть посмотрели, что я спрашивал. Чем объяснять мне разницу между SM и PM, лучше ответили бы на мой вопрос. За полезный ответ готов балами отблагодарить.

SM напрямую вызывает каллбек твоего окна, проходит сквозь свичер —
и вылетает, так ничего и не сделав....
PM заганяет WB_QUIT в стек сообщений, откуда оно потом забираеться GetMessage
— и GetMessage возвращет 0.
В первом случае до GetMessage даже не доходит...

з.ы. А спай — прав... Оконная процедура таки получила соббщение...
Другой вопрос как...
There is no bug
Re[7]: SendMessage vs PostMessage
От: Рек Россия  
Дата: 21.02.03 07:22
Оценка:
Здравствуйте, algod, Вы писали:

DM>>Господа, не надо заниматься пустой болтовней. Вы бы хоть посмотрели, что я спрашивал. Чем объяснять мне разницу между SM и PM, лучше ответили бы на мой вопрос. За полезный ответ готов балами отблагодарить.


A>SM напрямую вызывает каллбек твоего окна, проходит сквозь свичер —

A>и вылетает, так ничего и не сделав....
A>PM заганяет WB_QUIT в стек сообщений, откуда оно потом забираеться GetMessage
A>- и GetMessage возвращет 0.
A>В первом случае до GetMessage даже не доходит...

A>з.ы. А спай — прав... Оконная процедура таки получила соббщение...

A>Другой вопрос как...



Мелкие терминологические замечания:
"каллбек твоего окна" — это наверное "оконная процедура".
"стек сообщений" — наверное всё-таки "очередь сообщеий".

Кстати вопрос:
Если делать SM из другого потока (не из потока, создавшего окно),
то прямого вызова оконной процедуры происходить не будет?
Всё будет проходить через очередь?
Вариант И GetMessage в этом случае вернёт 0?

Или GetMessage всё равно, выгребая sm-cообщение из очереди, вызовет
оконную процедуру изнутри напрямую, не возвращая управление?
Re[8]: SendMessage vs PostMessage
От: algod Украина  
Дата: 21.02.03 07:49
Оценка:
Здравствуйте, Рек, Вы писали:

Рек>


Рек>Мелкие терминологические замечания:

Рек>...
Но ты же меня понял? Тогда — зачем эти вечные споры о терминологии

Рек>Кстати вопрос:

Рек>Если делать SM из другого потока (не из потока, создавшего окно),
Рек>то прямого вызова оконной процедуры происходить не будет?
Будет! Читаем МСДН:
If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.

SM гарантированно возвращает код "оконной процедуры". Если в этот момент оконная проца другого потока подвиснет — подвиснешь и ты.

(для справки есть еще SendMessageTimeout — тоже самое, что SM, но более расчитано на работу с многозадачностью )

Рек>Всё будет проходить через очередь?

Рек>Вариант И GetMessage в этом случае вернёт 0?
Рек>Или GetMessage всё равно, выгребая sm-cообщение из очереди, вызовет
Рек>оконную процедуру изнутри напрямую, не возвращая управление?

См. выше....
There is no bug
Re[9]: SendMessage vs PostMessage
От: Рек Россия  
Дата: 21.02.03 12:03
Оценка:
Здравствуйте, algod, Вы писали:

A>Здравствуйте, Рек, Вы писали:


Рек>>


Рек>>Мелкие терминологические замечания:

Рек>>...
A> Но ты же меня понял? Тогда — зачем эти вечные споры о терминологии

Рек>>Кстати вопрос:

Рек>>Если делать SM из другого потока (не из потока, создавшего окно),
Рек>>то прямого вызова оконной процедуры происходить не будет?
A> Будет! Читаем МСДН:
A>If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.

A>SM гарантированно возвращает код "оконной процедуры". Если в этот момент оконная проца другого потока подвиснет — подвиснешь и ты.


A> (для справки есть еще SendMessageTimeout — тоже самое, что SM, но более расчитано на работу с многозадачностью )


Рек>>Всё будет проходить через очередь?

Рек>>Вариант И GetMessage в этом случае вернёт 0?
Рек>>Или GetMessage всё равно, выгребая sm-cообщение из очереди, вызовет
Рек>>оконную процедуру изнутри напрямую, не возвращая управление?
A>
A> См. выше....

Правильно ли я понял,
что SM-сообщения обрабатываются внутри GetMessage (прямым колом)
и никогда не попадают в DispatchMessagе?
В том числе и тогда когда сообщение пришло из другого потока.
Так?
Re[10]: SendMessage vs PostMessage
От: algod Украина  
Дата: 21.02.03 12:39
Оценка:
Здравствуйте, Рек, Вы писали:

Рек>Правильно ли я понял,

Рек>что SM-сообщения обрабатываются внутри GetMessage (прямым колом)
Рек>и никогда не попадают в DispatchMessagе?
Рек>В том числе и тогда когда сообщение пришло из другого потока.
Рек>Так?

Извини — наверное где то неправильно выразился
GetMessage — забирает следующее сообщение из очереди. И ничего более... Оно не вызывает оконную процедуру.

вот DispatchMessagе — уже вызывает оконную процедуру, исходя из параметров полученых из GetMessage, по пути обработав таймер.

SendMessage напрямую вызывает оконную процу (с синхронизацией, естественно).

Т.е., грубо говоря, содержимое DispatchMessagе можно представить как:
LRESULT 
DispatchMessage
  ( CONST MSG *lpmsg )
{
// ***********************
//  Обработка каллбека таймера, если обрабатываем сообщение WM_TIMER, если такой имееться
// ***********************
//  Возможно что то еще: проверки на валидность оконного хендла, етс.
// ***********************

  return SendMessage
    ( lpmsg->hwnd,
    , lpmsg->message
    , lpmsg->wParam
    , lpmsg->lParam );
}


Грубая реализация SendMessage:

LRESULT SendMessage
  ( HWND hWnd
  , UINT Msg
  , WPARAM wParam
  , LPARAM lParam)
{
// ***********************
//  Что то тут есть: проверка на валидность оконного хендла, синхранизация многопоточности етс.
// ***********************

  return CallWindowProc
    ( (WNDPROC) GetWindowLong (lpmsg->hwnd, GWL_WNDPROC)
    , lpmsg->message
    , lpmsg->wParam
    , lpmsg->lParam );
}


Я не знаю досконально внутренний механизм этих функций, но судя по всему, оно где то рядом...
Теоретически можно поробовать реализовать стандартный оконный луп через CallWindowProc или
SendMessage — и посмотреть что получиться...

з.ы. кстати — сейчас попробую, и напишу
There is no bug
Re[10]: SendMessage vs PostMessage
От: algod Украина  
Дата: 21.02.03 12:48
Оценка:
Рек>Правильно ли я понял,
Рек>что SM-сообщения обрабатываются внутри GetMessage (прямым колом)
Рек>и никогда не попадают в DispatchMessagе?
Рек>В том числе и тогда когда сообщение пришло из другого потока.
Рек>Так?

В продолжение темы:
SM, CallWindowProc
— оба варианта прекрасно работают внутри
while(GetMessage(...) {...}

DispatchMessage — нужен только для таймера
There is no bug
Re[2]: SendMessage vs PostMessage
От: Valerio Россия linkedin.com/in/boronin
Дата: 22.02.03 10:45
Оценка: 13 (2)
Абсолютно верный ответ:
существует флаг статуса очереди сообщений — QS_QUIT
он выставляется как раз именно PostQuitMessage, а не PostMessage
при этом WM_QUIT вообще не добавляется к очереди сообщений

когда поток вызывает GetMessage or PeekMessage система проверяет состояние очередей потока и если видит установленный флаг QS_QUIT просто возвращает WM_QUIT и сбрасывает флаг

при этом помню интересный sideeffect от такого поведения для WM_QUIT:
фрагмент
PostQuitMessage(0);
PostMessage(hwnd,msg,wparam,lparam);

и здесь все сообщения после WM_QUIT будут обработаны ДО WM_QUIT

АВМ>

АВМ>The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.

АВМ>Do not post the WM_QUIT message using the PostMessage function; use PostQuitMessage.

... << RSDN@Home 1.0 beta 6 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[11]: SendMessage vs PostMessage
От: Kirill_Luzanov  
Дата: 12.03.03 15:18
Оценка:
Здравствуйте, algod, Вы писали:

A>Здравствуйте, Рек, Вы писали:


Рек>>Правильно ли я понял,

Рек>>что SM-сообщения обрабатываются внутри GetMessage (прямым колом)
Рек>>и никогда не попадают в DispatchMessagе?
Рек>>В том числе и тогда когда сообщение пришло из другого потока.
Рек>>Так?

A>Извини — наверное где то неправильно выразился

A>GetMessage — забирает следующее сообщение из очереди. И ничего более... Оно не вызывает оконную процедуру.

A>вот DispatchMessagе — уже вызывает оконную процедуру, исходя из параметров полученых из GetMessage, по пути обработав таймер.


A>SendMessage напрямую вызывает оконную процу (с синхронизацией, естественно).

НЕВЕРНО!!! Если поток не вызывает GetMessage или PeekMessage сообщение НИКОГДА не будет обработанно!
SendMessage НЕ ВЫЗЫВАЕТ напрямую оконную процедуру — если бы это было так — то оконная процедура вызывалсь бы
в ТЕКУЩЕМ потоке — а не потоке ВЛАДЕЮЩЕМ очередью сообщений!!!
В WINDOWS ВСЕ СООБЩЕНИЯ ДЛЯ ПОТОКА ОБРАБАТЫАЮТСЯ ТОЛЬКО В САМОМ ПОТОКЕ!
Так что прав — Pek.
Синхронные сообщения имеют наибольший приоритет и обрабатываются в первую очередь!
Они обрабатываются автоматически
(перенаправляются в оконную процедру) внутри вызова потоком Get(Peek)Message.
Используя Get(Peek)Message можно выбрать из очереди только асинхронное собщение.

A>Т.е., грубо говоря, содержимое DispatchMessagе можно представить как:

A>
A>LRESULT 
A>DispatchMessage
A>  ( CONST MSG *lpmsg )
A>{
A>// ***********************
A>//  Обработка каллбека таймера, если обрабатываем сообщение WM_TIMER, если такой имееться
A>// ***********************
A>//  Возможно что то еще: проверки на валидность оконного хендла, етс.
A>// ***********************

A>  return SendMessage
A>    ( lpmsg->hwnd,
A>    , lpmsg->message
A>    , lpmsg->wParam
A>    , lpmsg->lParam );
A>}
A>


A>Грубая реализация SendMessage:


A>
A>LRESULT SendMessage
A>  ( HWND hWnd
A>  , UINT Msg
A>  , WPARAM wParam
A>  , LPARAM lParam)
A>{
A>// ***********************
A>//  Что то тут есть: проверка на валидность оконного хендла, синхранизация многопоточности етс.
A>// ***********************

A>  return CallWindowProc
A>    ( (WNDPROC) GetWindowLong (lpmsg->hwnd, GWL_WNDPROC)
A>    , lpmsg->message
A>    , lpmsg->wParam
A>    , lpmsg->lParam );
A>}
A>


A>Я не знаю досконально внутренний механизм этих функций, но судя по всему, оно где то рядом...

A>Теоретически можно поробовать реализовать стандартный оконный луп через CallWindowProc или
A>SendMessage — и посмотреть что получиться...

A>з.ы. кстати — сейчас попробую, и напишу

Все не так
ПСЕВДОКОД Windows :
LRESULT SendMessage(HWND hWnd, UINT Msg , WPARAM wParam , LPARAM lParam)
{
   DWORD dwThreadID = System::GetWindowNativeThreadID(hWnd);
   System::MessageQueue* pQueue = System::GetThreadMessageQueue(dwThreadID);
   MSG msg(Msg, wParam, lParam)
   return pQueue->AddSync(&msg);
}

LRESULT System::MessageQueue::AddSync(MSG* pMsg)
{
   SyncMSGWrapper SyncMsg(pMsg);
   m_mtx.Lock();
   m_list.push_back(&SyncMsg)
   m_mtx.Unlock();
   m_NewMsgEvent.Set();
   if(WaitForXXXX(SyncMsg.m_ProcessedEvent.GetHandle(), INFINITE) == WAIT_OBJECT_0)
      return SyncMsg.GetResult();
   else
      обработка ошибок
}

BOOL GetMessage(MSG* pMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
{
   System::MessageQueue* pQueue = System::GetThreadMessageQueue(::GetCurrentThreadID());
   return pQueue->GetMessage(pMsg, hWnd, wMsgFilterMin,wMsgFilterMax);
}

BOOL System::MessageQueue::GetMessage(MSG* pMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
{
   if(::GetCurrentThreadID() != m_dwNativeThreadID)
       return -1;
   while(TRUE)
   {
    m_mtx.Lock();
    if(m_list.empty())
    {
        if(WaitForXXX(m_NewMsgEvent.GetHandle(), INFINiTE) == WAIT_OBJECT_0)
            break;
    }
    else
    {
      for(iter i = m_list.begin(); i != m_list.end(); ++i)
      {
          SystemMSG* pMSG = *i;
          if(pMSG->IsSync())
          {
             FindAndCallWindowProc(pMSG);
             pMsg->m_ProcessedEvent.Set();
             m_list.erase(i);
          }
      }
      // далее поиск на соотв фильтру асинхронного сообщения и возврат
      // первого подходящего
       
    }
  }
}

Think different
Re[12]: SendMessage vs PostMessage
От: Kirill_Luzanov  
Дата: 12.03.03 15:36
Оценка:
Здравствуйте, Kirill_Luzanov, Вы писали:


KL> НЕВЕРНО!!! Если поток не вызывает GetMessage или PeekMessage сообщение НИКОГДА не будет обработанно!

KL>SendMessage НЕ ВЫЗЫВАЕТ напрямую оконную процедуру — если бы это было так — то оконная процедура вызывалсь бы
KL>в ТЕКУЩЕМ потоке — а не потоке ВЛАДЕЮЩЕМ очередью сообщений!!!
KL>В WINDOWS ВСЕ СООБЩЕНИЯ ДЛЯ ПОТОКА ОБРАБАТЫАЮТСЯ ТОЛЬКО В САМОМ ПОТОКЕ!
KL>Так что прав — Pek.
Забыл уточнить — SendMessage может вызвать оконную процедуру напрямую ТОЛЬОКО если
она вызывается в родном для окна потоке. Иначе см. выше.
И соотв. слегка изм. псевдокод:
LRESULT SendMessage(HWND hWnd, UINT Msg , WPARAM wParam , LPARAM lParam)
{
   DWORD dwThreadID = System::GetWindowNativeThreadID(hWnd);
   System::MessageQueue* pQueue = System::GetThreadMessageQueue(dwThreadID);
   if(GetCurrentThreadId() == pQueue->GetNativeThredId())
      вызывается оконная процедура
   else
   {
     MSG msg(Msg, wParam, lParam)
     return pQueue->AddSync(&msg);
   }
}
далее смотри мой предыдущий пост...
Think different
Re[13]: SendMessage vs PostMessage
От: algod Украина  
Дата: 12.03.03 16:23
Оценка:
Здравствуйте, Kirill_Luzanov, Вы писали:

KL>Здравствуйте, Kirill_Luzanov, Вы писали:


KL>Забыл уточнить — SendMessage может вызвать оконную процедуру напрямую ТОЛЬОКО если

KL>она вызывается в родном для окна потоке. Иначе см. выше.
KL>И соотв. слегка изм. псевдокод:
KL>
KL>LRESULT SendMessage(HWND hWnd, UINT Msg , WPARAM wParam , LPARAM lParam)
KL>{
KL>   DWORD dwThreadID = System::GetWindowNativeThreadID(hWnd);
KL>   System::MessageQueue* pQueue = System::GetThreadMessageQueue(dwThreadID);
KL>   if(GetCurrentThreadId() == pQueue->GetNativeThredId())
KL>      вызывается оконная процедура
KL>   else
KL>   {
KL>     MSG msg(Msg, wParam, lParam)
KL>     return pQueue->AddSync(&msg);
KL>   }
KL>}
KL>далее смотри мой предыдущий пост...
KL>


Ладно... Частично сглючил... Как раз из за того, что ты описал в последнем посте .
Ведь все таки PostMessage выгребаеться из очереди . Хотя он для того и создан
There is no bug
Re[14]: SendMessage vs PostMessage
От: Kirill_Luzanov  
Дата: 12.03.03 17:13
Оценка:
Здравствуйте, algod, Вы писали:

A>Здравствуйте, Kirill_Luzanov, Вы писали:


KL>>Здравствуйте, Kirill_Luzanov, Вы писали:


KL>>Забыл уточнить — SendMessage может вызвать оконную процедуру напрямую ТОЛЬОКО если

KL>>она вызывается в родном для окна потоке. Иначе см. выше.
KL>>И соотв. слегка изм. псевдокод:
KL>>
KL>>LRESULT SendMessage(HWND hWnd, UINT Msg , WPARAM wParam , LPARAM lParam)
KL>>{
KL>>   DWORD dwThreadID = System::GetWindowNativeThreadID(hWnd);
KL>>   System::MessageQueue* pQueue = System::GetThreadMessageQueue(dwThreadID);
KL>>   if(GetCurrentThreadId() == pQueue->GetNativeThredId())
KL>>      вызывается оконная процедура
KL>>   else
KL>>   {
KL>>     MSG msg(Msg, wParam, lParam)
KL>>     return pQueue->AddSync(&msg);
KL>>   }
KL>>}
KL>>далее смотри мой предыдущий пост...
KL>>


A> Ладно... Частично сглючил... Как раз из за того, что ты описал в последнем посте .

A>Ведь все таки PostMessage выгребаеться из очереди . Хотя он для того и создан
Со всеми бывает...

Чтобы до конца расставить все точки над "и" резюмирую:
Если вызывающий SendMessage поток явл. РОДНЫМ для окна — сообщение в очередь сообщений
потока НЕ помещается — а НАПРЯМУЮ передается соотв. оконной процедуре.
Если вызвывающий SendMessage поток НЕ ЯВЛ. РОДНЫМ для окна — SendMessage НЕ ВЫЗЫВАЕТ
напрямую оконную процедуру (- если бы это было так — то оконная процедура вызывалсь бы
в ТЕКУЩЕМ потоке — а не потоке ВЛАДЕЮЩЕМ очередью сообщений) — а помещает его в очередь
и ждет обработки сообщения соотв.ф-циями (GetMessage и т.п.) РОДНОГО для окна потока!!!
В WINDOWS ВСЕ СООБЩЕНИЯ ДЛЯ ПОТОКА ОБРАБАТЫАЮТСЯ ТОЛЬКО В САМОМ ПОТОКЕ!
Обработка очереди сообщений:
Если поток не вызывает GetMessage или PeekMessage — то сообщения из ДРУГИХ
потоков НИКОГДА не будут обработанны!
Синхронные сообщения (из других потоков (см. выше)) имеют наибольший приоритет
и обрабатываются в первую очередь! Они обрабатываются автоматически
(перенаправляются в оконную процедру) внутри
вызова потоком Get(Peek)Message.
Используя Get(Peek)Message можно выбрать из очереди только асинхронное собщение.

Ну вроде все...
Think different
Re[15]: SendMessage vs PostMessage
От: Блудов Павел Россия  
Дата: 13.03.03 03:42
Оценка:
Здравствуйте, Kirill_Luzanov, Вы писали:

KL>Если поток не вызывает GetMessage или PeekMessage — то сообщения из ДРУГИХ

KL>потоков НИКОГДА не будут обработанны!

Маленькое дополнение.
::SendMessage(hwndОкнаИзДругойНити) не вернется, до тех пор, пока оконная процедура
жтого окна не отработает. Тем не менее, эта оконная процедура может в свою очередь
сделать ::SendMessage(hwndОкнаИзНитиСделавшейSendMessage), и это сообщение тоже
будет обработано.

Дело в том, что если ::SendMessage() должна сидеть и ждать, пока отработает
другая нить, то она обрабатывает вызовы ::SendMessage() из других нитей
для "своих" окон. ::PostMessage() для "своих" окон не будут обработаны до
::Get/PeekMessage().

И еще интересный момент.
Если было послано сообщение из лругой нити, то ::MsgWaitForMutliObjs() вернет
WAITOBJECT_0 + nObjects, как если бы в очереди завелось сообщение,
и следующий вызов ::GetMessage() "дернет" напрямую оконную процедуру,
но не вернется, так как ему нечего возвращать.

Довольно популярная ошибка, даже WTL-ный мастер вставляет ее в проекты
MultiThreadedSDI.

Павел.
Re[16]: SendMessage vs PostMessage
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 13.03.03 04:45
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

[]

БП>И еще интересный момент.

БП>Если было послано сообщение из лругой нити, то ::MsgWaitForMutliObjs() вернет
БП>WAITOBJECT_0 + nObjects, как если бы в очереди завелось сообщение,
БП>и следующий вызов ::GetMessage() "дернет" напрямую оконную процедуру,
БП>но не вернется, так как ему нечего возвращать.

БП>Довольно популярная ошибка, даже WTL-ный мастер вставляет ее в проекты

БП>MultiThreadedSDI.

Вот те здрасте! GetMessage вызывает напрямую оконную процедуру? Это ты где такое вычитал? Хе-хе.
GetMessage только и делает, что дожидается сообщения в очереди и заполняет структуру MSG. Все! Ничего она не вызывает!
А в WTL какой-то другой глюк.
Re[17]: SendMessage vs PostMessage
От: algod Украина  
Дата: 13.03.03 08:05
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Здравствуйте, Блудов Павел, Вы писали:


AS>Вот те здрасте! GetMessage вызывает напрямую оконную процедуру? Это ты где такое вычитал? Хе-хе.

AS>GetMessage только и делает, что дожидается сообщения в очереди и заполняет структуру MSG. Все! Ничего она не вызывает!
AS>А в WTL какой-то другой глюк.

А ты проверь, как я . Я тоже сначала не поверил. Простейший эксперимент:
В одном процессе открой окно, напиши в свичере оконной процы
case WM_USER + 0x100: MessageBepp (0); break;

а потом зациклись в пустоте
for ( ; ; );


Во втором процессе найди это окно (по капшану, хотя бы) — и пульни в него WM_USER + 0x100...
Оно никогда не дойдет . И окно твое "висеть" будет. В прямом смысле слова.

А вот если ты напишешь хотя бы так:
while (Get(Peek)Message (...));


То твоя мессага приходить будет... И даже бекграунд окна будет перерисовываться (короче все, что присылали из других процессов по SendMessage)

GetMessage — выгребает с возвращением только PostMessage. Kirill и Павел правы.
There is no bug
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.