次の方法で共有


アプリケーションで WIA デバイスを作成する方法

アプリケーションで WIA デバイス ドライバーを使用する場合は、IWiaDevMgr::CreateDevice メソッドを呼び出します (Microsoft Windows SDK のドキュメントで説明)。 WIA サービスは、最初に IStiUSD::LockDevice を呼び出し、WIA ドライバーを相互に排他的にアクセスできるようにロックします。 次に、WIA サービスは IWiaMiniDrv::d rvInitializeWia を呼び出し、初期 WIA 項目ツリー構造を作成します。 最後に、WIA サービスは、IStiUSD::UnLockDevice を呼び出すことにより、デバイス ドライバーのロックを解除します。

IWiaMiniDrv::d rvInitializeWia メソッドは、次のタスクを実行する必要があります。

  1. pStiDevice パラメーターが指すインターフェイスをキャッシュして、デバイスを適切にロックします。 (詳細は、IWiaMiniDrv::d rvLockWiaDevice をご覧ください。)

  2. 初期 WIA 項目ツリー構造を作成します。

  3. 現在のアプリケーション接続数を増やします。 この数は、アプリケーションがまだ接続されているかどうかをドライバーに通知するために使用されます。 また、IWiaMiniDrv::d rvUnInitializeWia で実行する適切なアクションを決定するのにも役立ちます。

WIA 項目には、論理的な意味を持つ名前を付けてください。 Microsoft では、Windows XP 以降で次の項目名が必要です。

Root
これは、WIA 項目ツリーのルート項目の用語です。

Flatbed
これは、フラットベッド スキャナーのみに対応するスキャナー、またはドキュメント フィーダーを備えたフラットベッド スキャナーに対応するスキャナーの用語です。

Feeder
これは、フィーダーのみに対応するスキャナーの用語です。

WIA サービスは、WIA アプリケーションによる IWiaDevMgr::CreateDevice の呼び出し (Windows SDK ドキュメントで説明) に応答し、IWiaMiniDrv::d rvInitializeWia メソッドを呼び出します。 その結果、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;
 }

次のコード例は、ValidateAndCacheConnectionInfo メソッドの実装を示しています。

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;
}