添加轮询事件支持

若要正确设置 WIA 驱动程序以报告轮询事件,请执行以下操作:

  1. 在设备的 INF 文件中设置 Capabilities=0x33 。 (有关详细信息,请参阅 WIA 设备的 INF 文件 。)

  2. IStiUSD::GetCapabilities 方法中报告STI_GENCAP_NOTIFICATIONS和STI_USD_GENCAP_NATIVE_PUSHSUPPORT。

  3. 报告 IWiaMiniDrv::d rvGetCapabilities 方法中支持的所有事件。

  4. 响应对 IStiUSD::GetStatus 方法的 调用。 WIA 服务以在 INF 文件中可配置的预设间隔调用此方法。 默认设置为 1 秒间隔。

  5. IStiUSD::GetNotificationData 方法中报告正确的事件信息响应。

WIA 服务调用 IStiUSD::GetStatus 方法进行两个主要操作:

  1. 检查设备的联机状态。

  2. 轮询设备事件,例如按钮事件。

可以通过检查STI_DEVICE_STATUS结构的 StatusMask 成员来确定操作请求。 StatusMask 成员可以是以下请求之一:

STI_DEVSTATUS_ONLINE_STATE
此操作请求检查设备是否处于联机状态,应通过设置 STI_DEVICE_STATUS 结构的 dwOnlinesState 成员进行填充。

STI_DEVSTATUS_EVENTS_STATE
此操作请求检查设备事件。 它应通过设置 STI_DEVICE_STATUS 结构的 dwEventHandlingState 成员来填充。 应使用的值是STI_EVENTHANDLING_PENDING。 (设备有一个挂起的事件,正在等待将其报告给 WIA 服务。)

设置STI_EVENTHANDLING_PENDING后,WIA 服务会发出信号,指出 WIA 驱动程序中发生了事件。 WIA 服务调用 IStiUSD::GetNotificationData 方法以获取有关事件的详细信息。

IStiUSD::GetNotificationData 方法针对轮询事件和中断事件调用。 在此方法中,应填写正确的事件信息以返回到 WIA 服务。

注意 始终清除 dwEventHandlingState 成员中的STI_EVENTHANDLING_PENDING标志,以确保在发生设备事件时正确设置它。 检测到事件时,此 WIA 驱动程序应将 m_guidLastEvent 类成员变量设置为正确的事件 GUID。 以后 WIA 服务调用 IStiUSD::GetNotificationData 方法时会检查m_guidLastEventm_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;
}