Win32 API 日本語リファレンス
ホームDevices.ImageAcquisition › IWiaDataCallback

IWiaDataCallback

COM
IIDa558a866-a5b0-11d2-a08f-00c04f72dc3c継承元IUnknown自前メソッド開始 vtbl3

公式ドキュメント

Windows Image Acquisition (WIA) ハードウェアデバイスからアプリケーションへのデータ転送中に、アプリケーション側のコールバック機構を提供します。注意 Windows Vista 向けアプリケーションでは、IWiaDataCallback の代わりに IWiaTransferCallback を使用してください。

解説(Remarks)

IWiaDataCallback インターフェイスは、すべての Component Object Model (COM) インターフェイスと同様に、IUnknown インターフェイスのメソッドを継承します。

IUnknown のメソッド 説明
IUnknown::QueryInterface サポートされているインターフェイスへのポインターを返します。
IUnknown::AddRef 参照カウントをインクリメントします。
IUnknown::Release 参照カウントをデクリメントします。

メソッド 1

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 3 HRESULT BandedDataCallback(INT lMessage, INT lStatus, INT lPercentComplete, INT lOffset, INT lLength, INT lReserved, INT lResLength, BYTE* pbBuffer)

データ転送の状態通知を提供します。IWiaDataTransfer インターフェイスの Windows Image Acquisition (WIA) データ転送メソッドは、このメソッドを定期的に呼び出します。

lMessageINTin

コールバックの理由を示す定数を指定します。次のいずれかの値を指定できます。

IT_MSG_DATA

WIA システムがアプリケーションにデータを転送しています。

IT_MSG_DATA_HEADER

アプリケーションは、実際のデータを受け取る前にヘッダーを受け取っています。

IT_MSG_DEVICE_STATUS

Windows Vista 以降。デバイスの状態が変化しました。

IT_MSG_FILE_PREVIEW_DATA

WIA システムがアプリケーションにプレビューデータを転送しています。

IT_MSG_FILE_PREVIEW_DATA_HEADER

アプリケーションは、実際のプレビューデータを受け取る前にヘッダーを受け取っています。

IT_MSG_NEW_PAGE

データ転送が新しいページを開始します。

IT_MSG_STATUS

このコールバックの呼び出しは、状態情報のみを送信します。

IT_MSG_TERMINATION

データ転送が完了しました。

lStatusINTin

WIA デバイスの状態を示す定数を指定します。次の値の組み合わせを設定できます。

IT_STATUS_TRANSFER_FROM_DEVICE

現在、WIA デバイスからデータが転送されています。

IT_STATUS_PROCESSING_DATA

現在、データが処理されています。

IT_STATUS_TRANSFER_TO_CLIENT

現在、クライアントのデータバッファーにデータが転送されています。

lPercentCompleteINTinこれまでに転送されたデータの割合 (パーセント) を指定します。
lOffsetINTin現在のデータバンドが開始するバッファー先頭からのオフセットをバイト単位で指定します。
lLengthINTin現在のデータバンドの長さをバイト単位で指定します。
lReservedINTinWIA ランタイムシステムの内部使用のために予約されています。
lResLengthINTinWIA ランタイムシステムの内部使用のために予約されています。
pbBufferBYTE*inoutデータバッファーへのポインター。

戻り値

型: HRESULT

メソッドが成功した場合、S_OK を返します。データ転送をキャンセルするには S_FALSE を返します。メソッドが失敗した場合は、標準の COM エラーコードを返します。

解説(Remarks)

アプリケーションは IWiaDataCallback::BandedDataCallback メソッドを実装して提供する必要があります。このメソッドは、IWiaDataTransfer インターフェイスのデータ転送メソッドによって定期的に呼び出されます。これにより、データ転送中の状態メッセージがアプリケーションに提供されます。S_FALSE を返すことで、このメソッドを使ってデータ転送を途中で終了させることもできます。

このメソッドが呼び出されると、lMessage パラメーターに呼び出しの理由が格納されます。すべての呼び出しですべてのパラメーターにデータが格納されるわけではありません。たとえば、IWiaDataCallback::BandedDataCallbackIT_MSG_TERMINATION メッセージで呼び出された場合、pbBufferlOffsetlLength の各パラメーターの値を使用しようとしてはいけません。

lMessage の値が IT_MSG_DATA の場合、pbBuffer が指すバッファーには画像データのバンドが格納されています。lOffset パラメーターには、現在のデータバンドが開始するバッファー先頭からのオフセットがバイト単位で格納されます。lLength パラメーターには、現在のデータバンドの長さがバイト単位で指定されます。

lMessageIT_MSG_DATA または IT_MSG_STATUS に設定された呼び出しでは、lStatus パラメーターに有効な値が格納されます。lMessage がその他の値の場合、その内容を使用してはいけません。

lMessageIT_MSG_DATA_HEADER の場合、pbBuffer パラメーターは WIA_DATA_CALLBACK_HEADER 構造体を指します。

画像データ転送中にエラーが発生した場合、ドライバーは lMessage を IT_MSG_DEVICE_STATUS に設定します。プロキシコールバックオブジェクトは ReportStatus を呼び出し、これがエラーを処理してユーザーにメッセージを表示します。

次の例は、IWiaDataCallback::BandedDataCallback メソッドを実装する方法の一例を示しています。

このサンプルアプリケーションのコードでは、IWiaDataCallback インターフェイスから派生した CDataCallback オブジェクトを定義しています。アプリケーションは CDataCallback オブジェクトをインスタンス化する必要があります。その後、CDataCallback::QueryInterface を呼び出して IWiaDataCallback インターフェイスポインターを取得します。データを受け取る準備ができたら、idtGetBandedData メソッドを呼び出し、IWiaDataCallback インターフェイスへのポインターを渡します。

idtGetBandedData メソッドは、IWiaDataCallback インターフェイスポインターを使用して、アプリケーションの CDataCallback::BandedDataCallback メソッドを定期的に呼び出します。最初の呼び出しでは状態メッセージが送信されます。続いて、データヘッダーをコールバックメソッドに転送する呼び出しが行われます。アプリケーションがデータヘッダーを受け取った後、idtGetBandedDataCDataCallback::BandedDataCallback を呼び出してアプリケーションにデータを転送します。データ転送が完了すると、最後にコールバックメソッドを呼び出して終了メッセージを送信します。


//
// アプリケーションは "new" 演算子を使用して CDataCallback オブジェクトを
// インスタンス化し、QueryInterface を呼び出して IWiaDataCallback
// インターフェイスを取得する必要があります。
//
// この例では、メモリ内転送を使用しており、アプリケーションは続いて
// IWiaDataTransfer::idtGetBandedData メソッドを呼び出し、
// IWiaDataCallback インターフェイスポインターを渡します。
//
// アプリケーションが IWiaDataTransfer::idtGetData を使用してファイル転送を
// 行う場合は、状態メッセージのみが送信され、データはファイルで転送されます。
//
class CDataCallback : public IWiaDataCallback
{
private:
    LONG  m_cRef;               // オブジェクトの参照カウント 
    PBYTE m_pBuffer;            // データバッファー
    LONG  m_nBufferLength;      // バッファーの長さ
    LONG  m_nBytesTransfered;   // 転送された総バイト数
    GUID  m_guidFormat;         // データ形式

public:
    
    //
    // コンストラクターとデストラクター
    //
    CDataCallback()
      : m_cRef(1),
        m_pBuffer(NULL),
        m_nBufferLength(0),
        m_nBytesTransfered(0),
        m_guidFormat(IID_NULL)
    {
    }
    ~CDataCallback()
    {
        //
        // アイテムのバッファーを解放します
        //
        if (m_pBuffer)
        {
            LocalFree( m_pBuffer );
            m_pBuffer = NULL;
        }
        m_nBufferLength = 0;
        m_nBytesTransfered = 0;
    }

    //
    // IUnknown のメソッド
    //
    HRESULT CALLBACK QueryInterface( REFIID riid, void **ppvObject )
    {
        //
        // 引数を検証します
        //
        if (NULL == ppvObject)
        {
            return E_INVALIDARG;
        }

        //
        // 適切なインターフェイスを返します
        //
        if (IsEqualIID( riid, IID_IUnknown ))
        {
            *ppvObject = static_cast<CDataCallback *>(this);
        }
        else if (IsEqualIID( riid, IID_IWiaDataCallback ))
        {
            *ppvObject = static_cast<CDataCallback *>(this);
        }
        else
        {
            *ppvObject = NULL;
            return(E_NOINTERFACE);
        }

        //
        // インターフェイスを返す前に参照カウントをインクリメントします。
        //
        reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
        return S_OK;
    }
    ULONG CALLBACK AddRef()
    {
        return InterlockedIncrement(&m_cRef);
    }    
    ULONG CALLBACK Release()
    {
        LONG cRef = InterlockedDecrement(&m_cRef);
        if (0 == cRef)
        {
            delete this;
        }
        return cRef;
    }

    //
    // IWiaDataTransfer::idtGetBandedData メソッドは、状態メッセージとともに
    // IWiaDataCallback::BandedDataCallback メソッドを定期的に呼び出します。
    // コールバックメソッドにデータヘッダーメッセージを送信し、続いて 1 つ以上の
    // データメッセージを送信してデータを転送します。最後に終了メッセージを
    // 送信して完了します。
    //
    
    HRESULT _stdcall BandedDataCallback(
            LONG lMessage,
            LONG lStatus,
            LONG lPercentComplete,
            LONG lOffset,
            LONG lLength,
            LONG lReserved,
            LONG lResLength,
            BYTE *pbData)
    {
        UNREFERENCED_PARAMETER(lReserved);
        UNREFERENCED_PARAMETER(lResLength);
        switch (lMessage)
        {
        case IT_MSG_DATA_HEADER:
            {
                //
                // データヘッダーには画像の最終的なサイズが含まれます。
                //
                PWIA_DATA_CALLBACK_HEADER pHeader = reinterpret_cast(pbData);
                if (pHeader && pHeader->lBufferSize)
                {
                    //
                    // 画像を保持するメモリブロックを確保します
                    //
                    m_pBuffer = reinterpret_cast(LocalAlloc(LPTR,pHeader->lBufferSize));
                    if (m_pBuffer)
                    {
                        //
                        // バッファーサイズを保存します。
                        //
                        m_nBufferLength = pHeader->lBufferSize;

                        //
                        // 転送済みバイト数を初期化します。
                        //
                        m_nBytesTransfered = 0;

                        //
                        // ファイル形式を保存します。
                        //
                        m_guidFormat = pHeader->guidFormatID;
                    }
                }
            }
            break;

        case IT_MSG_DATA:
            {
                //
                // メモリブロックが作成済みであることを確認します。
                //
                if (NULL != m_pBuffer)
                {
                    //
                    // 新しいバンドをコピーします。
                    //
                    CopyMemory( m_pBuffer + lOffset, pbData, lLength );

                    //
                    // バイト数を加算します。
                    //
                    m_nBytesTransfered += lLength;
                }
            }
            break;

        case IT_MSG_STATUS:
            {
                //
                // 転送フェーズを表示します
                //
                if (lStatus & IT_STATUS_TRANSFER_FROM_DEVICE)
                {
                    _tprintf(TEXT("Transfer from device\n"));
                }
                else if (lStatus & IT_STATUS_PROCESSING_DATA)
                {
                    _tprintf(TEXT("Processing Data\n"));
                }
                else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT)
                {
                    _tprintf(TEXT("Transfer to Client\n"));
                }

                //
                // 完了率を表示します
                //
                _tprintf( TEXT("lPercentComplete: %d\n"), lPercentComplete );
            }
            break;
        }

        return S_OK;
    }
};
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

HSP用 COM定義

#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"

出力引数:
#define global IID_IWiaDataCallback "{A558A866-A5B0-11D2-A08F-00C04F72DC3C}"
#usecom global IWiaDataCallback IID_IWiaDataCallback "{}"
#comfunc global IWiaDataCallback_BandedDataCallback  3 int,int,int,int,int,int,int,var
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。