Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++: COM, OLE, ActiveX
Войти
Регистрация
Восстановить пароль
 
DaniilSavin
0 / 0 / 0
Регистрация: 29.02.2016
Сообщений: 48
1

Сканирование через WIA

06.06.2019, 15:36. Просмотров 390. Ответов 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
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.06.2019, 15:36
Ответы с готовыми решениями:

WIA сканирование с заданными параметрами
Использую WIA для сканирования документов, как можно получить изображение со сканера, без вызова...

Как сделать скоростное многостраничное сканирование (twain или wia)
word: макрос: как сделать скоростное многостраничное сканирование (twain или wia) Макрос...

Сканирование IP через сокеты
Возникла такая проблема пишу программу которая должна управлять другим компом через socet и вот...

Почему при указании пути через имя компа сканирование не проходит, а через IP - проходит?
Всем доброго времени суток, Ситуация такая - Есть 3 компа с Windows 7 на борту (у всех их...

Сканирование железа через ЛВС
Необходимо написать программу со следующими функциями: - поиск доступных компьютеров в локальной...

0
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.06.2019, 15:36

Сканирование процесса через определенное время
Привет, как сделать сканирование процесса через опредиленное время например каждых 5-10 минут?

Сканирование и вызов печати через ассемблер
Нужен кусочек программы со сканированием и вызовом печати найденного

Использование WIA в WPF
Using WIA пишу вот так, в результате подчеркивает. Пространство имен не известно. в reference...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru