Come l'applicazione crea il dispositivo WIA
Quando un'applicazione intende usare un driver di dispositivo WIA, chiama il metodo IWiaDevMgr::CreateDevice (descritto nella documentazione Microsoft Windows SDK). Il servizio WIA chiama prima IStiUSD::LockDevice per bloccare il driver WIA per l'accesso reciproco esclusivo. Successivamente, il servizio WIA chiama IWiaMiniDrv::d rvInitializeWia per creare la struttura dell'albero degli elementi WIA iniziale. Infine, il servizio WIA sblocca il driver di dispositivo chiamando IStiUSD::UnLockDevice.
Il metodo IWiaMiniDrv::d rvInitializeWia deve eseguire le attività seguenti.
Memorizzare nella cache l'interfaccia a cui punta il parametro pStiDevice per il blocco del dispositivo appropriato. Per altre informazioni, vedere IWiaMiniDrv::d rvLockWiaDevice.
Creare la struttura dell'albero degli elementi WIA iniziale.
Incrementare il numero di connessioni dell'applicazione corrente. Questo conteggio viene usato per informare il driver se un'applicazione è ancora connessa. Consente anche di determinare l'azione appropriata da intraprendere in IWiaMiniDrv::d rvUnInitializeWia.
Gli elementi WIA devono essere denominati con un significato logico. Microsoft richiede i nomi degli elementi seguenti per Windows XP e versioni successive.
Radice
Questo è il termine per l'elemento radice dell'albero degli elementi WIA.
Pianale
Questo è il termine per uno scanner che supporta solo uno scanner a piano o uno scanner che supporta uno scanner flat con un alimentatore di documenti.
Alimentatore
Questo è il termine per uno scanner che supporta solo un feeder.
Il servizio WIA chiama il metodo IWiaMiniDrv::d rvInitializeWia in risposta alla chiamata di un'applicazione WIA a IWiaDevMgr::CreateDevice (descritta nella documentazione di Windows SDK). Di conseguenza, il servizio WIA chiama il metodo IWiaMiniDrv::d rvInitializeWia per ogni nuova connessione client.
Il metodo IWiaMiniDrv::d rvInitializeWia deve inizializzare tutte le strutture private e creare l'albero degli elementi del driver. L'albero degli elementi del driver mostra il layout di tutti gli elementi WIA supportati da questo dispositivo WIA. Questo metodo viene usato solo per creare la struttura ad albero iniziale, non il contenuto (proprietà WIA). Il servizio WIA popola singolarmente le proprietà WIA per gli elementi del driver WIA effettuando più chiamate al metodo IWiaMiniDrv::d rvInitItemProperties .
Tutti i dispositivi WIA hanno un elemento radice, che è l'elemento padre di tutti gli elementi del dispositivo WIA. Per creare un elemento del dispositivo WIA, il driver WIA deve chiamare la funzione helper del servizio WIA, wiasCreateDrvItem.
L'esempio seguente illustra come creare un elemento radice del 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
//
}
Per creare un elemento figlio WIA, che si trova direttamente sotto l'elemento radice creato nell'esempio precedente, usare codice simile al seguente.
Nota ** Si noti che il metodo IWiaDrvItem::AddItemToFolder viene chiamato per aggiungere l'elemento figlio appena creato all'elemento radice.
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;
}
L'esempio seguente mostra un'implementazione del metodo 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;
}