Цикл сообщений — обязательный раздел кода в каждой программе , использующей графический интерфейс пользователя под Microsoft Windows . [1] Программы Windows с графическим интерфейсом управляются событиями . Windows поддерживает отдельную очередь сообщений для каждого потока, создавшего окно. Обычно только первый поток создает окна. Windows помещает сообщения в эту очередь каждый раз, когда в окне этого потока происходит действие мыши, когда происходит действие клавиатуры, когда это окно находится в фокусе, и в другое время. Процесс также может добавлять сообщения в свою очередь. Чтобы принимать вводимые пользователем данные и по другим причинам, каждый поток с окном должен постоянно извлекать сообщения из своей очереди и обрабатывать их. Программист заставляет процесс сделать это, написав цикл , который вызывает GetMessage (который блокирует сообщение и извлекает его), а затем вызывает DispatchMessage (который отправляет сообщение) и повторяется бесконечно. Это цикл сообщений. Обычно существует цикл сообщений в основной программе , который выполняется в основном потоке , и дополнительный цикл сообщений в каждом созданном модальном диалоге . Сообщения для каждого окна процесса проходят через его очередь сообщений и обрабатываются его циклом сообщений. Цикл сообщений — это один из видов цикла событий .
Базовый цикл сообщений выглядит следующим образом:
int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nCmdShow ) { MSG msg ; BOOL Брет ; while ( 1 ) { bRet = GetMessage ( & msg , NULL , 0 , 0 ); if ( bRet == -1 ) // Если bRet равен -1, GetMessage не удалось. { // Обрабатываем или регистрируем ошибку; возможно выход. // ... } else if ( bRet != 0 ) // Если bRet не равен 0 или -1, сообщение должно быть обработано. { TranslateMessage ( & сообщение ); DispatchMessage ( & сообщение ); } else // Если bRet равен 0, цикл сообщений должен выйти. { перерыв ; } } вернуть сообщение . вПарам ; }
Обычно цикл событий вызывает TranslateMessage
каждое сообщение, которое может преобразовать виртуальные нажатия клавиш в строки . Технически вызов TranslateMessage
не требуется, но если его не вызвать, могут возникнуть проблемы. Цикл сообщений должен вызвать DispatchMessage
.
Цикл сообщений не воздействует напрямую на сообщения, которые он обрабатывает. Он отправляет их, вызывая DispatchMessage
, который передает сообщение «оконной процедуре» для окна, которому было адресовано сообщение. («Оконная процедура» — это процедура обратного вызова , которая была связана с классом окна при его регистрации.) (Одну и ту же оконную процедуру могут использовать несколько окон.)
Код также может отправлять сообщения непосредственно оконной процедуре. Такие сообщения называются сообщениями, не находящимися в очереди.
Строгий цикл сообщений — не единственный вариант. Код в другом месте программы также может принимать и отправлять сообщения. PeekMessage
это неблокирующий вызов, который возвращает немедленный возврат с сообщением, если какое-либо из них ожидает, или без сообщения, если ни одно из них не ожидает. WaitMessage
позволяет потоку спать до тех пор, пока сообщение не окажется в очереди.
Современные инфраструктуры графического интерфейса , такие как Windows Forms , Windows Presentation Foundation , MFC , Delphi , Qt и другие, не требуют, чтобы приложения кодировали цикл сообщений Windows, поскольку они автоматически маршрутизируют такие события, как нажатия клавиш и щелчки мыши, соответствующим обработчикам, как определены в рамках. Однако каждая платформа где-то реализует цикл сообщений, и цикл сообщений обычно можно получить или заменить, когда требуется более прямой контроль.