Cómo crea la aplicación el dispositivo WIA
Cuando una aplicación pretende usar un controlador de dispositivo WIA, llama al método IWiaDevMgr::CreateDevice (descrito en la documentación de Microsoft Windows SDK). El servicio WIA llama primero a IStiUSD::LockDevice para bloquear el controlador WIA para el acceso mutuamente exclusivo. A continuación, el servicio WIA llama a IWiaMiniDrv::d rvInitializeWia para crear la estructura inicial del árbol de elementos WIA. Por último, el servicio WIA desbloquea el controlador del dispositivo mediante una llamada a IStiUSD::UnLockDevice.
El método IWiaMiniDrv::d rvInitializeWia debe realizar las siguientes tareas.
Almacene en caché la interfaz a la que apunta el parámetro pStiDevice para el bloqueo adecuado del dispositivo. (Para obtener más información, vea IWiaMiniDrv::d rvLockWiaDevice).
Cree la estructura inicial del árbol de elementos WIA.
Incremente el número de conexiones de la aplicación actual. Este recuento se usa para informar al controlador de si una aplicación todavía está conectada. También ayuda a determinar la acción adecuada que se debe realizar en IWiaMiniDrv::d rvUnInitializeWia.
Los elementos WIA deben denominarse con algún significado lógico. Microsoft requiere los siguientes nombres de elemento para Windows XP y versiones posteriores.
Raíz
Este es el término para el elemento raíz del árbol de elementos WIA.
Plana
Este es el término de un escáner que solo admite un escáner plano o un escáner que admite un escáner plano con un alimentador de documentos.
Alimentador
Este es el término de un analizador que solo admite un alimentador.
El servicio WIA llama al método IWiaMiniDrv::d rvInitializeWia en respuesta a la llamada de una aplicación WIA a IWiaDevMgr::CreateDevice (descrita en la documentación de Windows SDK). Una consecuencia de esto es que el servicio WIA llama al método IWiaMiniDrv::d rvInitializeWia para cada nueva conexión de cliente.
El método IWiaMiniDrv::d rvInitializeWia debe inicializar las estructuras privadas y crear el árbol de elementos del controlador. El árbol de elementos del controlador muestra el diseño de todos los elementos WIA compatibles con este dispositivo WIA. Este método solo se usa para crear la estructura de árbol inicial, no el contenido (propiedades WIA). El servicio WIA rellenará individualmente las propiedades de WIA para los elementos del controlador WIA realizando varias llamadas al método IWiaMiniDrv::d rvInitItemProperties .
Todos los dispositivos WIA tienen un elemento raíz, que es el elemento primario de todos los elementos de dispositivo WIA. Para crear un elemento de dispositivo WIA, el controlador WIA debe llamar a la función auxiliar del servicio WIA, wiasCreateDrvItem.
En el ejemplo siguiente se muestra cómo crear un elemento raíz de dispositivo WIA.
LONG lItemFlags = WiaItemTypeFolder|WiaItemTypeDevice|WiaItemTypeRoot;
IWiaDrvItem *pIWiaDrvRootItem = NULL;
HRESULT hr =
wiasCreateDrvItem(
lItemFlags, // item flags
bstrRootItemName, // item name ("Root")
bstrRootFullItemName, // item full name ("0000\Root")
(IWiaMiniDrv *)this, // this WIA driver object
sizeof(MINIDRIVERITEMCONTEXT), // size of context
NULL, // context
&pIWiaDrvRootItem // created ROOT item
); // (IWiaDrvItem interface)
if(S_OK == hr){
//
// ROOT item was created successfully
//
}
Para crear un elemento secundario WIA, ubicado directamente en el elemento raíz creado en el ejemplo anterior, use código similar al siguiente.
Nota ** Observe que se llama al método IWiaDrvItem::AddItemToFolder para agregar el elemento secundario recién creado al elemento raíz.
LONG lItemFlags = WiaItemTypeFile|WiaItemTypeDevice|WiaItemTypeImage;
PMINIDRIVERITEMCONTEXT pItemContext = NULL;
IWiaDrvItem *pIWiaDrvNewItem = NULL;
HRESULT hr =
wiasCreateDrvItem(
lItemFlags, // item flags
bstrItemName, // item name ("Flatbed")
bstrFullItemName, // item full name ("0000\Root\Flatbed")
(IWiaMiniDrv *)this, // this WIA driver object
sizeof(MINIDRIVERITEMCONTEXT), // size of context
(PBYTE)&pItemContext, // context
&pIWiaDrvNewItem // created child item
); // (IWiaDrvItem interface)
if(S_OK == hr){
//
// A New WIA driver item was created successfully
//
hr = pIWiaDrvNewItem->AddItemToFolder(pIWiaDrvRootItem); // add the new item to the ROOT
if(S_OK == hr){
//
// successfully created and added a new WIA driver item to
// the WIA driver item tree.
//
}
pNewItem->Release();
pNewItem = NULL;
}
En el ejemplo siguiente se muestra una implementación del método IWiaMiniDrv::d rvInitializeWia .
HRESULT _stdcall CWIADevice::drvInitializeWia(
BYTE *pWiasContext,
LONG lFlags,
BSTR bstrDeviceID,
BSTR bstrRootFullItemName,
IUnknown *pStiDevice,
IUnknown *pIUnknownOuter,
IWiaDrvItem **ppIDrvItemRoot,
IUnknown **ppIUnknownInner,
LONG *plDevErrVal)
{
//
// If the caller did not pass in the correct parameters,
// then fail the call with E_INVALIDARG.
//
if (!pWiasContext) {
return E_INVALIDARG;
}
if (!plDevErrVal) {
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
*ppIDrvItemRoot = NULL;
*ppIUnknownInner = NULL;
if (m_pStiDevice == NULL) {
//
// save STI device interface for locking
//
m_pStiDevice = (IStiDevice *)pStiDevice;
}
//
// build WIA item tree
//
LONG lItemFlags = WiaItemTypeFolder|WiaItemTypeDevice|WiaItemTypeRoot;
IWiaDrvItem *pIWiaDrvRootItem = NULL;
//
// create the ROOT item of the WIA device. This name should NOT be
// localized in different languages. "Root" is used by WIA drivers.
//
BSTR bstrRootItemName = SysAllocString(WIA_DEVICE_ROOT_NAME);
if(!bstrRootItemName) {
return E_OUTOFMEMORY;
}
hr = wiasCreateDrvItem(lItemFlags, // item flags
bstrRootItemName, // item name ("Root")
bstrRootFullItemName, // item full name ("0000\Root")
(IWiaMiniDrv *)this, // this WIA driver object
sizeof(MINIDRIVERITEMCONTEXT), // size of context
NULL, // context
&pIWiaDrvRootItem); // created ROOT item
// (IWiaDrvItem interface)
if (S_OK == hr) {
//
// ROOT item was created successfully, save the newly created Root
// item in the pointer given by the WIA service (ppIDrvItemRoot).
//
*ppIDrvItemRoot = pIWiaDrvRootItem;
//
// Create a child item directly under the Root WIA item
//
lItemFlags = WiaItemTypeFile|WiaItemTypeDevice|WiaItemTypeImage;
PMINIDRIVERITEMCONTEXT pItemContext = NULL;
IWiaDrvItem *pIWiaDrvNewItem = NULL;
//
// create a name for the WIA child item. "Flatbed" is used by
// WIA drivers that support a flatbed scanner.
//
BSTR bstrItemName = SysAllocString(WIA_DEVICE_FLATBED_NAME);
if (bstrItemName) {
WCHAR wszFullItemName[MAX_PATH + 1] = {0};
_snwprintf(wszFullItemName,(sizeof(wszFullItemName) / sizeof(WCHAR)) - 1,L"%ls\\%ls",
bstrRootFullItemName,bstrItemName);
BSTR bstrFullItemName = SysAllocString(wszFullItemName);
if (bstrFullItemName) {
hr = wiasCreateDrvItem(lItemFlags, // item flags
bstrItemName, // item name ("Flatbed")
trFullItemName, // item full name ("0000\Root\Flatbed")
(IWiaMiniDrv *)this, // this WIA driver object
sizeof(MINIDRIVERITEMCONTEXT), // size of context
(BYTE**)&pItemContext, // context
&pIWiaDrvNewItem); // created child item
// (IWiaDrvItem interface)
if (S_OK == hr) {
//
// A New WIA driver item was created successfully
//
hr = pIWiaDrvNewItem->AddItemToFolder(pIWiaDrvRootItem); // add the new item to the ROOT
if (S_OK == hr) {
//
// successfully created and added a new WIA
// driver item to the WIA driver item tree.
//
}
//
// The new item is no longer needed, because it has
// been passed to the WIA service.
//
pIWiaDrvNewItem->Release();
pIWiaDrvNewItem = NULL;
}
SysFreeString(bstrFullItemName);
bstrFullItemName = NULL;
} else {
hr = E_OUTOFMEMORY;
}
SysFreeString(bstrItemName);
bstrItemName = NULL;
} else {
hr = E_OUTOFMEMORY;
}
}
//
// increment application connection count
//
if(S_OK == hr){
InterlockedIncrement(&m_lClientsConnected);
}
return hr;
}