GetMessage () вернет -1 в главном цикле сообщений? - PullRequest
6 голосов
/ 13 марта 2011

В соответствии с GetMessage API из библиотеки MSDN может возвращать -1 при возникновении ошибки. В документе приведен фрагмент кода распространенной ошибки, которого следует избегать:

while (GetMessage( lpMsg, hWnd, 0, 0)) ...

Документ гласит:

Возможность возврата -1 означает, что такой код может привести к летальному исходу ошибки приложения. Вместо этого используйте код как это:

BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

Мой вопрос заключается в том, что в каждом примере кода, включая приложение по умолчанию, созданное из Visual Studio от Microsoft, основной цикл сообщений выглядит следующим образом:

while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

Обратите внимание, что второй параметр GetMessage, указанный выше, имеет значение NULL. Если приведенный выше код действителен, означает ли это, что GetMessage здесь НИКОГДА не возвращает -1, так что обработка возвращаемого значения -1 не требуется?

Ответы [ 4 ]

4 голосов
/ 13 марта 2011

Вы должны следовать правилам, указанным в документации MSDN для GetMessage().Это безболезненно, и не похоже, что вокруг вашего кода разбросано большое количество циклов сообщений.

Команда Visual Studio отделена от команды Windows и делает те же ошибки, что и все остальные!

На самом деле я не могу себе представить, GetMessage() возвращает ошибку, но это характер обработки ошибок - это не значит, что вы не должны правильно обрабатывать ошибки.

3 голосов
/ 13 марта 2011

Мой инстинкт (он же Раймонд Чен экстрасенсорные способности) говорит мне, что GetMessage(&msg, NULL, 0, 0) вернет -1 только в случае крайне редкого катастрофического сбоя, такого как повреждение очереди сообщений. В этом случае его тестирование похоже на перехват std :: bad_alloc в программе на C ++: когда это происходит, вероятно, уже слишком поздно что-либо предпринимать. Позволить процессу зависать (игнорируя GetMessage () == -1) или умирать (не перехватывая bad_alloc) допустимо, если, конечно, этот процесс не контролирует атомную электростанцию.

Все зависит от того, насколько формальным ты хочешь быть. Я бы специально проверил на -1 в коммерческом приложении, но не в маленькой утилите, написанной для личного использования.

3 голосов
/ 13 марта 2011

Учитывая, что VS дает вам неправильный код по умолчанию, и, похоже, это никого не волнует, вполне вероятно, что это не вызовет проблем в текущих версиях Windows .

Возможно, что какая-то будущая версия GetMessage вернет -1. Однако, поскольку ошибочный код должен присутствовать во многих существующих приложениях, это может привести к поломке огромного количества существующего кода. Учитывая приверженность Microsoft обратной совместимости, я думаю, что вряд ли они изменят поведение GetMessage, на которое полагаются многие программы.

И, несмотря на все это, вы все равно должны следовать документации.

3 голосов
/ 13 марта 2011

В документации, которую вы упоминаете, сказано:

В случае ошибки возвращаемое значение равно -1.Например, функция завершается ошибкой, если hWnd является недопустимым дескриптором окна или lpMsg является недопустимым указателем.

Во втором примере эти два случаяохватывает: msg - типичная структура, выделенная стеком, поэтому &msg всегда будет действительным указателем.NULL передается в параметре hwnd и является допустимым значением для этого параметра.wMsgFilterMin и wMsgFilterMax равны нулю, что также является допустимой комбинацией.

Таким образом, GetMessage() не завершится ошибкой во время проверки параметров.В документации четко не указано, возвращает ли она также -1 в других ситуациях (например, исчерпана память).Тем не менее, я уже некоторое время вызываю GetMessage() так же, как и ваш второй пример, и я никогда не видел, чтобы он возвращал -1 и превращал мой цикл сообщений в бесконечный цикл.Конечно, ваш пробег может отличаться, но это вполне безопасно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...