Wie die Anwendung das WIA-Gerät erstellt
Wenn eine Anwendung einen WIA-Gerätetreiber verwenden möchte, ruft sie die IWiaDevMgr::CreateDevice-Methode auf (in der Microsoft Windows SDK-Dokumentation beschrieben). Der WIA-Dienst ruft zuerst IStiUSD::LockDevice auf, um den WIA-Treiber für den sich gegenseitig ausschließenden Zugriff zu sperren. Als Nächstes ruft der WIA-Dienst IWiaMiniDrv::d rvInitializeWia auf, um die anfängliche STRUKTUR der WIA-Elementstruktur zu erstellen. Schließlich entsperrt der WIA-Dienst den Gerätetreiber, indem er IStiUSD::UnLockDevice aufruft.
Die IWiaMiniDrv::d rvInitializeWia-Methode sollte die folgenden Aufgaben ausführen.
Zwischenspeichern Sie die Schnittstelle, auf die der pStiDevice-Parameter verweist, um das Gerät ordnungsgemäß zu sperren. (Weitere Informationen finden Sie unter IWiaMiniDrv::d rvLockWiaDevice.)
Erstellen Sie die anfängliche STRUKTUR des WIA-Elements.
Erhöhen Sie die aktuelle Anwendungsverbindungsanzahl. Diese Anzahl wird verwendet, um den Treiber darüber zu informieren, ob eine Anwendung noch verbunden ist. Es hilft auch, die richtige Aktion in IWiaMiniDrv::d rvUnInitializeWia zu ermitteln.
WIA-Elemente sollten mit einer logischen Bedeutung benannt werden. Microsoft benötigt die folgenden Elementnamen für Windows XP und höher.
Wurzel
Dies ist der Begriff für das Stammelement der WIA-Elementstruktur.
Flachbett
Dies ist der Begriff für einen Scanner, der nur einen Flachbettscanner unterstützt, oder einen Scanner, der einen Flachbettscanner mit einem Dokumenteinzug unterstützt.
Feeder
Dies ist der Begriff für einen Scanner, der nur einen Feeder unterstützt.
Der WIA-Dienst ruft die IWiaMiniDrv::d rvInitializeWia-Methode als Reaktion auf den Aufruf von IWiaDevMgr::CreateDevice einer WIA-Anwendung auf (in der Windows SDK-Dokumentation beschrieben). Eine Folge davon ist, dass der WIA-Dienst die IWiaMiniDrv::d rvInitializeWia-Methode für jede neue Clientverbindung aufruft.
Die IWiaMiniDrv::d rvInitializeWia-Methode sollte alle privaten Strukturen initialisieren und die Treiberelementstruktur erstellen. Die Treiberelementstruktur zeigt das Layout aller WIA-Elemente an, die von diesem WIA-Gerät unterstützt werden. Diese Methode wird verwendet, um nur die anfängliche Strukturstruktur zu erstellen, nicht die Inhalte (WIA-Eigenschaften). Der WIA-Dienst füllt die WIA-Eigenschaften für die WIA-Treiberelemente einzeln auf, indem er mehrere Aufrufe der IWiaMiniDrv::d rvInitItemProperties-Methode ausführt.
Alle WIA-Geräte verfügen über ein Stammelement, das allen WIA-Geräteelementen übergeordnet ist. Um ein WIA-Geräteelement zu erstellen, sollte der WIA-Treiber die WIA-Diensthilfsfunktion wiasCreateDrvItem aufrufen.
Das folgende Beispiel zeigt, wie Sie ein WIA-Gerätestammelement erstellen.
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
//
}
Um ein untergeordnetes WIA-Element zu erstellen, das sich direkt unter dem im vorherigen Beispiel erstellten Stammelement befindet, verwenden Sie Code ähnlich dem folgenden.
Hinweis **** Beachten Sie, dass die IWiaDrvItem::AddItemToFolder-Methode aufgerufen wird, um das neu erstellte untergeordnete Element dem Stammelement hinzuzufügen.
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;
}
Das folgende Beispiel zeigt eine Implementierung der IWiaMiniDrv::d rvInitializeWia-Methode .
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;
}