Сканирование через WIA
06.06.2019, 15:36. Показов 13948. Ответов 0
Всем привет, не могу понять в чем проблема, нужно сканировать изображение без каких либо диалоговых окон
Windows 10, сканера два, оба canon, для проверки делал все прям как тут
файл WiaScan.h
C++ (Qt) | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
| #pragma once
#include "wia_lh.h"
#include "Wia.h"
#include "combaseapi.h"
#include <iostream>
#include <QDebug>
#include "shlwapi.h"
#include "atlbase.h"
#include "wiadef.h"
class WIAScan
{
public:
explicit WIAScan(IWiaDevMgr2 ** deviceManager);
~WIAScan() { CoUninitialize(); }
private:
IWiaDevMgr2 * devMgr;
IWiaItem2 ** wiaItem;
BSTR devId;
QString devName;
HRESULT CreateWiaDeviceManager(IWiaDevMgr2 **ppWiaDevMgr);
HRESULT EnumerateWiaDevices(IWiaDevMgr2 *pWiaDevMgr);
HRESULT ReadSomeWiaProperties(IWiaPropertyStorage *pWiaPropertyStorage);
HRESULT CreateWiaDevice(IWiaDevMgr2 *pWiaDevMgr, BSTR bstrDeviceID, IWiaItem2 **ppWiaDevice);
HRESULT EnumerateItems(IWiaItem2 *pWiaItem);
HRESULT TransferWiaItem(IWiaItem2 *pIWiaItem);
void PrintCommands(IWiaItem2 * item);
class CWiaDataCallback : public IWiaTransferCallback//IWiaDataCallback
{
private:
LONG m_cRef; // Object reference count
PBYTE m_pBuffer; // Data buffer
LONG m_nBufferLength; // Length of buffer
LONG m_nBytesTransfered; // Total number of bytes transferred
GUID m_guidFormat; // Data format
public:
CWiaDataCallback() : m_cRef(1), m_pBuffer(NULL), m_nBufferLength(0), m_nBytesTransfered(0), m_guidFormat(IID_NULL) { }
~CWiaDataCallback()
{
if (m_pBuffer)
{
LocalFree(m_pBuffer);
m_pBuffer = NULL;
}
m_nBufferLength = 0;
m_nBytesTransfered = 0;
}
HRESULT CALLBACK QueryInterface(REFIID riid, void **ppvObject)
{
if (NULL == ppvObject)
return E_INVALIDARG;
if (IsEqualIID(riid, IID_IUnknown))
*ppvObject = static_cast<CWiaDataCallback *>(this);
else if (IsEqualIID(riid, IID_IWiaDataCallback))
*ppvObject = static_cast<CWiaDataCallback *>(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;
}
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<PWIA_DATA_CALLBACK_HEADER>(pbData);
if (pHeader && pHeader->lBufferSize)
{
m_pBuffer = reinterpret_cast<PBYTE>(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)
{
qDebug() << "Transfer from device\n";
}
else if (lStatus & IT_STATUS_PROCESSING_DATA)
{
qDebug() << "Processing Data\n";
}
else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT)
{
qDebug() << "Transfer to Client\n";
}
qDebug() << "lPercentComplete: " << lPercentComplete << "\n";
}
break;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE TransferCallback(LONG lFlags, __RPC__in WiaTransferParams *pWiaTransferParams) { std::cout << "TransferCallback";
return S_OK;
}
HRESULT STDMETHODCALLTYPE GetNextStream(LONG lFlags, __RPC__in BSTR bstrItemName, __RPC__in BSTR bstrFullItemName, _Outptr_result_maybenull_ _At_(*ppDestination, _When_(return == S_OK, _Post_notnull_)) IStream **ppDestination) { std::cout << "GetNextStream";
return S_OK;
}
};
}; |
|
файл WiaScan.cpp
C++ (Qt) | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
| #include "WiaScan.h"
WIAScan::WIAScan(IWiaDevMgr2 ** deviceManager) : wiaItem(new IWiaItem2 *)
{
CoInitialize(NULL);
if (SUCCEEDED(CreateWiaDeviceManager(deviceManager)))
if (SUCCEEDED(EnumerateWiaDevices(*deviceManager)))
if (SUCCEEDED(CreateWiaDevice(*deviceManager, devId, wiaItem)))
if (SUCCEEDED(EnumerateItems(*wiaItem)))
TransferWiaItem(*wiaItem);
else
std::cout << "Enumerate items error";
else
std::cout << "Creation error";
else
std::cout << "Enumerate wia error";
else
std::cout << "Manager error";
}
HRESULT WIAScan::CreateWiaDeviceManager(IWiaDevMgr2 **ppWiaDevMgr)
{
*ppWiaDevMgr = NULL;
HRESULT hr = CoCreateInstance(CLSID_WiaDevMgr2, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr2, (void**)ppWiaDevMgr);
return hr;
}
HRESULT WIAScan::EnumerateWiaDevices(IWiaDevMgr2 *ppWiaDevMgr)
{
IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL;
HRESULT hr = ppWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo);
if (SUCCEEDED(hr))
{
while (S_OK == hr)
{
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
hr = pWiaEnumDevInfo->Next(1, &pWiaPropertyStorage, NULL);
if (hr == S_OK)
{
ReadSomeWiaProperties(pWiaPropertyStorage);
pWiaPropertyStorage->Release();
pWiaPropertyStorage = NULL;
}
}
if (S_FALSE == hr)
return hr;
pWiaEnumDevInfo->Release();
pWiaEnumDevInfo = NULL;
}
return hr;
}
HRESULT WIAScan::ReadSomeWiaProperties(IWiaPropertyStorage *pWiaPropertyStorage)
{
if (NULL == pWiaPropertyStorage)
return E_INVALIDARG;
PROPSPEC PropSpec[3] = { 0 };
PROPVARIANT PropVar[3] = { 0 };
const ULONG c_nPropertyCount = sizeof(PropSpec) / sizeof(PropSpec[0]);
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;
HRESULT hr = pWiaPropertyStorage->ReadMultiple(c_nPropertyCount, PropSpec, PropVar);
if (SUCCEEDED(hr))
{
if (VT_BSTR == PropVar[0].vt)
devId = SysAllocString(PropVar[0].bstrVal);
if (VT_BSTR == PropVar[1].vt)
devName = QString::fromWCharArray(PropVar[1].bstrVal);
FreePropVariantArray(c_nPropertyCount, PropVar);
}
return hr;
}
HRESULT WIAScan::CreateWiaDevice(IWiaDevMgr2 *pWiaDevMgr, BSTR bstrDeviceID, IWiaItem2 **ppWiaDevice)
{
if (NULL == pWiaDevMgr || NULL == bstrDeviceID || NULL == ppWiaDevice)
return E_INVALIDARG;
*ppWiaDevice = NULL;
HRESULT hr = pWiaDevMgr->CreateDevice(NULL, bstrDeviceID, ppWiaDevice);
return hr;
}
HRESULT WIAScan::EnumerateItems(IWiaItem2 *pWiaItem)
{
if (NULL == pWiaItem)
return E_INVALIDARG;
LONG lItemType = 0;
HRESULT hr = pWiaItem->GetItemType(&lItemType);
if (SUCCEEDED(hr))
{
if (lItemType & WiaItemTypeFolder || lItemType & WiaItemTypeHasAttachments)
{
IEnumWiaItem2 *pEnumWiaItem = NULL;
hr = pWiaItem->EnumChildItems(NULL, &pEnumWiaItem);
if (SUCCEEDED(hr))
{
while (S_OK == hr)
{
IWiaItem2 *pChildWiaItem = NULL;
hr = pEnumWiaItem->Next(1, &pChildWiaItem, NULL);
if (S_OK == hr)
{
LONG lItemType = 0;
hr = pChildWiaItem->GetItemType(&lItemType);
if (lItemType & WiaItemTypeFolder || lItemType & WiaItemTypeHasAttachments)
{
hr = EnumerateItems(pChildWiaItem);
PrintCommands(pChildWiaItem);
}
pChildWiaItem->Release();
pChildWiaItem = NULL;
}
}
if (S_FALSE == hr)
hr = S_OK;
pEnumWiaItem->Release();
pEnumWiaItem = NULL;
}
}
}
return hr;
}
HRESULT WIAScan::TransferWiaItem(IWiaItem2 *pIWiaItem2)
{
if (NULL == pIWiaItem2)
return E_INVALIDARG;
IWiaTransfer * pWiaTransfer = NULL;
HRESULT hr = pIWiaItem2->QueryInterface(IID_IWiaTransfer, (void**)&pWiaTransfer);
if (SUCCEEDED(hr))
{
CWiaDataCallback * pWiaClassCallback = new CWiaDataCallback;
IWiaItem2 ** ppWiaItemChild = new IWiaItem2 *;
IWiaItem2 * pWiaItemChild = NULL;
CComBSTR bzUploadFileName (L"ImageItem");
hr = pIWiaItem2->CreateChildItem(WiaItemTypeTransfer, 0, bzUploadFileName, ppWiaItemChild);
if (pWiaClassCallback)
{
LONG lItemType = 0;
hr = pIWiaItem2->GetItemType(&lItemType);
//if (lItemType & WiaItemTypeTransfer)
{
/*if ((lItemType & WiaItemTypeFolder))
{
std::cout << "\nI am a folder item";
hr = pWiaTransfer->Download(NULL, pWiaClassCallback);
if (S_OK == hr)
std::cout << "\npWiaTransfer->Download() on folder item SUCCEEDED";
else if (S_FALSE == hr)
std::cout << "\npWiaTransfer->Download() on folder item returned S_FALSE. Folder may not be having child items" << hr;
else if (FAILED(hr))
std::cout << "\npWiaTransfer->Download() on folder item failed" << hr;
}
else if (lItemType & WiaItemTypeFile)*/
{
hr = pWiaTransfer->Download(0, pWiaClassCallback);
if (S_OK == hr)
std::cout << "\npWiaTransfer->Download() on file item SUCCEEDED";
else if (S_FALSE == hr)
std::cout << "\npWiaTransfer->Download() on file item returned S_FALSE. File may be empty" << hr;
else if (FAILED(hr))
std::cout << "\npWiaTransfer->Download() on file item failed" << hr;
}
}
pWiaClassCallback->Release();
pWiaClassCallback = NULL;
}
else
std::cout << "\nUnable to create CWiaTransferCallback class instance";
pWiaTransfer->Release();
pWiaTransfer = NULL;
}
else
std::cout << "\npIWiaItem2->QueryInterface failed on IID_IWiaTransfer" << hr;
return hr;
}
void WIAScan::PrintCommands(IWiaItem2* item)
{
IEnumWIA_DEV_CAPS* caps = 0;
HRESULT h = item->EnumDeviceCapabilities(WIA_DEVICE_COMMANDS, &caps);
if (SUCCEEDED(h))
{
ULONG count = 0;
caps->GetCount(&count);
if (count > 0)
{
WIA_DEV_CAP* cap = new WIA_DEV_CAP[count];
ULONG fetched;
caps->Next(count, cap, &fetched);
for (int i = 0; i < fetched; i++)
std::cout << cap[i].bstrName << "\n";
}
caps->Release();
}
} |
|
скорее всего в тексте есть какие то мои ошибки, в основном все копировал по ссылке
проблема в подключении к устройству, процедура вывода команд, в ней только 4 пункта Syncronize/Delete all items/Delete device tree/Build device tree. я так понял должны быть в т.ч Take picture или как то так.
item->DeviceCommand(NULL, &WIA_CMD_BUILD_DEVICE_TREE, &item); - работает, но ничего не меняет в дереве
через item->DeviceDialog(........) запускается стандартное wia окно, через него работает сканирование, но мне нужно без него сделать
item->CreateChildItem(WiaItemTypeImage, NULL, imgName, wiaImageItem); - E_NOTIMPL
item->DeviceCommand(NULL, &WIA_CMD_TAKE_PICTURE, wiaImageItem); - соответственно из предыдущей команда, тоже не работает, может не хватает какой нибудь инициализации Com порта, имя устройства, его id и описание драйвера читаются
0
|