Параметр hWnd в GetMessage
От: Chan_dzu  
Дата: 06.09.07 13:14
Оценка:
Обнаружил, что если в основоном цикле окна делать GetMessage(&msg, hWnd, 0, 0), то после закрытия окна оконная процедура получает WM_DESTROY, окно удаляется, всё в порядке. Но GetMessage начинает возвращать -1 (GetLastError = 1400 — Неверный хендл окна).
Если вызывать GetMessage(&msg, NULL, 0, 0), то всё ok.
Как это объяснить?
Re: Параметр hWnd в GetMessage
От: Unmanaged Россия ICQ 476611995
Дата: 06.09.07 13:48
Оценка:
C_>Обнаружил, что если в основоном цикле окна делать GetMessage(&msg, hWnd, 0, 0), то после закрытия окна оконная процедура получает WM_DESTROY, окно удаляется, всё в порядке. Но GetMessage начинает возвращать -1 (GetLastError = 1400 — Неверный хендл окна).
C_>Если вызывать GetMessage(&msg, NULL, 0, 0), то всё ok.
C_>Как это объяснить?

А по-твоему хендл окна должен оставаться валидным после уничтожения этого окна?
STATUS_INVALID_DEVICE_REQUEST
Re: Параметр hWnd в GetMessage
От: niko_ Россия www.KGBSpy.ru
Дата: 06.09.07 13:58
Оценка: 1 (1)
Здравствуйте, 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;
The truth is out there
Re[2]: Параметр hWnd в GetMessage
От: Chan_dzu  
Дата: 06.09.07 15:54
Оценка:
Это всё понятно.
Но в случае с 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 — ошибка?
Re[4]: Параметр hWnd в GetMessage
От: Chan_dzu  
Дата: 07.09.07 16:09
Оценка:
Здравствуйте, Аноним, Вы писали:

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?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.