Udostępnij przez


Dodaj obsługę zdarzeń ankietowania

Aby prawidłowo skonfigurować sterownik WIA w celu raportowania zdarzeń sondowania, wykonaj następujące czynności:

  1. Ustaw Capabilities=0x33 w pliku INF urządzenia. (Aby uzyskać szczegółowe informacje, zobacz pliki INF dla urządzeń WIA).

  2. Raport STI_GENCAP_NOTIFICATIONS i STI_USD_GENCAP_NATIVE_PUSHSUPPORT w metodzie IStiUSD::GetCapabilities.

  3. Zgłoś wszystkie obsługiwane zdarzenia w metodzie IWiaMiniDrv::drvGetCapabilities.

  4. Odpowiadanie na wywołania metody IStiUSD::GetStatus. Usługa WIA wywołuje tę metodę w określonym interwale, który można skonfigurować w pliku INF. Ustawieniem domyślnym jest 1-sekundowy interwał.

  5. Zgłoś prawidłową odpowiedź na informacje o zdarzeniach w metodzie IStiUSD::GetNotificationData.

Usługa WIA wywołuje metodę IStiUSD::GetStatus dla dwóch głównych operacji:

  1. Sprawdzanie stanu online urządzenia.

  2. Sondowanie zdarzeń urządzenia, takich jak zdarzenie naciśnięcia przycisku.

Określenie żądania operacji można wykonać, sprawdzając element StatusMask składowej struktury STI_DEVICE_STATUS. Element członkowski StatusMask może być jednym z następujących żądań:

STI_DEVSTATUS_ONLINE_STATE
To żądanie operacji sprawdza, czy urządzenie jest w trybie online i powinno być wypełnione przez ustawienie dwOnlinesState elementu członkowskiego struktury STI_DEVICE_STATUS.

STI_DEVSTATUS_EVENTS_STATE
To żądanie operacji sprawdza zdarzenia urządzenia. Należy go wypełnić, ustawiając pole dwEventHandlingState struktury STI_DEVICE_STATUS. Wartość, która powinna być używana, to STI_EVENTHANDLING_PENDING. (Urządzenie ma zdarzenie w toku i czeka na zgłoszenie go do usługi WIA.)

Gdy ustawiony jest STI_EVENTHANDLING_PENDING, usługa WIA otrzymuje sygnał, że w sterowniku WIA wystąpiło zdarzenie. Usługa WIA wywołuje metodę IStiUSD::GetNotificationData, aby uzyskać więcej informacji o zdarzeniu.

Metoda IStiUSD::GetNotificationData jest wywoływana dla zdarzeń sondowanych i zdarzeń przerwania. W tej metodzie należy wypełnić odpowiednie informacje o zdarzeniu, aby powrócić do usługi WIA.

Należy pamiętać, zawsze czyścić flagę STI_EVENTHANDLING_PENDING w dwEventHandlingState elementu członkowskiego, aby upewnić się, że jest on prawidłowo ustawiony po wystąpieniu zdarzenia urządzenia. Ten sterownik WIA powinien ustawić zmienną składową klasy m_guidLastEvent na prawidłowy identyfikator GUID zdarzenia po wykryciu zdarzenia. m_guidLastEvent jest sprawdzana później, gdy usługa WIA wywołuje metodę IStiUSD::GetNotificationData. Zmienna składowa m_guidLastEvent jest zdefiniowana w klasie CWIADevice (w poniższym fragmencie kodu), używanej do buforowania ostatniego zdarzenia. Po zażądaniu tej zmiennej składowej przez usługę WIA jest ona zawsze ustawiona na GUID_NULL.

Poniższy przykład przedstawia implementację metody 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;
}