Передача данных изображений в WIA 2.0
Примечание
В этом руководстве показано, как передавать данные образов в приложениях, работающих под управлением Windows Vista или более поздних версий. Сведения о передаче данных образов в приложениях, работающих под управлением Windows XP или более ранних версий, см. в статье Передача данных образов в WIA 1.0 .
Так как передача данных изображений в Windows Image Acquisition (WIA) 2.0 осуществляется по потоку, вам не нужно указывать тип назначения (например, память или файл). Приложение просто предоставляет WIA 2.0 поток для использования, а драйвер выполняет чтение или запись в поток. Поток может быть потоком файлов, потоком памяти или любым другим типом потока и прозрачным для драйвера. Использование потоков также обеспечивает простую интеграцию с фильтром обработки изображений.
Используйте методы интерфейса IWiaTransfer для передачи данных с устройства WIA 2.0 в приложение. Этот интерфейс доступен через интерфейс IWiaItem2 . Интерфейс IWiaTransfer содержит методы для запроса отправки или скачивания данных на устройство и с устройства. Эти методы принимают обратный вызов, предоставляемый приложением, и используют IStream , предоставленный приложением, для фактического назначения передачи данных.
Приложения должны запрашивать элемент изображения, чтобы получить указатель на его интерфейс IWiaTransfer , как показано в следующем примере кода:
// Get the IWiaTransfer interface
//
IWiaTransfer *pWiaTransfer = NULL;
hr = pIWiaItem2->QueryInterface(IID_IWiaTransfer,(void**)&pWiaTransfer);
В предыдущем коде предполагается, что pWiaItem2 является допустимым указателем на интерфейс IWiaItem2 . Вызов IUnknown::QueryInterface заполняет pWiaTransfer указателем на интерфейс IWiaTransfer элемента, на который ссылается pWiaItem2.
Затем приложение создает экземпляр объекта обратного вызова, как показано ниже.
// Instantiate the object which receives the callbacks
//
CWiaTransferCallback *pWiaClassCallback = new CWiaTransferCallback;
Затем приложение задает свойства с помощью интерфейса IWiaPropertyStorage элемента IWiaItem2 и выполняет передачу.
Загрузки:
// Download
hr = pWiaTransfer->Download(0,pWiaClassCallback);
Загрузки:
//Create child item which eventually will be the uploaded image
IWiaItem2* pWiaItemChild = NULL;
HRESULT hr = pIWiaItem2->CreateChildItem(WiaItemTypeImage|WiaItemTypeFile,0,bzUploadFileName,&pWiaItemChild);
if(SUCCEEDED(hr))
{
//Set the format for the child item as BMP
IWiaPropertyStorage* pWiaChildPropertyStorage = NULL;
hr = pWiaItemChild->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaChildPropertyStorage );
if(SUCCEEDED(hr))
{
WritePropertyGuid(pWiaChildPropertyStorage,WIA_IPA_FORMAT,WiaImgFmt_BMP );
//release pWiaChildPropertyStorage
pWiaChildPropertyStorage->Release();
pWiaChildPropertyStorage = NULL;
}
//Get the IWiaTransfer interface of the child
IWiaTransfer* pWiaTransferChild = NULL;
hr = pWiaItemChild->QueryInterface( IID_IWiaTransfer, (void**)&pWiaTransferChild );
if(SUCCEEDED(hr)){
IStream* pUploadStream = NULL;
//Create stream on test.BMP file
hr = SHCreateStreamOnFile(L"test.BMP",STGM_READ, &pUploadStream);
if(SUCCEEDED(hr)){
pWiaTransferChild->Upload(0,pUploadStream,pWiaClassCallback);
}
}
}
Ниже приведен полный пример передачи данных.
HRESULT TransferWiaItem( IWiaItem2 *pIWiaItem2)
{
// Validate arguments
if (NULL == pIWiaItem2)
{
_tprintf(TEXT("\nInvalid parameters passed"));
return E_INVALIDARG;
}
// Get the IWiaTransfer interface
IWiaTransfer *pWiaTransfer = NULL;
HRESULT hr = pIWiaItem2->QueryInterface( IID_IWiaTransfer, (void**)&pWiaTransfer );
if (SUCCEEDED(hr))
{
// Create our callback class
CWiaTransferCallback *pWiaClassCallback = new CWiaTransferCallback;
if (pWiaClassCallback)
{
LONG lItemType = 0;
hr = pIWiaItem2->GetItemType( &lItemType );
//download all items which have WiaItemTypeTransfer flag set
if(lItemType & WiaItemTypeTransfer)
{
// If it is a folder, do folder download . Hence with one API call, all the leaf nodes of this folder
// will be transferred
if ((lItemType & WiaItemTypeFolder))
{
_tprintf ( L"\nI am a folder item");
hr = pWiaTransfer->Download(WIA_TRANSFER_ACQUIRE_CHILDREN, pWiaClassCallback);
if(S_OK == hr)
{
_tprintf(TEXT("\npWiaTransfer->Download() on folder item SUCCEEDED"));
}
else if(S_FALSE == hr)
{
ReportError(TEXT("\npWiaTransfer->Download() on folder item returned S_FALSE. Folder may not be having child items"),hr);
}
else if(FAILED(hr))
{
ReportError(TEXT("\npWiaTransfer->Download() on folder item failed"),hr);
}
}
// If this is an file type, do file download
else if (lItemType & WiaItemTypeFile )
{
hr = pWiaTransfer->Download(0,pWiaClassCallback);
if(S_OK == hr)
{
_tprintf(TEXT("\npWiaTransfer->Download() on file item SUCCEEDED"));
}
else if(S_FALSE == hr)
{
ReportError(TEXT("\npWiaTransfer->Download() on file item returned S_FALSE. File may be empty"),hr);
}
else if(FAILED(hr))
{
ReportError(TEXT("\npWiaTransfer->Download() on file item failed"),hr);
}
}
}
// Release our callback. It should now delete itself.
pWiaClassCallback->Release();
pWiaClassCallback = NULL;
}
else
{
ReportError( TEXT("\nUnable to create CWiaTransferCallback class instance") );
}
// Release the IWiaTransfer
pWiaTransfer->Release();
pWiaTransfer = NULL;
}
else
{
ReportError( TEXT("\npIWiaItem2->QueryInterface failed on IID_IWiaTransfer"), hr );
}
return hr;
}
// Callback Class should be something like this:
class CWiaTransferCallback : public IWiaTransferCallback
{
public: // Constructors, destructor
CWiaTransferCallback () : m_cRef(1) {};
~ CWiaTransferCallback () {};
public: // IWiaTransferCallback
HRESULT __stdcall TransferCallback(
LONG lFlags,
WiaTransferParams *pWiaTransferParams)
{
HRESULT hr = S_OK;
switch (pWiaTransferParams->lMessage)
{
case WIA_TRANSFER_MSG_STATUS:
...
break;
case WIA_TRANSFER_MSG_END_OF_STREAM:
...
break;
case WIA_TRANSFER_MSG_END_OF_TRANSFER:
...
break;
default:
break;
}
return hr;
}
HRESULT __stdcall GetNextStream(
LONG lFlags,
BSTR bstrItemName,
BSTR bstrFullItemName,
IStream **ppDestination)
{
HRESULT hr = S_OK;
// Return a new stream for this item's data.
//
hr = CreateDestinationStream(bstrItemName, ppDestination);
return hr;
}
public: // IUnknown
.
.
. // Etc.
private:
/// For ref counting implementation
LONG m_cRef;
};