Обнаружил, что если в основоном цикле окна делать GetMessage(&msg, hWnd, 0, 0), то после закрытия окна оконная процедура получает WM_DESTROY, окно удаляется, всё в порядке. Но GetMessage начинает возвращать -1 (GetLastError = 1400 — Неверный хендл окна).
Если вызывать GetMessage(&msg, NULL, 0, 0), то всё ok.
Как это объяснить?
C_>Обнаружил, что если в основоном цикле окна делать GetMessage(&msg, hWnd, 0, 0), то после закрытия окна оконная процедура получает WM_DESTROY, окно удаляется, всё в порядке. Но GetMessage начинает возвращать -1 (GetLastError = 1400 — Неверный хендл окна). C_>Если вызывать GetMessage(&msg, NULL, 0, 0), то всё ok. C_>Как это объяснить?
А по-твоему хендл окна должен оставаться валидным после уничтожения этого окна?
Здравствуйте, Chan_dzu, Вы писали:
C_>Обнаружил, что если в основоном цикле окна делать GetMessage(&msg, hWnd, 0, 0), то после закрытия окна оконная процедура получает WM_DESTROY, окно удаляется, всё в порядке. Но GetMessage начинает возвращать -1 (GetLastError = 1400 — Неверный хендл окна). C_>Если вызывать GetMessage(&msg, NULL, 0, 0), то всё ok. C_>Как это объяснить?
После уничтожения окна цикл продолжает выполнятся т.к. он об этом не был "уведомлён" и понятоное дело hWnd уже не действителен, поэтому GetMessage возвращает -1 (В MSDN'е всё описано).
Дабы избежать этого надо в обработчик сообщений окна добавить следующее:
case WM_DESTROY:
PostQuitMessage(...);
break;
При варианте с NULL'ём GetMessage'у побарабану на уничтоженное окно, ведь функция получает сообщения от всех окон текущего потока.
Цикл должен выглядеть примерно так:
MSG msg;
BOOL bRet;
while (NULL != (bRet = GetMessageW(&msg, hWnd, 0, 0)))
{
if (bRet == -1)
{
msg.wParam = GetLastError(); // к примеруbreak;
}
else
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
Result = msg.wParam;
Это всё понятно.
Но в случае с GetMessage(&msg, NULL, 0, 0) он как-то узнаёт о том что окно закрылось и возвращает 0.
А предложенный код не нравится тем, что при штатной работе генерятся ошибки.
Неужели нет корректного выхода?
Re[3]: Параметр hWnd в GetMessage
От:
Аноним
Дата:
06.09.07 16:51
Оценка:
C_>Это всё понятно. C_>Но в случае с GetMessage(&msg, NULL, 0, 0) он как-то узнаёт о том что окно закрылось и возвращает 0.
Окнозакрывается _внутри_ вызова GetMessage. А перед ним HWND был валиден
C_>А предложенный код не нравится тем, что при штатной работе генерятся ошибки.
С каких пор PostQuitMessage — ошибка?
Здравствуйте, Аноним, Вы писали:
C_>>Это всё понятно. C_>>Но в случае с GetMessage(&msg, NULL, 0, 0) он как-то узнаёт о том что окно закрылось и возвращает 0. А>Окнозакрывается _внутри_ вызова GetMessage. А перед ним HWND был валиден
Так почему тогда GetMessage(&msg, hWnd, 0, 0) НЕ возвращает 0?
C_>>А предложенный код не нравится тем, что при штатной работе генерятся ошибки. А>С каких пор PostQuitMessage — ошибка?
MSG msg;
BOOL bRet;
while (NULL != (bRet = GetMessageW(&msg, hWnd, 0, 0)))
{
if (bRet == -1)
{
msg.wParam = GetLastError(); // к примеруbreak;
}else
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
Result = msg.wParam;
Сформулируем вопрос так: можно ли использовать GetMessageW(&msg, hWnd, 0, 0) без обработки ошибок? Если нет, то зачем нужен параметр hWnd?