Bagikan melalui


Cara Aplikasi Membuat Perangkat WIA

Ketika aplikasi berniat menggunakan driver perangkat WIA, aplikasi memanggil metode IWiaDevMgr::CreateDevice (dijelaskan dalam dokumentasi Microsoft Windows SDK). Layanan WIA pertama kali memanggil IStiUSD::LockDevice untuk mengunci driver WIA untuk akses yang saling eksklusif. Selanjutnya, layanan WIA memanggil IWiaMiniDrv::d rvInitializeWia untuk membuat struktur pohon item WIA awal. Akhirnya, layanan WIA membuka kunci driver perangkat dengan memanggil IStiUSD::UnLockDevice.

Metode IWiaMiniDrv::d rvInitializeWia harus melakukan tugas-tugas berikut.

  1. Cache antarmuka yang dirujuk parameter pStiDevice untuk penguncian perangkat yang tepat. (Untuk informasi selengkapnya, lihat IWiaMiniDrv::d rvLockWiaDevice.)

  2. Buat struktur pohon item WIA awal.

  3. Tingkatkan jumlah koneksi aplikasi saat ini. Jumlah ini digunakan untuk memberi tahu driver apakah aplikasi masih tersambung. Ini juga membantu menentukan tindakan yang tepat untuk diambil dalam IWiaMiniDrv::d rvUnInitializeWia.

Item WIA harus dinamai dengan beberapa arti logis. Microsoft memerlukan nama item berikut untuk Windows XP dan yang lebih baru.

Akar
Ini adalah istilah untuk item akar pohon item WIA.

Flatbed
Ini adalah istilah untuk pemindai yang hanya mendukung pemindai flatbed, atau pemindai yang mendukung pemindai flatbed dengan pengumpan dokumen.

Pengumpan
Ini adalah istilah untuk pemindai yang hanya mendukung pengumpan.

Layanan WIA memanggil metode IWiaMiniDrv::d rvInitializeWia sebagai respons terhadap panggilan aplikasi WIA ke IWiaDevMgr::CreateDevice (dijelaskan dalam dokumentasi Windows SDK). Konsekuensinya adalah bahwa layanan WIA memanggil metode IWiaMiniDrv::d rvInitializeWia untuk setiap koneksi klien baru.

Metode IWiaMiniDrv::d rvInitializeWia harus menginisialisasi struktur privat apa pun dan membuat pohon item driver. Pohon item driver menunjukkan tata letak semua item WIA yang didukung oleh perangkat WIA ini. Metode ini digunakan untuk membuat struktur pohon awal saja, bukan konten (properti WIA). Layanan WIA akan secara individual mengisi properti WIA untuk item driver WIA dengan melakukan beberapa panggilan ke metode IWiaMiniDrv::d rvInitItemProperties .

Semua perangkat WIA memiliki item root, yang merupakan induk dari semua item perangkat WIA. Untuk membuat item perangkat WIA, driver WIA harus memanggil fungsi pembantu layanan WIA, wiasCreateDrvItem.

Contoh berikut menunjukkan cara membuat item akar perangkat 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
  //

 }

Untuk membuat item anak WIA, yang terletak langsung di bawah item akar yang dibuat dalam contoh sebelumnya, gunakan kode yang mirip dengan yang berikut ini.

Catatan **** Perhatikan bahwa metode IWiaDrvItem::AddItemToFolder dipanggil untuk menambahkan item anak yang baru dibuat ke item akar.

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

Contoh berikut menunjukkan implementasi metode 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;
}