Функции GetMessage и PeekMessage позволяют вам указать фильтр, ограничивающий обрабатываемые сообщения по описателю окна или диапазону кодов сообщений, которые функции будут получать из очереди. Хотя это вполне нормально - использовать их, но вы только убедитесь, что время от времени вы позволяете проходить любому (нефильтрованному) сообщению.
Частой ошибкой бывает использование GetMessage с фильтром по окну в вашем цикле выборки сообщений:
while GetMessage(Msg, Wnd, 0, 0) do // Неверно!Хотя ваша программа может создавать всего одно окно, этот код, тем не менее, неверен.
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
"Как это может быть?" - спросите вы, - "Моя программа имеет только одно окно. Почему тут могут быть какие-то ещё сообщения для других окон? Фильтр, хотя и избыточен, но ведь безвреден, правда?"
Многие системные службы создают окна для вас. Например, если включено редактирование метода ввода, то редактор метода может создать вспомогательные окна для содействия вводу символов. Если вы инициализируете COM, то тогда COM может решить создать вспомогательное окно для поддержки межпоточного маршаллинга. Если вы используете только фильтрованный GetMessage, то сообщения для этих окон никогда не будут обработаны, а вы останетесь сидеть и почёсывать голову, соображая, почему ваша программа иногда зависает, когда вы, например, пытаетесь сделать drag&drop.
Мораль истории: убедитесь, что ваши циклы сообщений рано или поздно выбирают все сообщения из очереди, так что дополнительные службы смогут функционировать верно.
См. также: в чём разница между Send- и Post-функциями?
ОтветитьУдалить