IWiaDataCallback
COM公式ドキュメント
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。
データ転送の状態通知を提供します。IWiaDataTransfer インターフェイスの Windows Image Acquisition (WIA) データ転送メソッドは、このメソッドを定期的に呼び出します。
| lMessage | INT | in | コールバックの理由を示す定数を指定します。次のいずれかの値を指定できます。 IT_MSG_DATAWIA システムがアプリケーションにデータを転送しています。 IT_MSG_DATA_HEADERアプリケーションは、実際のデータを受け取る前にヘッダーを受け取っています。 IT_MSG_DEVICE_STATUSWindows Vista 以降。デバイスの状態が変化しました。 IT_MSG_FILE_PREVIEW_DATAWIA システムがアプリケーションにプレビューデータを転送しています。 IT_MSG_FILE_PREVIEW_DATA_HEADERアプリケーションは、実際のプレビューデータを受け取る前にヘッダーを受け取っています。 IT_MSG_NEW_PAGEデータ転送が新しいページを開始します。 IT_MSG_STATUSこのコールバックの呼び出しは、状態情報のみを送信します。 IT_MSG_TERMINATIONデータ転送が完了しました。 |
| lStatus | INT | in | WIA デバイスの状態を示す定数を指定します。次の値の組み合わせを設定できます。 IT_STATUS_TRANSFER_FROM_DEVICE現在、WIA デバイスからデータが転送されています。 IT_STATUS_PROCESSING_DATA現在、データが処理されています。 IT_STATUS_TRANSFER_TO_CLIENT現在、クライアントのデータバッファーにデータが転送されています。 |
| lPercentComplete | INT | in | これまでに転送されたデータの割合 (パーセント) を指定します。 |
| lOffset | INT | in | 現在のデータバンドが開始するバッファー先頭からのオフセットをバイト単位で指定します。 |
| lLength | INT | in | 現在のデータバンドの長さをバイト単位で指定します。 |
| lReserved | INT | in | WIA ランタイムシステムの内部使用のために予約されています。 |
| lResLength | INT | in | WIA ランタイムシステムの内部使用のために予約されています。 |
| pbBuffer | BYTE* | inout | データバッファーへのポインター。 |
戻り値
解説(Remarks)
アプリケーションは IWiaDataCallback::BandedDataCallback メソッドを実装して提供する必要があります。このメソッドは、IWiaDataTransfer インターフェイスのデータ転送メソッドによって定期的に呼び出されます。これにより、データ転送中の状態メッセージがアプリケーションに提供されます。S_FALSE を返すことで、このメソッドを使ってデータ転送を途中で終了させることもできます。
このメソッドが呼び出されると、lMessage パラメーターに呼び出しの理由が格納されます。すべての呼び出しですべてのパラメーターにデータが格納されるわけではありません。たとえば、IWiaDataCallback::BandedDataCallback が IT_MSG_TERMINATION メッセージで呼び出された場合、pbBuffer、lOffset、lLength の各パラメーターの値を使用しようとしてはいけません。
lMessage の値が IT_MSG_DATA の場合、pbBuffer が指すバッファーには画像データのバンドが格納されています。lOffset パラメーターには、現在のデータバンドが開始するバッファー先頭からのオフセットがバイト単位で格納されます。lLength パラメーターには、現在のデータバンドの長さがバイト単位で指定されます。
lMessage が IT_MSG_DATA または IT_MSG_STATUS に設定された呼び出しでは、lStatus パラメーターに有効な値が格納されます。lMessage がその他の値の場合、その内容を使用してはいけません。
lMessage が IT_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 メソッドを定期的に呼び出します。最初の呼び出しでは状態メッセージが送信されます。続いて、データヘッダーをコールバックメソッドに転送する呼び出しが行われます。アプリケーションがデータヘッダーを受け取った後、idtGetBandedData は CDataCallback::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 公式リファレンス: 英語 (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 方式にも切替可。#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,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。