IWiaDataTransfer :: idtGetData завершается с STG_E_MEDIUMFULL

Следовал инструкциям Microsoft по внедрению приложения MFC GUI, совместимого с XP, для чтения изображений с принтера / сканера Canon MF6540.

С lpszFileName в STGMEDIUM, оставленным в NULL, idtGetData терпит неудачу с STG_E_MEDIUMFULL.

Если для lpszFileName задано значение L «c: \ tmp \ foo.bmp», где «c: \ tmp» — это существующая папка, происходит сбой idtGetData с 0xC0000005.

Как я могу, пожалуйста, idtGetData? Благодарю.

// WIADlg.cpp : implementation file
//

#include "stdafx.h"#include "WIA.h"#include "WIADlg.h"#include "WIADataCallback.h"#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();

// Dialog Data
enum { IDD = IDD_ABOUTBOX };

protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()

// CWIADlg dialog

CWIADlg::CWIADlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CWIADlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_root = NULL;
m_scanner = NULL;
}

void CWIADlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CWIADlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CWIADlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_BUTTON_SCAN, &CWIADlg::OnBnClickedButtonScan)
END_MESSAGE_MAP()// CWIADlg message handlers

BOOL CWIADlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);         // Set big icon
SetIcon(m_hIcon, FALSE);        // Set small icon

// TODO: Add extra initialization here
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)&m_pWiaDevMgr);
if (FAILED(hr))
{
CString str;
str.Format("CoCreateInstance CLSID_WiaDevMsg failure %08X", hr);
MessageBox(str);
}

IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL;
hr = m_pWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo);
if (SUCCEEDED(hr))
{
// Loop until you get an error or pWiaEnumDevInfo->Next returns S_FALSE to signal the end of the list.
while (S_OK == hr)
{
// Get the next device's property storage interface pointer
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
hr = pWiaEnumDevInfo->Next(1, &pWiaPropertyStorage, NULL);

// pWiaEnumDevInfo->Next will return S_FALSE when the list is exhausted, so check for S_OK before using the returned value.
if (hr == S_OK)
{
// Do something with the device's IWiaPropertyStorage*
ReadSomeWiaProperties(pWiaPropertyStorage);

// Release the device's IWiaPropertyStorage*
pWiaPropertyStorage->Release();
pWiaPropertyStorage = NULL;
}
}

// If the result of the enumeration is S_FALSE (which is normal), change it to S_OK.
if (S_FALSE == hr)
{
hr = S_OK;
}

// Release the enumerator
pWiaEnumDevInfo->Release();
pWiaEnumDevInfo = NULL;
}

return TRUE;  // return TRUE  unless you set the focus to a control
}

void CWIADlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CWIADlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CWIADlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}

HRESULT CWIADlg::ReadSomeWiaProperties(IWiaPropertyStorage *pWiaPropertyStorage)
{
// Declare PROPSPECs and PROPVARIANTs, and initialize them to zero.
PROPSPEC PropSpec[3] = {0};
PROPVARIANT PropVar[3] = {0};

// How many properties are you querying for?
const ULONG c_nPropertyCount = sizeof(PropSpec)/sizeof(PropSpec[0]);

// Define which properties you want to read:
// Device ID.  This is what you would use to create the device.
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = WIA_DIP_DEV_ID;

// Device Name
PropSpec[1].ulKind = PRSPEC_PROPID;
PropSpec[1].propid = WIA_DIP_DEV_NAME;

// Device description
PropSpec[2].ulKind = PRSPEC_PROPID;
PropSpec[2].propid = WIA_DIP_DEV_DESC;

// Ask for the property values
HRESULT hr = pWiaPropertyStorage->ReadMultiple(c_nPropertyCount, PropSpec, PropVar);
if (SUCCEEDED(hr))
{
// IWiaPropertyStorage::ReadMultiple will return S_FALSE if some
// properties could not be read, so you have to check the return
// types for each requested item.
CString str;
WIA_DEVICE *device = new WIA_DEVICE;

// Check the return type for the device ID
if (VT_BSTR == PropVar[0].vt)
{
// Do something with the device ID
TRACE(TEXT("WIA_DIP_DEV_ID: %ws\n"), PropVar[0].bstrVal);
device->deviceID.Format("%ws", PropVar[0].bstrVal);
device->bstrDeviceID = SysAllocString(PropVar[0].bstrVal);
}

// Check the return type for the device name
if (VT_BSTR == PropVar[1].vt)
{
// Do something with the device name
TRACE(TEXT("WIA_DIP_DEV_NAME: %ws\n"), PropVar[1].bstrVal);
device->deviceName.Format("%ws", PropVar[1].bstrVal);
}

// Check the return type for the device description
if (VT_BSTR == PropVar[2].vt)
{
// Do something with the device description
TRACE(TEXT("WIA_DIP_DEV_DESC: %ws\n"), PropVar[2].bstrVal);
device->deviceDesc.Format("%ws", PropVar[2].bstrVal);
}

CListBox *list = (CListBox*)GetDlgItem(IDC_LIST_WIA_DEVICES);
int nIndex = list->AddString((LPCTSTR)device->deviceName);
list->SetItemDataPtr(nIndex, device);

// Free the returned PROPVARIANTs
FreePropVariantArray(c_nPropertyCount, PropVar);
}

// Return the result of reading the properties
return hr;
}void CWIADlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
CDialogEx::OnOK();
}void CWIADlg::OnBnClickedButtonScan()
{
// TODO: Add your control notification handler code here
CListBox *list = (CListBox*)GetDlgItem(IDC_LIST_WIA_DEVICES);
int nIndex = list->GetCurSel();
if (nIndex < 0)
{
MessageBox("No device selected");
return;
}

WIA_DEVICE *device = (WIA_DEVICE*)list->GetItemDataPtr(nIndex);
MessageBox(device->deviceName);

HRESULT hr = m_pWiaDevMgr->CreateDevice(device->bstrDeviceID, &m_root);
if (FAILED(hr))
{
CString str;
str.Format("CreateDevice failure %08X", hr);
MessageBox(str);
}
EnumerateItems(m_root);
TransferWiaItem(m_root, m_scanner);
}

HRESULT CWIADlg::EnumerateItems(IWiaItem *pWiaItem)
{
CString str;
// Get the item type for this item.
LONG lItemType = 0;
HRESULT hr = pWiaItem->GetItemType(&lItemType);
if (SUCCEEDED(hr))
{
str.Format("pWiaItem=%08X", pWiaItem);
if (lItemType & WiaItemTypeAnalyze)
str += " WiaItemTypeAnalyze";
if (lItemType & WiaItemTypeAudio)
str += " WiaItemTypeAudio";
if (lItemType & WiaItemTypeBurst)
str += " WiaItemTypeBurst";
if (lItemType & WiaItemTypeDeleted)
str += " WiaItemTypeDeleted";
if (lItemType & WiaItemTypeDevice)
str += " WiaItemTypeDevice";
if (lItemType & WiaItemTypeDisconnected)
str += " WiaItemTypeDisconnected";
if (lItemType & WiaItemTypeDocument)
str += " WiaItemTypeDocument";
if (lItemType & WiaItemTypeFile)
str += " WiaItemTypeFile";
if (lItemType & WiaItemTypeFolder)
str += " WiaItemTypeFolder";
if (lItemType & WiaItemTypeFree)
str += " WiaItemTypeFree";
if (lItemType & WiaItemTypeGenerated)
str += " WiaITemTypeGenerated";
if (lItemType & WiaItemTypeHasAttachments)
str += " WiaItemTypeHasAttachments";
if (lItemType & WiaItemTypeHPanorama)
str += " WiaItemTypeHPanorama";
if (lItemType & WiaItemTypeImage)
{
str += " WiaItemTypeImage";
m_scanner = pWiaItem;
}
if (lItemType & WiaItemTypeProgrammableDataSource)
str += " WiaItemTypeProgrammableDataSource";
if (lItemType & WiaItemTypeRemoved)
str += " WiaItemTypeRemoved";
if (lItemType & WiaItemTypeRoot)
str += " WiaItemTypeRoot";
if (lItemType & WiaItemTypeStorage)
str += " WiaItemTypeStorage";
if (lItemType & WiaItemTypeTransfer)
str += " WiaItemTypeTransfer";
//      if (lItemType & WiaItemTypeTwainCapabilityPassThrough)
//          str += " WiaItemTypeTwainCapabilityPassThrough";
if (lItemType & WiaItemTypeVideo)
str += " WiaItemTypeVideo";
if (lItemType & WiaItemTypeVPanorama)
str += " WiaItemTypeVPanorama";
MessageBox(str);

// If it is a folder, or it has attachments, enumerate its children.
if (lItemType & WiaItemTypeFolder || lItemType & WiaItemTypeHasAttachments)
{
// Get the child item enumerator for this item.
IEnumWiaItem *pEnumWiaItem = NULL;

hr = pWiaItem->EnumChildItems(&pEnumWiaItem);
if (SUCCEEDED(hr))
{
// Loop until you get an error or pEnumWiaItem->Next returns S_FALSE to signal the end of the list.
while (S_OK == hr)
{
str.Format("pEnumWiaItem=%08X", pEnumWiaItem);
MessageBox(str);
// Get the next child item.
IWiaItem *pChildWiaItem = NULL;

hr = pEnumWiaItem->Next(1, &pChildWiaItem, NULL);

// pEnumWiaItem->Next will return S_FALSE when the list is
// exhausted, so check for S_OK before using the returned
// value.
if (S_OK == hr)
{
str.Format("pChildWiaItem=%08X", pChildWiaItem);
MessageBox(str);
// Recurse into this item.
hr = EnumerateItems(pChildWiaItem);
#if 0
// Release this item.
str.Format("Releasing %08X", pChildWiaItem);
MessageBox(str);
pChildWiaItem->Release();
pChildWiaItem = NULL;
#endif
}
}

// If the result of the enumeration is S_FALSE (which is normal), change it to S_OK.
if (S_FALSE == hr)
{
hr = S_OK;
}

// Release the enumerator.
pEnumWiaItem->Release();
pEnumWiaItem = NULL;
}
}
}
return hr;
}

HRESULT CWIADlg::TransferWiaItem(IWiaItem *root, IWiaItem *scanner)
{
CString str;
// Get the IWiaPropertyStorage interface so you can set required properties.
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
HRESULT hr = root->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 = scanner->QueryInterface(IID_IWiaDataTransfer, (void**)&pWiaDataTransfer);
if (SUCCEEDED(hr))
{
#if 1
// 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))
{
AfxMessageBox("calling idtGetData");
// Perform the transfer using default settings
STGMEDIUM stgMedium = {0};
stgMedium.tymed = TYMED_FILE;
stgMedium.lpszFileName = L"c:\\tmp\\foo.bmp";
hr = pWiaDataTransfer->idtGetData(&stgMedium, pWiaDataCallback);
if (S_OK == hr)
{
// Print the filename (note that this filename is always a WCHAR string, not TCHAR).
str.Format("Transferred filename: %ws", stgMedium.lpszFileName);
AfxMessageBox(str);

// Release any memory associated with the stgmedium This will delete the file stgMedium.lpszFileName.
ReleaseStgMedium(&stgMedium);
}
else
{
str.Format("idtGetData failure=%08X", hr);
AfxMessageBox(str);
}

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

// Release our callback.  It should now delete itself.
pCallback->Release();
pCallback = NULL;
}
#else
// Perform the transfer using default settings
STGMEDIUM stgMedium = {0};
stgMedium.tymed = TYMED_FILE;
//              stgMedium.lpszFileName = L"c:\\tmp\\foo.bmp";
hr = pWiaDataTransfer->idtGetData(&stgMedium, NULL);
if (S_OK == hr)
{
// Print the filename (note that this filename is always a WCHAR string, not TCHAR).
str.Format(TEXT("Transferred filename: %ws"), stgMedium.lpszFileName);
MessageBox(str);

// Release any memory associated with the stgmedium This will delete the file stgMedium.lpszFileName.
ReleaseStgMedium(&stgMedium);
}
else
{
str.Format("idtGetData failure=%08X", hr);
MessageBox(str);
}
#endif
// Release the IWiaDataTransfer
pWiaDataTransfer->Release();
pWiaDataTransfer = NULL;
}
else
{
str.Format("TransferWiaItem::QueryInterface IID_IWiaDataTransfer failure=%08X", hr);
MessageBox(str);
}
}
else
{
str.Format("TransferWiaItem::WriteMultiple failure=%08X", hr);
MessageBox(str);
}

// Release the IWiaPropertyStorage
pWiaPropertyStorage->Release();
pWiaPropertyStorage = NULL;
}
else
{
str.Format("TransferWiaItem::QueryInterface IID_IWiaPropertyStorage failure=%08X", hr);
MessageBox(str);
}

return hr;
}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]