События оборудования
Некоторые звуковые устройства предоставляют аппаратные регуляторы громкости, переключатели отключения звука или другие типы ручных элементов управления. Приложения могут реагировать на изменения в этих элементах управления, изменяя громкость или иным образом изменяя способ воспроизведения звукового потока. Когда пользователь настраивает элемент управления оборудованием, драйвер мини-порта использует интерфейс IPortEvents , чтобы сообщить драйверу порта о возникновении аппаратного события. Драйвер порта, в свою очередь, уведомляет приложение о событии, чтобы он смог считывать новый параметр элемента управления с устройства.
Драйвер мини-порта может запрашивать драйвер порта для интерфейса IPortEvents во время обслуживания вызова Init (см . IMiniportWavePci::Init, например) из драйвера порта. В Microsoft Windows 98 SE, Windows Me и Windows 2000 и более поздних версиях этот запрос выполняется успешно. Пример кода см. в примере аудиоадаптера Sb16 в более ранних версиях комплекта драйверов Windows (WDK).
Когда драйвер порта вызывает метод IMiniport::GetDescription драйвера, метод выводит PCFILTER_DESCRIPTOR структуру, которая, среди прочего, определяет события, поддерживаемые вашим устройством. События можно указать в таблицах автоматизации для элементов Pins и Nodes PCFILTER_DESCRIPTOR, а также в элементе AutomationTable , который указывает на таблицу автоматизации для самого фильтра. Каждое событие задается структурой PCEVENT_ITEM . Драйвер должен задать элементы Set и Id структуры PCEVENT_ITEM KSEVENTSETID_AudioControlChange и KSEVENT_CONTROL_CHANGE, а также загрузить указатель на подпрограмму EventHandler драйвера в элемент Handler . Драйвер также должен задать бит PCEVENT_ITEM_FLAG_BASICSUPPORT в элементе Flags , чтобы указать базовую поддержку событий изменения управления, а также задать PCEVENT_ITEM_FLAG_ONESHOT и (или) PCEVENT_ITEM_FLAG_ENABLE битов, чтобы указать, что он поддерживает однократное и (или) повторяющееся уведомление.
Когда позже приложение вызывает функцию mixerOpen (описанную в документации по Microsoft Windows SDK) для запроса уведомления о конкретном событии, драйвер порта вызывает подпрограмму EventHandler драйвера с указателем на структуру PCEVENT_REQUEST. Элемент Verb этой структуры имеет значение PCEVENT_VERB_ADD, а его член EventItem указывает событие, которое необходимо включить. Структура PCEVENT_REQUEST также содержит указатель на структуру KSEVENT_ENTRY , которую драйвер должен рассматривать как непрозрачные системные данные. После включения события обработчик должен вызвать IPortEvents::AddEventToEventList с тем же KSEVENT_ENTRY указателем. При этом вызове обработчик подтверждает, что событие включено.
Когда происходит событие оборудования и подпрограмма прерывания работы драйвера обнаруживает отключение звука или изменение громкости, драйвер передает сигнал о событии драйверу порта, вызывая IPortEvents::GenerateEventList с набором параметров, описывающих событие. Например, следующий вызов описывает изменение элемента управления в узле линейного тома:
pPE->GenerateEventList(NULL, KSEVENT_CONTROL_CHANGE,
FALSE, ULONG(-1), TRUE, LINEOUT_VOL);
Во время этого вызова драйвер порта ищет в списке событий все события, соответствующие параметрам вызова, и отправляет уведомления клиентам, которые отслеживают эти события. В этом примере pPE является указателем на объект IPortEvents , а LINEOUT_VOL — это идентификатор узла, который драйвер мини-порта назначает узлу lineout-volume. Неопределенные параметры (например, GUID набора событий и идентификатор закрепления в предыдущем примере) рассматриваются как подстановочные знаки и всегда соответствуют соответствующим параметрам в списке.