Добавление поддержки событий опроса
Чтобы правильно настроить драйвер WIA для передачи данных о событиях опроса, сделайте следующее:
Задайте Capabilities=0x33 в INF-файле устройства. (Дополнительные сведения см. в разделе INF-файлы для устройств WIA .)
Отчет STI_GENCAP_NOTIFICATIONS и STI_USD_GENCAP_NATIVE_PUSHSUPPORT в методе IStiUSD::GetCapabilities .
Сообщите обо всех поддерживаемых событиях в методе IWiaMiniDrv::d rvGetCapabilities .
Отвечать на вызовы метода IStiUSD::GetStatus . Служба WIA вызывает этот метод через предустановленный интервал, который можно настроить в INF-файле. Значение по умолчанию — 1-секундный интервал.
Сообщите о правильном ответе сведений о событии в методе IStiUSD::GetNotificationData .
Служба WIA вызывает метод IStiUSD::GetStatus для двух основных операций:
Проверка состояния устройства в сети.
Опрос событий устройства, таких как событие push-кнопки.
Определить запрос операции можно, проверив элемент StatusMaskструктуры STI_DEVICE_STATUS . Элемент StatusMask может иметь один из следующих запросов:
STI_DEVSTATUS_ONLINE_STATE
Этот запрос операции проверяет, находится ли устройство в сети и должно ли быть заполнено, задав член dwOnlinesState структуры STI_DEVICE_STATUS.
STI_DEVSTATUS_EVENTS_STATE
Этот запрос операции проверяет наличие событий устройства. Его следует заполнить, задав член dwEventHandlingState структуры STI_DEVICE_STATUS. Значение, которое следует использовать, — STI_EVENTHANDLING_PENDING. (Устройство находится в ожидании события и ожидает передачи его в службу WIA.)
Если задано STI_EVENTHANDLING_PENDING, служба WIA получает сигнал о том, что в драйвере WIA произошло событие. Служба WIA вызывает метод IStiUSD::GetNotificationData для получения дополнительных сведений о событии.
Метод IStiUSD::GetNotificationData вызывается для опрашиваемых событий и событий прерывания. Именно в этом методе необходимо заполнить соответствующие сведения о событии, чтобы вернуться в службу WIA.
Примечание Всегда снимите флажок STI_EVENTHANDLING_PENDING в элементе dwEventHandlingState , чтобы убедиться, что он правильно задан при возникновении события устройства. Этот драйвер WIA должен задать для переменной-члена класса m_guidLastEvent правильный GUID события при обнаружении события. M_guidLastEvent проверяется позже, когда служба WIA вызывает метод IStiUSD::GetNotificationData. Переменная m_guidLastEvent-члена определена в классе CWIADevice (в следующем фрагменте кода), используемом для кэширования последнего сигнального события. После того как эта переменная-член была запрошена службой WIA, ей всегда присваивается значение GUID_NULL.
В следующем примере показана реализация метода IStiUSD::GetStatus .
STDMETHODIMP CWIADevice::GetStatus(PSTI_DEVICE_STATUS pDevStatus)
{
//
// If the caller did not pass in the correct parameters,
// then fail the call with E_INVALIDARG.
//
if(!pDevStatus)
{
return E_INVALIDARG;
}
HRESULT hr = S_OK;
//
// If we are asked, verify state of an event handler
//(front panel buttons, user controlled attachments, etc.).
//
// If your device requires polling, then this is where you would
// specify the event result.
// However, It is not recommended to have polled events.
// Interrupt events are better for performance, and reliability.
// See the SetNotificationsHandle method for how to
// implement interrupt events.
//
//
// clear the dwEventHandlingState field first to make sure we are really setting
// a pending event.
//
pDevStatus->dwEventHandlingState &= ~STI_EVENTHANDLING_PENDING;
if (pDevStatus->StatusMask & STI_DEVSTATUS_EVENTS_STATE) {
//
// set the polled event result here, for the GetNotificationData()
// method to read and report.
// (m_guidLastEvent will be read in GetNotificationData)
//
LONG lEventResult = 0;
PollMyDeviceForEvents(&lEventResult)
if(lEventResult == DEVICE_SCAN_BUTTON_PRESSED) {
//
// polled event result was one we know about
//
m_guidLastEvent = WIA_EVENT_SCAN_IMAGE;
} else {
//
// nothing happened, so continue
//
m_guidLastEvent = GUID_NULL;
}
if (m_guidLastEvent != GUID_NULL) {
//
// if the event GUID is NOT GUID_NULL, set the
// STI_EVENTHANDLING_PENDING flag letting the WIA service
// know that we have an event ready. This will tell the WIA
// service to call GetNotificationData() for the event
// specific information.
//
pDevStatus->dwEventHandlingState |= STI_EVENTHANDLING_PENDING;
}
}
return S_OK;
}