添加轮询事件支持
若要正确设置 WIA 驱动程序以报告轮询事件,请执行以下操作:
在设备的 INF 文件中设置 Capabilities=0x33 。 (有关详细信息,请参阅 WIA 设备的 INF 文件 。)
在 IStiUSD::GetCapabilities 方法中报告STI_GENCAP_NOTIFICATIONS和STI_USD_GENCAP_NATIVE_PUSHSUPPORT。
报告 IWiaMiniDrv::d rvGetCapabilities 方法中支持的所有事件。
响应对 IStiUSD::GetStatus 方法的 调用。 WIA 服务以在 INF 文件中可配置的预设间隔调用此方法。 默认设置为 1 秒间隔。
在 IStiUSD::GetNotificationData 方法中报告正确的事件信息响应。
WIA 服务调用 IStiUSD::GetStatus 方法进行两个主要操作:
检查设备的联机状态。
轮询设备事件,例如按钮事件。
可以通过检查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_guidLastEvent。 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;
}