Сведения о сообщениях и очередях сообщений

в отличие от приложений на основе MS-DOS, приложения на основе Windows являются управляемыми событиями. Они не выполняют явных вызовов функций (например, вызовов библиотеки времени выполнения C) для получения входных данных. Вместо этого они ожидают передачи входных данных системой.

Система передает все входные данные для приложения различным окнам в приложении. Каждое окно имеет функцию, называемую процедурой окна, которую система вызывает всякий раз, когда она имеет входные данные для окна. Процедура окна обрабатывает входные данные и возвращает управление системе. Дополнительные сведения о процедурах окна см. в разделе процедуры окна.

Если окно верхнего уровня перестает отвечать на сообщения более чем через несколько секунд, система считает, что окно не отвечает. В этом случае система скрывает окно и заменяет его окном фантома с тем же Z-порядком, расположением, размером и визуальными атрибутами. Это позволяет пользователю перемещать его, изменять его размер или даже закрывать приложение. Однако это единственные доступные действия, так как приложение на самом деле не отвечает. В режиме отладчика система не создает Несинхронизированное окно.

В этом разделе рассматриваются следующие темы:

Windows Ошибка

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

Система отправляет сообщение в процедуру окна с набором четырех параметров: маркером окна, идентификатором сообщения и двумя значениями, которые называются параметрами сообщения. Обработчик окна определяет окно, для которого предназначено сообщение. Система использует ее для определения того, какая процедура окна должна получить сообщение.

Идентификатор сообщения — это именованная константа, которая определяет назначение сообщения. Когда процедура окна получает сообщение, она использует идентификатор сообщения для определения способа обработки сообщения. Например, идентификатор сообщения WM _ Paint сообщает процедуре окна, что клиентская область окна изменилась и должна быть перерисована.

Параметры сообщения указывают данные или расположение данных, используемых процедурой окна при обработке сообщения. Значение и значения параметров сообщения зависят от сообщения. Параметр сообщения может содержать целочисленный, упакованный битовый флаг, указатель на структуру, содержащую дополнительные данные, и т. д. Если сообщение не использует параметры сообщения, обычно ему присваивается значение NULL. Процедура окна должна проверять идентификатор сообщения, чтобы определить способ интерпретации параметров сообщения.

Типы сообщений

В этом разделе описываются два типа сообщений:

Сообщения System-Defined

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

Каждое определяемое системой сообщение имеет уникальный идентификатор сообщения и соответствующую символьную константу (определенную в файлах заголовков пакета средств разработки программного обеспечения (SDK)), которая указывает назначение сообщения. Например, константа WM _ Paint запрашивает, что окно зарисовывает свое содержимое.

Символьные константы укажите категорию, которой принадлежат системные сообщения. Префикс константы определяет тип окна, которое может интерпретировать и обрабатывать сообщение. Ниже приведены префиксы и связанные с ними категории сообщений.

Prefix Категория сообщений Документация
АБМ и АБН Панель инструментов рабочего стола приложения Сообщения и уведомления оболочки
ACM и АКН Элемент управления "Анимация" Управляющие сообщения и уведомления элемента управления анимацией
BCM, BCN, BM и млрд долл Button - элемент управления Сообщения управления кнопками и уведомления об управлении кнопками
CB и КБН ComboBox - элемент управления Сообщения элемента управления ComboBox и уведомления элемента управления ComboBox
Кбем и кбен Элемент управления ComboBoxEx ComboBoxEx сообщения и ComboBoxEx уведомления
CCM Общий элемент управления Управляющие сообщения
CDM Общее диалоговое окно Сообщения общего диалогового окна
DFM Контекстное меню по умолчанию Сообщения и уведомления оболочки
DL Перетащить поле списка Перетаскивать уведомления из списка
DM Элемент управления "Кнопка" по умолчанию Сообщения диалогового окна
DTM и ДТН Элемент выбора даты и времени Сообщения выбора даты и времени и уведомления средства выбора даты и времени
EM и EN Элемент управления "Поле ввода" Изменение управляющих сообщений, уведомлений об изменении элементов управления, сообщений с богатыми возможностями редактированияи уведомлений с расширенными возможностями редактирования
HDM и ХДН Элемент управления "заголовок" Сообщения элемента управления заголовков и уведомления элемента управления заголовка
HKM Элемент управления горячими ключами Управляющие сообщения горячих ключей
IPM и ИПН контроль IP-адресов Сообщения IP-адреса и уведомления об IP-адресах
Балансировка нагрузки и ЛБН Элемент управления "Список" Сообщения списка и уведомления в виде списка
ХЕШ Элемент управления SysLink Управляющие сообщения SysLink
LVM и ЛВН Элемент управления представления списка Просмотр сообщений и уведомлений в виде списка
MCM и МКН Элемент управления "Календарь на месяц" Месячные сообщения календаря и уведомления календаря месяца
Управление на основе политик (PBM) Индикатор выполнения Сообщения на индикаторе выполнения
PGM и ПГН Элемент управления страничного навигатора Сообщения управления страничного навигатора и уведомления элемента управления страничного навигатора
ПСМ и PSN Страница свойств. Сообщения на странице свойств и уведомления на странице свойств
RB и РБН Элемент управления главной панели Управляющие сообщения главной панели и уведомления элемента управления главной панели
SB и СБН Окно строки состояния Сообщения в строке состояния и уведомления в строке состояния
сбм Элемент управления "Полоса прокрутки" Прокрутка сообщений
АДАПТЕР Меню оболочки Сообщения и уведомления оболочки
STM и СТН Статический элемент управления Статические управляющие сообщения и уведомления статического элемента управления
ТБ и ТБН Панель инструментов Сообщения элемента управления панели инструментов и уведомления элемента управления панели инструментов
ТБМ и трбн Элемент управления TrackBar Контрольные сообщения и уведомления элемента управления TrackBar
TCM и ТКН Элемент управления табуляции Управляющие сообщения вкладки и уведомления элемента управления Tab
TDM и ТДН Диалоговое окно задачи Сообщения диалогового окна задачи и Уведомления диалогового окна задачи
ТТМ и ТТН Элемент управления ToolTip Уведомления управляющих сообщений и всплывающих подсказок
TVM и ТВН Элемент управления представления в виде дерева Сообщения в представлении в виде дерева и уведомления в виде дерева
UDM и УДН Элемент управления "вверх/вниз" Сообщения со стрелками вверх и вниз
WM Общие сведения
сообщения
в буфере
обмена уведомления об
общих диалоговых окнах уведомления
курсора
копировать сообщение
диспетчер окон рабочего стола сообщения
о
диалоговом окне
сообщения об управлении устройствами
уведомления
платформа динамических данных Exchange сообщения
платформа динамических данных Exchange уведомления
обработчика уведомлений
клавиатура сообщения ускорителя
клавиатуры уведомления о
вводе
с
клавиатуры сообщения уведомления

общие сообщения окна охватывают широкий спектр информации и запросов, в том числе сообщения для ввода с клавиатуры, входа в меню и диалоговых окон, создания окон и управления, а также платформа динамических данных Exchange (DDE).

Сообщения Application-Defined

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

Значения идентификаторов сообщений используются следующим образом.

  • Система резервирует значения идентификаторов сообщений в диапазоне от Символ 0x0000 до 0x03FF (значение WM _ User – 1) для системных сообщений. Приложения не могут использовать эти значения для частных сообщений.
  • Значения в диапазоне 0x0400 (значение _ пользователя WM) через 0x7FFF доступны для идентификаторов сообщений для классов частных окон.
  • Если приложение помечено как версия 4,0, можно использовать значения идентификаторов сообщений в диапазоне от 0x8000 (_ приложение WM) до 0xBFFF для частных сообщений.
  • Система возвращает идентификатор сообщения в диапазоне от 0xC000 до 0xFFFF, когда приложение вызывает функцию регистервиндовмессаже для регистрации сообщения. Идентификатор сообщения, возвращаемый этой функцией, гарантированно уникален в пределах всей системы. Использование этой функции предотвращает конфликты, которые могут возникать, если другие приложения используют один и тот же идентификатор сообщения для разных целей.

Маршрутизация сообщений

Система использует два метода для маршрутизации сообщений в оконную процедуру: отправка сообщений в очередь сообщений"первым помещается", системный объект памяти, который временно хранит сообщения и отправляет сообщения непосредственно в процедуру окна.

Сообщения, отправляемые в очередь сообщений, называются сообщениями в очереди. В первую очередь это результат ввода данных пользователем, введенный с помощью мыши или клавиатуры, например _ WM MOUSEMOVE, WM _ Лбуттондовн, WM _ KeyDownи WM _ char . Другие сообщения в очереди включают в себя таймер, Paint и сообщение о выходе : _ таймер WM, WM _ Paintи WM _ Quit. Большинство других сообщений, которые отправляются непосредственно в процедуру окна, называются сообщениями, не помещенными в очередь.

Сообщения в очереди

Система может отображать любое количество окон за раз. Чтобы направить ввод с клавиатуры и мыши в соответствующее окно, система использует очереди сообщений.

Система поддерживает одну очередь системных сообщений и одну очередь сообщений конкретного потока для каждого потока графического пользовательского интерфейса. Чтобы избежать издержек, связанных с созданием очереди сообщений для потоков, отличных от графического пользовательского интерфейса, все потоки изначально создаются без очереди сообщений. Система создает очередь сообщений, специфичную для конкретного потока, только когда поток выполняет первый вызов одной из конкретных пользовательских функций. вызовы функций графического пользовательского интерфейса не вызывают создание очереди сообщений.

Когда пользователь перемещает мышь, нажимает кнопки мыши или типы на клавиатуре, драйвер устройства для мыши или клавиатуры преобразует входные данные в сообщения и помещает их в очередь системных сообщений. Система удаляет сообщения по одному за раз из очереди системных сообщений, анализирует их, чтобы определить окно назначения, а затем отправляет их в очередь сообщений потока, создавшего окно назначения. Очередь сообщений потока получает все сообщения мыши и клавиатуры для окон, созданных потоком. Поток удаляет сообщения из своей очереди и направляет систему на отправку в соответствующую оконную процедуру для обработки.

За исключением сообщения WM _ Paint , сообщения _ таймера WM и сообщения WM _ Quit , система всегда отправляет сообщения в конце очереди сообщений. Это гарантирует, что окно получит свои входные сообщения в соответствующей последовательности (FIFO). Однако сообщение WM _ Paint , сообщение _ таймера WM и сообщение WM _ Quit хранятся в очереди и передаются в процедуру окна только в том случае, если очередь не содержит других сообщений. Кроме того, несколько сообщений WM _ Paint для одного и того же окна объединяются в одно сообщение WM _ Paint , объединяя все недопустимые части клиентской области в одну область. Сочетание сообщений WM _ Paint сокращает число попыток, которым окно должно перерисовывать содержимое клиентской области.

Система отправляет сообщение в очередь сообщений потока, заполняя структуру MSG и затем копируя ее в очередь сообщений. Информация в MSG включает: маркер окна, для которого предназначено сообщение, идентификатор сообщения, два параметра сообщения, время отправки сообщения и позицию курсора мыши. Поток может поместить сообщение в собственную очередь сообщений или в очередь другого потока с помощью функции onmessage или постсреадмессаже .

Приложение может удалить сообщение из очереди с помощью функции- сообщения . Чтобы проверить сообщение, не удаляя его из очереди, приложение может использовать функцию PeekMessage . Эта функция заполняет сообщения информацией о сообщении.

После удаления сообщения из очереди приложение может использовать функцию DispatchMessage , чтобы направить систему на отправку сообщения в процедуру окна для обработки. DispatchMessage принимает указатель на сообщение , заполненное предыдущим вызовом функции MSG или PeekMessage . DispatchMessage передает обработчик окна, идентификатор сообщения и два параметра сообщения в процедуру окна, но не передает время отправки сообщения или положения курсора мыши. Приложение может получить эти сведения, вызвав функции жетмессажетиме и жетмессажепос при обработке сообщения.

Поток может использовать функцию ваитмессаже для передачи управления другим потокам, если в очереди сообщений нет сообщений. Функция приостанавливает поток и не возвращает значение, пока в очередь сообщений потока не помещается новое сообщение.

Чтобы связать значение с очередью сообщений текущего потока, можно вызвать функцию сетмессажеекстраинфо . Затем вызовите функцию жетмессажеекстраинфо , чтобы получить значение, связанное с последним сообщением, полученным функцией пересообщения или функции PeekMessage .

Сообщения, не помещенные в очередь

Сообщения, не помещенные в очередь, немедленно отправляются в конечную процедуру окна назначения, минуя очередь системных сообщений и очередь сообщений потока. Система обычно отправляет сообщения, не помещенные в очередь, чтобы уведомить окно событий, влияющих на него. Например, когда пользователь активирует новое окно приложения, система отправляет окну ряд сообщений, включая WM _ Activate, WM _ SETFOCUSи WM _ сеткурсор. Эти сообщения уведомляют окно о том, что оно было активировано, что ввод с клавиатуры направляется в окно, а курсор мыши переместился в границы окна. Непоставленные в очередь сообщения также могут быть вызваны тем, что приложение вызывает определенные системные функции. Например, система отправляет сообщение WM _ виндовпосчанжед после того, как приложение использует функцию SetWindowPos для перемещения окна.

Некоторые функции, отправляющие сообщения, не помещенные в очередь, — это броадкастсистеммессаже, броадкастсистеммессажеекс, SendMessage, функции sendmessagetimeoutи сенднотифимессаже.

Обработка сообщений

Приложение должно удалять и обрабатывать сообщения, размещенные в очередях сообщений своих потоков. Однопотоковое приложение обычно использует цикл обработки сообщений в функции WinMain , чтобы удалять и отсылать сообщения в соответствующие процедуры окна при обработке. Приложения с несколькими потоками могут включать цикл обработки сообщений в каждом потоке, который создает окно. В следующих разделах описывается работа цикла сообщений и объясняется роль процедуры окна:

Цикл обработки сообщений

Простой цикл обработки сообщений состоит из одного вызова функции в каждую из этих трех функций: TranslateMessage, DispatchMessage. Обратите внимание, что при возникновении ошибки функция onmessage возвращает значение – 1, поэтому требуется специальное тестирование.

MSG msg;
BOOL bRet;

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

Функция MSG получает сообщение из очереди и копирует его в структуру типа MSG. Он возвращает ненулевое значение, если не обнаруживает сообщение WM _ Quit , в этом случае возвращается значение false и завершается цикл. В многопоточном приложении завершение цикла обработки сообщений часто является первым шагом при закрытии приложения. Приложение может завершить собственный цикл с помощью функции посткуитмессаже , как правило, в ответ на сообщение WM _ destroy в оконной процедуре главного окна приложения.

Если указать в качестве второго параметра аргумента Window, тоиз очереди будут извлекаться только сообщения для указанного окна. Кроме того, в сообщении можно фильтровать сообщения в очереди, получая только те сообщения, которые попадают в указанный диапазон. Дополнительные сведения о фильтрации сообщений см. в разделе Фильтрация сообщений.

Цикл обработки сообщений потока должен включать TranslateMessage , если поток может принимать символьные данные с клавиатуры. Система создает сообщения виртуального ключа (WM _ KeyDown и WM _ KEYUP) каждый раз, когда пользователь нажимает клавишу. Сообщение виртуального ключа содержит код виртуального ключа, который определяет, какой ключ был нажат, но не его значение. Чтобы получить это значение, цикл обработки сообщений должен содержать TranslateMessage, который преобразует сообщение виртуального ключа в символьное сообщение (WM _ char) и помещает его обратно в очередь сообщений приложения. Символьное сообщение может быть удалено при последующей итерации цикла обработки сообщений и отправлено в процедуру окна.

Функция DispatchMessage отправляет сообщение в процедуру окна, связанную с маркером окна, указанным в структуре MSG . Если дескриптор окна находится на _ самом верхнем уровне HWND, DispatchMessage отправляет сообщение в процедуры окна всех окон верхнего уровня в системе. Если указатель окна имеет значение NULL, DispatchMessage не выполняет никаких действий с сообщением.

Главный поток приложения запускает цикл обработки сообщений после инициализации приложения и создания хотя бы одного окна. После запуска цикл обработки сообщений продолжит получать сообщения из очереди сообщений потока и отправлять их в соответствующие окна. Цикл обработки сообщений завершается, когда функция onmessage удаляет сообщение WM _ Quit из очереди сообщений.

Для очереди сообщений требуется только один цикл обработки сообщений, даже если приложение содержит много окон. DispatchMessage всегда отправляет сообщение в соответствующее окно; Это связано с тем, что каждое сообщение в очереди является структурой сообщений, содержащей маркер окна, которому принадлежит сообщение.

Можно изменить цикл обработки сообщений различными способами. Например, можно извлечь сообщения из очереди без их отправки в окно. Это полезно для приложений, которые передают сообщения, не указывающие окно. Кроме того, можно направить сообщение в поиск конкретных сообщений, открывая другие сообщения в очереди. Это полезно, если необходимо временно обойти обычный порядок FIFO очереди сообщений.

Приложение, использующее сочетания клавиш, должно иметь возможность преобразования сообщений клавиатуры в командные сообщения. Для этого цикл обработки сообщений приложения должен включать вызов функции TranslateAccelerator . Дополнительные сведения о сочетаниях клавиш см. в разделе сочетанияклавиш.

Если поток использует немодальное диалоговое окно, то цикл обработки сообщений должен включать функцию исдиалогмессаже , чтобы диалоговое окно могла получить ввод с клавиатуры.

Процедура окна

Оконная процедура — это функция, которая получает и обрабатывает все сообщения, отправленные в окно. Каждый класс окна содержит процедуру окна, и каждое окно, созданное с помощью этого класса, использует эту же оконную процедуру для реагирования на сообщения.

Система отправляет сообщение в процедуру окна, передавая данные сообщения в качестве аргументов в процедуру. Затем процедура окна выполняет соответствующее действие для сообщения. Он проверяет идентификатор сообщения и при обработке сообщения использует сведения, указанные в параметрах сообщения.

Процедура окна обычно не игнорирует сообщение. Если сообщение не обрабатывается, оно должно отправить сообщение обратно в систему для обработки по умолчанию. Оконная процедура делает это путем вызова функции дефвиндовпрок , которая выполняет действие по умолчанию и возвращает результат сообщения. Затем процедура Window должна вернуть это значение в виде собственного результата сообщения. Большинство процедур обработки окон обрабатывают всего несколько сообщений и передают все остальные в систему, вызывая дефвиндовпрок.

Так как процедура окна совместно используется всеми окнами, принадлежащими одному и тому же классу, она может обрабатывать сообщения для нескольких различных окон. Чтобы определить конкретное окно, затронутое сообщением, процедура окна может проверить маркер окна, переданный в сообщении. Дополнительные сведения о процедурах окна см. в разделе процедуры окна.

Фильтрация сообщений

Приложение может выбирать определенные сообщения для извлечения из очереди сообщений (при пропуске других сообщений) с помощью функции PeekMessage или метода with Message для указания фильтра сообщений. Фильтр — это диапазон идентификаторов сообщений (определяемый первым и последним идентификатором), обработчиком окна или и то, и другое. Для выбора сообщений, которые необходимо извлечь из очереди, используется фильтр сообщений и PeekMessage . Фильтрация сообщений полезна, если приложение должно искать в очереди сообщений сообщения, которые были получены позже в очереди. Он также полезен, если приложение должно обрабатывать входные сообщения (оборудование) перед обработкой отправленных сообщений.

Константы WM _ Кэйфирст и WM _ кэйласт могут использоваться в качестве значений фильтров для получения всех сообщений клавиатуры; константы WM _ маусефирст и WM _ мауселаст можно использовать для получения всех сообщений мыши.

Любое приложение, фильтрующее сообщения, должно гарантировать, что может быть отправлено сообщение, удовлетворяющее условиям фильтра сообщений. Например, если приложение фильтрует сообщение WM _ char в окне, которое не получает ввод с клавиатуры , функция GetChars не возвращает значение. Это фактически «зависает» приложение.

Публикация и отправка сообщений

Любое приложение может публиковать и отправлять сообщения. Как и система, приложение отправляет сообщение, копируя его в очередь сообщений, и отправляет сообщение, передавая данные сообщения в качестве аргументов в процедуру окна. Для публикации сообщений приложение использует функцию сообщений . Приложение может отправить сообщение, вызвав функцию SendMessage, броадкастсистеммессаже, сендмессажекаллбакк, функции sendmessagetimeout, сенднотифимессажеили сенддлгитеммессаже .

Отправка сообщений

Приложение обычно отправляет сообщение для уведомления определенного окна о выполнении задачи. Параметр i Message создает структуру сообщений для сообщения и копирует сообщение в очередь сообщений. Цикл обработки сообщений приложения в конечном итоге извлекает сообщение и отправляет его в соответствующую процедуру окна.

Приложение может публиковать сообщение без указания окна. Если приложение предоставляет нулевой маркер окна при вызове сообщения, сообщение отправляется в очередь, связанную с текущим потоком. Поскольку маркер окна не указан, приложение должно обработать сообщение в цикле обработки сообщений. Это один из способов создания сообщения, которое применяется ко всему приложению, а не к конкретному окну.

Иногда может потребоваться опубликовать сообщение во всех окнах верхнего уровня в системе. Приложение может опубликовать сообщение во всех окнах верхнего уровня, вызвав сообщение и указав HWND Top _ в параметре HWND .

Распространенная ошибка программирования заключается в том, что функция отправки сообщений всегда отправляет сообщение. Это не имеет значения, если очередь сообщений заполнена. Приложение должно проверить возвращаемое значение функции почтовых сообщений , чтобы определить, было ли сообщение отправлено, и, если оно не было, перенесите его.

отправка сообщений

Приложение обычно отправляет сообщение, чтобы уведомить процедуру окна о необходимости немедленного выполнения задачи. Функция SendMessage отправляет сообщение в процедуру окна, соответствующую заданному окну. Функция ожидает, пока процедура окна не завершит обработку, а затем вернет результат сообщения. Родительские и дочерние окна часто взаимодействуют, отправляя сообщения друг другу. Например, родительское окно, имеющее элемент управления "поле ввода" в качестве дочернего окна, может задать текст элемента управления, отправив ему сообщение. Элемент управления может уведомлять родительское окно об изменениях текста, которые выполняются пользователем, отправляя сообщения обратно в родительский объект.

Функция сендмессажекаллбакк также отправляет сообщение в процедуру окна, соответствующую заданному окну. Однако эта функция возвращает значение немедленно. После того, как процедура окна обработает сообщение, система вызывает указанную функцию обратного вызова. Дополнительные сведения о функции обратного вызова см. в описании функции сендасинкпрок .

Иногда может потребоваться отправить сообщение всем окнам верхнего уровня в системе. Например, если приложение изменяет системное время, оно должно уведомлять все окна верхнего уровня об изменении, отправляя сообщение WM _ тимечанже . Приложение может отправить сообщение всем окнам верхнего уровня, вызвав SendMessage и указав HWND Top _ в параметре HWND . Вы также можете транслировать сообщение во все приложения, вызвав функцию броадкастсистеммессаже и указав _ приложения BSM в параметре лпдвреЦипиентс .

С помощью функций SendMessage или инсендмессажеекс процедура окна может определить, обрабатывается ли сообщение, отправленное другим потоком. Эта возможность полезна, если обработка сообщений зависит от происхождения сообщения.

Взаимоблокировки сообщений

Поток, который вызывает функцию SendMessage для отправки сообщения в другой поток, не может продолжить выполнение до тех пор, пока не будет возвращена процедура окна, получающая сообщение. Если принимающий поток получает управление при обработке сообщения, то поток отправки не может продолжать выполнение, так как он ожидает возврата SendMessage . Если принимающий поток присоединен к той же очереди, что и отправитель, это может привести к взаимоблокировке приложения. (Обратите внимание, что обработчики журнала присоединяют потоки к одной очереди.)

Обратите внимание, что принимающему потоку не требуется явно управлять yield; вызов любой из следующих функций может привести к неявному получению потоком управления.

Чтобы избежать потенциальных взаимоблокировок в приложении, рассмотрите возможность использования функций сенднотифимессаже или функции sendmessagetimeout . В противном случае процедура окна может определить, было ли полученное сообщение отправлено другим потоком путем вызова функции SendMessage или инсендмессажеекс . Перед вызовом любой из функций из предыдущего списка при обработке сообщения процедура окна должна сначала вызвать SendMessage или инсендмессажеекс. Если эта функция возвращает значение true, то процедура Window должна вызывать функцию реплимессаже перед любой функцией, которая приводит к получению управления потоком.

Широковещательная рассылка сообщений

Каждое сообщение состоит из идентификатора сообщения и двух параметров: wParam и lParam. Идентификатор сообщения — это уникальное значение, указывающее назначение сообщения. Параметры предоставляют дополнительные сведения, относящиеся к конкретному сообщению, но параметр wParam обычно представляет собой значение типа, которое предоставляет дополнительные сведения о сообщении.

Вещание сообщения — это просто отправка сообщения нескольким получателям в системе. Чтобы выполнить широковещательную рассылку сообщения из приложения, используйте функцию броадкастсистеммессаже , указав получателей сообщения. Вместо того чтобы указывать отдельных получателей, необходимо указать одного или нескольких типов получателей. Эти типы являются приложениями, устанавливаемыми драйверами, сетевыми драйверами и драйверами устройств на уровне системы. Система отправляет широковещательные сообщения всем членам каждого указанного типа.

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

Система передает сообщения получателям в следующем порядке: драйверы устройств на уровне системы, сетевые драйверы, устанавливаемые драйверы и приложения. Это означает, что драйверы устройств системного уровня, если они выбраны в качестве получателей, всегда получат первую возможность ответить на сообщение. В пределах заданного типа получателя драйвер не гарантированно получает данное сообщение перед любым другим драйвером. Это означает, что сообщение, предназначенное для конкретного драйвера, должно иметь глобальный уникальный идентификатор сообщения, чтобы другой драйвер не мог его непреднамеренно обрабатывать.

Кроме того, сообщения можно рассылать во все окна верхнего уровня, задав _ широковещательное сообщение HWND в функции SendMessage, сендмессажекаллбакк, функции sendmessagetimeoutили сенднотифимессаже .

Приложения получают сообщения через процедуру окна своих окон верхнего уровня. Сообщения не отправляются в дочерние окна. Службы могут принимать сообщения с помощью процедуры окна или их обработчиков управления службами.

Примечание

Драйверы устройств на уровне системы используют связанную функцию на уровне системы для вещания системных сообщений.

Сообщения запроса

Вы можете создавать собственные пользовательские сообщения и использовать их для координации действий между приложениями и другими компонентами системы. Это особенно полезно, если вы создали собственные устанавливаемые драйверы или драйверы устройств на уровне системы. Пользовательские сообщения могут содержать сведения о драйвере и приложениях, использующих этот драйвер, и из него.

Чтобы опросить получателей для разрешения на выполнение заданного действия, используйте сообщение запроса. Вы можете создавать собственные сообщения запроса, задав значение _ запроса БСФ в параметре DwFlags при вызове броадкастсистеммессаже. Каждый получатель сообщения запроса должен возвращать значение true , чтобы функция отправляла сообщение следующему получателю. Если какой-либо получатель возвращает _ запрос на _ отклонение широковещательного запроса, вещание немедленно завершается, а функция возвращает ноль.