Witam, chciałbym napisać program, który skanuje obrazy, tak jak to robi zwykła aplikacja, jak np. program od HP. Do tej pory mam taki kod ale wyskakuje idtGetData failed.
#include <QCoreApplication>
#include <windows.h>
#include <stdio.h>
#include <wia.h>
#include <QDebug>
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "wiaguid.lib")
HRESULT hr;
IWiaDevMgr *pWiaDevMgr = NULL;
IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL;
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
IWiaItem *pWiaDevice = NULL;
PROPSPEC PropSpec[3] = {0};
PROPVARIANT PropVar[3] = {0};
IWiaDataTransfer *pWiaDataTransfer = NULL;
STGMEDIUM stgMedium = {0};
void exit_program(const char* exit_message)
{
// Clean up WIA / COM stuff
ReleaseStgMedium(&stgMedium);
if (pWiaDataTransfer) pWiaDataTransfer->Release();
FreePropVariantArray(3, PropVar);
if (pWiaDevice) pWiaDevice->Release();
if (pWiaPropertyStorage) pWiaPropertyStorage->Release();
if (pWiaEnumDevInfo) pWiaEnumDevInfo->Release();
if (pWiaDevMgr) pWiaDevMgr->Release();
CoUninitialize();
// If an error message was supplied print it
if (strlen(exit_message) > 0)
{
fprintf(stderr, exit_message);
fprintf(stderr, "\n");
exit(1);
}
// Exit the program normally
exit(0);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int devnum = 1;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) exit_program("Could not initialise COM");
hr = CoCreateInstance(
CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER,
IID_IWiaDevMgr, (void**)&pWiaDevMgr);
if (FAILED(hr)) exit_program("CoCreateInstance failed");
hr = pWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo);
if (FAILED(hr)) exit_program("EnumDeviceInfo failed");
fprintf(stderr, "Scanning WIA devices...\n");
int dev_count = 0;
while (hr == S_OK)
{
// Try to get IWiaPropertyStorage for next device
hr = pWiaEnumDevInfo->Next(1, &pWiaPropertyStorage, NULL);
// If there are no more devices, stop scanning
if (hr != S_OK) break;
// Found another device
dev_count++;
fprintf(stderr, "Found device %d\n", dev_count);
// If this is the requested device, break out of loop
if (dev_count == devnum) break;
// Release the current device's IWiaPropertyStorage
pWiaPropertyStorage->Release();
pWiaPropertyStorage = NULL;
}
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = WIA_DIP_DEV_ID;
PropSpec[1].ulKind = PRSPEC_PROPID;
PropSpec[1].propid = WIA_DIP_DEV_NAME;
PropSpec[2].ulKind = PRSPEC_PROPID;
PropSpec[2].propid = WIA_DIP_DEV_DESC;
hr = pWiaPropertyStorage->ReadMultiple(3, PropSpec, PropVar);
if (FAILED(hr)) exit_program("ReadMultiple failed");
QString convertedBSTR((QChar*) PropVar[0].bstrVal, wcslen(PropVar[0].bstrVal));
if (VT_BSTR == PropVar[0].vt) qDebug() << "WIA_DIP_DEV_ID : " << QString((QChar*) PropVar[0].bstrVal, wcslen(PropVar[0].bstrVal));
if (VT_BSTR == PropVar[1].vt) qDebug() << "WIA_DIP_DEV_ID : " << QString((QChar*) PropVar[1].bstrVal, wcslen(PropVar[1].bstrVal));
if (VT_BSTR == PropVar[2].vt) qDebug() << "WIA_DIP_DEV_ID : " << QString((QChar*) PropVar[2].bstrVal, wcslen(PropVar[2].bstrVal));
// if (VT_BSTR == PropVar[0].vt) fprintf(stderr, TEXT("WIA_DIP_DEV_ID: %ws\n"), PropVar[0].bstrVal );
// if (VT_BSTR == PropVar[1].vt) fprintf(stderr, TEXT("WIA_DIP_DEV_NAME: %ws\n"), PropVar[1].bstrVal );
// if (VT_BSTR == PropVar[2].vt) fprintf(stderr, TEXT("WIA_DIP_DEV_DESC: %ws\n"), PropVar[2].bstrVal );
hr = pWiaDevMgr->CreateDevice(PropVar[0].bstrVal, &pWiaDevice);
if (FAILED(hr)) exit_program("CreateDevice failed");
FreePropVariantArray(3, PropVar);
// Configure storage medium
GUID guidOutputFormat = WiaImgFmt_BMP;
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = WIA_IPA_FORMAT;
PropSpec[1].ulKind = PRSPEC_PROPID;
PropSpec[1].propid = WIA_IPA_TYMED;
PropVar[0].vt = VT_CLSID;
PropVar[0].puuid = &guidOutputFormat;
PropVar[1].vt = VT_I4;
PropVar[1].lVal = TYMED_FILE;
pWiaPropertyStorage->WriteMultiple(2, PropSpec, PropVar, WIA_IPA_FIRST);
if (FAILED(hr)) exit_program("WriteMultiple failed");
hr = pWiaDevice->QueryInterface(IID_IWiaDataTransfer, (void**)&pWiaDataTransfer);
if (FAILED(hr)) exit_program("QueryInterface IID_IWiaDataTransfer failed");
// stgMedium.tymed = TYMED_FILE;
// wchar_t* filename = L"temp.bmp";
// stgMedium.lpszFileName = filename;
LPWSTR pwszFileName = (LPWSTR)::CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR));
#ifdef UNICODE
::lstrcpy(pwszFileName, L"temp.bmp");
#else
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, "temp.bmp", -1, pwszFileName, MAX_PATH);
#endif
stgMedium.tymed = TYMED_FILE;
stgMedium.lpszFileName = pwszFileName;
// idtGetData is currently returning S_FALSE
hr = pWiaDataTransfer->idtGetData(&stgMedium, 0);
if (hr == E_INVALIDARG) fprintf(stderr, "E_INVALIDARG\n");
if (hr == E_OUTOFMEMORY) fprintf(stderr, "E_OUTOFMEMORY\n");
if (hr == E_UNEXPECTED) fprintf(stderr, "E_UNEXPECTED\n");
if (hr == S_FALSE) fprintf(stderr, "S_FALSE\n");
if (hr == S_OK) fprintf(stderr, "S_OK\n");
if (hr == STG_E_MEDIUMFULL) fprintf(stderr, "STG_E_MEDIUMFULL\n");
if (hr == WIA_S_NO_DEVICE_AVAILABLE) fprintf(stderr, "WIA_S_NO_DEVICE_AVAILABLE\n");
//if (FAILED(hr)) exit_program("idtGetData failed");
if (hr != S_OK) exit_program("idtGetData failed");
qDebug() << "Filename : " << stgMedium.lpszFileName;
//fprintf(stderr, TEXT("Filename: %ws\n"), stgMedium.lpszFileName);
// Not working!!
system("copy temp.bmp other.bmp");
// Release COM objects and exit
exit_program("");
return a.exec();
}