應用程式如何建立 WIA 裝置
當應用程式想要使用 WIA 設備磁碟機時,它會呼叫Microsoft Windows SDK檔) 中所述的IWiaDevMgr::CreateDevice方法 (。 WIA 服務會先呼叫 IStiUSD::LockDevice ,以鎖定 WIA 驅動程式以進行互斥存取。 接下來,WIA 服務會呼叫 IWiaMiniDrv::d rvInitializeWia 來建立初始 WIA 專案樹狀結構。 最後,WIA 服務會藉由呼叫 IStiUSD::UnLockDevice來解除鎖定設備磁碟機。
IWiaMiniDrv::d rvInitializeWia方法應該執行下列工作。
快取 pStiDevice 參數指向的介面,以取得適當的裝置鎖定。 (如需詳細資訊,請參閱 IWiaMiniDrv::d rvLockWiaDevice.)
建立初始 WIA 專案樹狀結構。
遞增目前的應用程式連線計數。 此計數是用來通知驅動程式應用程式是否仍然連線。 它也有助於判斷 在 IWiaMiniDrv::d rvUnInitializeWia中採取的適當動作。
WIA 專案應該以一些邏輯意義命名。 Microsoft 需要 Windows XP 和更新版本的下列專案名稱。
平板
這是僅支援平面掃描器的掃描器,或支援具有檔摘要器的平面掃描器的掃描器一詞。
WIA 服務會呼叫 IWiaMiniDrv::d rvInitializeWia 方法來回應 WIA 應用程式對 IWiaDevMgr::CreateDevice (的呼叫,如 Windows SDK 檔) 中所述。 因此,WIA 服務會針對每個新的用戶端連線呼叫 IWiaMiniDrv::d rvInitializeWia 方法。
IWiaMiniDrv::d rvInitializeWia方法應該初始化任何私用結構,並建立驅動程式專案樹狀結構。 驅動程式專案樹狀結構會顯示此 WIA 裝置支援的所有 WIA 專案配置。 這個方法只會用來建立初始樹狀結構, 而不是 WIA 屬性 (的內容) 。 WIA 服務會透過對 IWiaMiniDrv::d rvInitItemProperties 方法進行多次呼叫,個別填入 WIA 驅動程式專案的 WIA 屬性。
所有 WIA 裝置都有根專案,這是所有 WIA 裝置專案的父項。 若要建立 WIA 裝置專案,WIA 驅動程式應該呼叫 WIA 服務協助程式函式 wiasCreateDrvItem。
下列範例示範如何建立 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
//
}
若要建立 WIA 子專案,請直接位於上一個範例中建立的根專案底下,使用類似下列的程式碼。
注意 *** 請注意, 會呼叫 IWiaDrvItem::AddItemToFolder 方法,將新建立的子專案新增至根專案。
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;
}
下列範例示範 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;
}