Цикл сообщений в Microsoft Windows
![]() | Эта статья включает список литературы , связанную литературу или внешние ссылки , но ее источники остаются неясными, поскольку в ней отсутствуют встроенные цитаты . ( Ноябрь 2023 г. ) |
Цикл сообщений — обязательный раздел кода в каждой программе , использующей графический интерфейс пользователя под Microsoft Windows . [1] Программы Windows с графическим интерфейсом управляются событиями . Windows поддерживает отдельную очередь сообщений для каждого потока, создавшего окно. Обычно только первый поток создает окна. Windows помещает сообщения в эту очередь каждый раз, когда в окне этого потока происходит действие мыши, когда происходит действие клавиатуры, когда это окно находится в фокусе, и в другое время. Процесс также может добавлять сообщения в свою очередь. Чтобы принимать вводимые пользователем данные и по другим причинам, каждый поток с окном должен постоянно извлекать сообщения из своей очереди и обрабатывать их. Программист заставляет процесс сделать это, написав цикл , который вызывает GetMessage (который блокирует сообщение и извлекает его), а затем вызывает DispatchMessage (который отправляет сообщение) и повторяется бесконечно. Это цикл сообщений. Обычно существует цикл сообщений в основной программе , который выполняется в основном потоке , и дополнительный цикл сообщений в каждом созданном модальном диалоге . Сообщения для каждого окна процесса проходят через его очередь сообщений и обрабатываются его циклом сообщений. Цикл сообщений — это один из видов цикл событий .
Базовый цикл сообщений выглядит следующим образом:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
while (1)
{
bRet = GetMessage(&msg, NULL, 0, 0);
if (bRet == -1) // If bRet is -1, GetMessage has failed.
{
// Handle or log the error; possibly exit.
// ...
}
else if (bRet != 0) // If bRet is not 0 or -1, the message must be processed.
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else // If bRet is 0, the message loop should exit.
{
break;
}
}
return msg.wParam;
}
Обычно цикл событий вызывает вызов TranslateMessage
на каждое сообщение, которое может переводить виртуальные нажатия клавиш в строки . Вызов TranslateMessage
технически не требуется, но если его не вызвать, могут возникнуть проблемы. Цикл сообщений должен вызывать DispatchMessage
.
Цикл сообщений не воздействует напрямую на сообщения, которые он обрабатывает. Он отправляет их, вызывая DispatchMessage
, который передает сообщение «оконной процедуре» для окна, которому было адресовано сообщение. («Оконная процедура» — это процедура обратного вызова , которая была связана с классом окна при его регистрации.) (Одну и ту же оконную процедуру могут использовать несколько окон.)
Код также может отправлять сообщения непосредственно оконной процедуре. Такие сообщения называются сообщениями, не находящимися в очереди.
Строгий цикл сообщений — не единственный вариант. Код в другом месте программы также может принимать и отправлять сообщения. PeekMessage
это неблокирующий вызов, который возвращает немедленный возврат с сообщением, если какое-либо из них ожидает, или без сообщения, если ни одно из них не ожидает. WaitMessage
позволяет потоку спать до тех пор, пока сообщение не окажется в очереди.
графического интерфейса Современные инфраструктуры , такие как Windows Forms , Windows Presentation Foundation , MFC , Delphi , Qt и другие, не требуют, чтобы приложения кодировали цикл сообщений Windows, поскольку они автоматически маршрутизируют такие события, как нажатия клавиш и щелчки мыши, соответствующим обработчикам, как определены в рамках. Однако каждая платформа где-то реализует цикл сообщений, и цикл сообщений обычно можно получить или заменить, когда требуется более прямой контроль.
См. также
[ редактировать ]- Xlib для цикла событий в системе X Window
Ссылки
[ редактировать ]- ^ «Вход в цикл сообщений» . 25 марта 2010 года . Проверено 23 ноября 2023 г.