次の方法で共有


WIA 1.0 でのイメージ データの転送

注意

このチュートリアルでは、Windows XP 以前を実行するアプリケーションでイメージ データを転送する方法について説明します。 Windows Vista 以降で実行されるアプリケーションでのイメージ データの転送については、「 WIA 2.0 でのイメージ データの転送」を参照してください。

 

IWiaDataTransfer インターフェイスのメソッドを使用して、Windows イメージ取得 (WIA) 1.0 デバイスからアプリケーションにデータを転送します。 このインターフェイスでは、デバイス オブジェクトからアプリケーションにデータを転送し、マーシャリング中に不要なデータ コピーを排除するための共有メモリ ウィンドウがサポートされています。

アプリケーションでは、次のコード サンプルのように、イメージ項目に対してクエリを実行して、 その IWiaDataTransfer インターフェイスへのポインターを取得する必要があります。

    // Get the IWiaDataTransfer interface
    //
    IWiaDataTransfer *pWiaDataTransfer = NULL;
    hr = pWiaItem->QueryInterface( IID_IWiaDataTransfer, (void**)&pWiaDataTransfer );

前のコードでは、pWiaItem が IWiaItem インターフェイスへの有効なポインターであると想定されています。 IUnknown::QueryInterface の呼び出しは、pWiaItem によって参照されるアイテムの IWiaDataTransfer インターフェイスへのポインターで pWiaDataTransfer を埋めます。

その後、アプリケーションは STGMEDIUM 構造体メンバーを設定します。 詳細については、STGMEDIUM と TYMED に関するページを参照してください。

    // Set storage medium
    //
    STGMEDIUM StgMedium = {0};
    StgMedium.tymed = TYMED_FILE;

ファイル名を指定する場合は、適切なファイル拡張子を含める必要があります。WIA 1.0 では、ファイル拡張子は提供されません。 StgMediumlpszFileName メンバーが NULL の場合、WIA 1.0 は転送されたデータのランダムなファイル名とパスを生成します。 ReleaseStgMedium を呼び出す前に、このファイルを移動またはコピーします。これは、この関数によってファイルが削除されるためです。

その後、アプリケーションは IWiaDataTransfer::idtGetData メソッドを呼び出してデータ転送を実行します。

    // Perform the transfer
    //
    hr = pWiaDataTransfer->idtGetData( &stgMedium, pWiaDataCallback );

IWiaDataTransfer::idtGetData の呼び出しで、2 番目のパラメーターは IWiaDataCallback インターフェイスへのポインターを指定します。 アプリケーションでは、データ転送中にコールバックを受け取るために、このインターフェイスを実装する必要があります。 このインターフェイスの実装の詳細については、「 IWiaDataCallback::BandedDataCallback」を参照してください。

その後、アプリケーションは IWiaDataTransfer インターフェイスへのポインターを解放し、 STGMEDIUM 構造体に割り当てられたすべてのデータを解放します。

アプリケーションでは、ファイル転送ではなく、メモリ内データ転送を使用してイメージを転送することもできます。 この場合、アプリケーションは idtGetData メソッドの代わりに idtGetBandedData メソッドを使用します。

完全なデータ転送サンプルを次に示します。

HRESULT TransferWiaItem( IWiaItem *pWiaItem )
{
    //
    // Validate arguments
    //
    if (NULL == pWiaItem)
    {
        return E_INVALIDARG;
    }

    //
    // Get the IWiaPropertyStorage interface so you can set required properties.
    //
    IWiaPropertyStorage *pWiaPropertyStorage = NULL;
    HRESULT hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage );
    if (SUCCEEDED(hr))
    {
        //
        // Prepare PROPSPECs and PROPVARIANTs for setting the
        // media type and format
        //
        PROPSPEC PropSpec[2] = {0};
        PROPVARIANT PropVariant[2] = {0};
        const ULONG c_nPropCount = sizeof(PropVariant)/sizeof(PropVariant[0]);

        //
        // Use BMP as the output format
        //
        GUID guidOutputFormat = WiaImgFmt_BMP;

        //
        // Initialize the PROPSPECs
        //
        PropSpec[0].ulKind = PRSPEC_PROPID;
        PropSpec[0].propid = WIA_IPA_FORMAT;
        PropSpec[1].ulKind = PRSPEC_PROPID;
        PropSpec[1].propid = WIA_IPA_TYMED;

        //
        // Initialize the PROPVARIANTs
        //
        PropVariant[0].vt = VT_CLSID;
        PropVariant[0].puuid = &guidOutputFormat;
        PropVariant[1].vt = VT_I4;
        PropVariant[1].lVal = TYMED_FILE;

        //
        // Set the properties
        //
        hr = pWiaPropertyStorage->WriteMultiple( c_nPropCount, PropSpec, PropVariant, WIA_IPA_FIRST );
        if (SUCCEEDED(hr))
        {
            //
            // Get the IWiaDataTransfer interface
            //
            IWiaDataTransfer *pWiaDataTransfer = NULL;
            hr = pWiaItem->QueryInterface( IID_IWiaDataTransfer, (void**)&pWiaDataTransfer );
            if (SUCCEEDED(hr))
            {
                //
                // Create our callback class
                //
                CWiaDataCallback *pCallback = new CWiaDataCallback;
                if (pCallback)
                {
                    //
                    // Get the IWiaDataCallback interface from our callback class.
                    //
                    IWiaDataCallback *pWiaDataCallback = NULL;
                    hr = pCallback->QueryInterface( IID_IWiaDataCallback, (void**)&pWiaDataCallback );
                    if (SUCCEEDED(hr))
                    {
                        //
                        // Perform the transfer using default settings
                        //
                        STGMEDIUM stgMedium = {0};
                        StgMedium.tymed = TYMED_FILE;
                        hr = pWiaDataTransfer->idtGetData( &stgMedium, pWiaDataCallback );
                        if (S_OK == hr)
                        {
                            //
                            // Print the filename (note that this filename is always
                            // a WCHAR string, not TCHAR).
                            //
                            _tprintf( TEXT("Transferred filename: %ws\n"), stgMedium.lpszFileName );

                            //
                            // Release any memory associated with the stgmedium
                            // This will delete the file stgMedium.lpszFileName.
                            //
                            ReleaseStgMedium( &stgMedium );
                        }

                        //
                        // Release the callback interface
                        //
                        pWiaDataCallback->Release();
                        pWiaDataCallback = NULL;
                    }

                    //
                    // Release our callback.  It should now delete itself.
                    //
                    pCallback->Release();
                    pCallback = NULL;
                }

                //
                // Release the IWiaDataTransfer
                //
                pWiaDataTransfer->Release();
                pWiaDataTransfer = NULL;
            }
        }

        //
        // Release the IWiaPropertyStorage
        //
        pWiaPropertyStorage->Release();
        pWiaPropertyStorage = NULL;
    }

    return hr;
}