Поделиться через


Добавление поддержки событий опроса

Чтобы правильно настроить драйвер WIA для передачи данных о событиях опроса, сделайте следующее:

  1. Задайте Capabilities=0x33 в INF-файле устройства. (Дополнительные сведения см. в разделе INF-файлы для устройств WIA .)

  2. Отчет STI_GENCAP_NOTIFICATIONS и STI_USD_GENCAP_NATIVE_PUSHSUPPORT в методе IStiUSD::GetCapabilities .

  3. Сообщите обо всех поддерживаемых событиях в методе IWiaMiniDrv::d rvGetCapabilities .

  4. Отвечать на вызовы метода IStiUSD::GetStatus . Служба WIA вызывает этот метод через предустановленный интервал, который можно настроить в INF-файле. Значение по умолчанию — 1-секундный интервал.

  5. Сообщите о правильном ответе сведений о событии в методе IStiUSD::GetNotificationData .

Служба WIA вызывает метод IStiUSD::GetStatus для двух основных операций:

  1. Проверка состояния устройства в сети.

  2. Опрос событий устройства, таких как событие 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;
}