调整TWAIN头文件位置;调整TWAIN界面调用;更改USB-BULK错误返回及OVELAPPED对象使用

This commit is contained in:
gb 2023-04-04 13:50:10 +08:00
parent ddb7aafffc
commit 0bddeb4634
8 changed files with 410 additions and 257 deletions

View File

@ -10,6 +10,7 @@
//#include <winioctl.h> //#include <winioctl.h>
#include <usbscan.h> #include <usbscan.h>
#include <Dbt.h> #include <Dbt.h>
#include <ntstatus.h> // for STATUS_CANCELLED - 0xC0000120
#pragma comment(lib, "setupapi.lib") #pragma comment(lib, "setupapi.lib")
#pragma comment(lib, "hid.lib") #pragma comment(lib, "hid.lib")
@ -78,7 +79,7 @@ std::wstring ansi2unicode(const char* ansi, UINT cp = CP_ACP)
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// OVERLAPPED ... // OVERLAPPED ...
ovl_cls::ovl_cls() : ref_(1), io_bytes_(0) ovl_cls::ovl_cls(uint32_t type) : ref_(1), io_bytes_(0), type_(type)
{ {
memset(&ovl_, 0, sizeof(ovl_)); memset(&ovl_, 0, sizeof(ovl_));
ovl_.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); ovl_.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
@ -109,6 +110,14 @@ bool ovl_cls::is_waited(void)
{ {
return WaitForSingleObject(ovl_.hEvent, 0) == WAIT_OBJECT_0; return WaitForSingleObject(ovl_.hEvent, 0) == WAIT_OBJECT_0;
} }
void ovl_cls::notify(void)
{
SetEvent(ovl_.hEvent);
}
uint32_t ovl_cls::type(void)
{
return type_;
}
ovl_mgr::ovl_mgr() ovl_mgr::ovl_mgr()
{} {}
@ -118,14 +127,14 @@ ovl_mgr::~ovl_mgr()
v->release(); v->release();
} }
ovl_cls* ovl_mgr::get_ovl(void) ovl_cls* ovl_mgr::get_ovl(uint32_t type)
{ {
std::lock_guard<std::mutex> lock(lock_); std::lock_guard<std::mutex> lock(lock_);
ovl_cls* o = NULL; ovl_cls* o = NULL;
for (auto& v : ovls_) for (auto& v : ovls_)
{ {
if (v->is_waited()) if (v->is_waited() && v->type() == type)
{ {
o = v; o = v;
o->add_ref(); o->add_ref();
@ -136,13 +145,18 @@ ovl_cls* ovl_mgr::get_ovl(void)
if (!o) if (!o)
{ {
o = new ovl_cls(); o = new ovl_cls(type);
ovls_.push_back(o); ovls_.push_back(o);
o->add_ref(); o->add_ref();
} }
return o; return o;
} }
void ovl_mgr::notify_all(void)
{
for (auto& v : ovls_)
v->notify();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// usb_device ... // usb_device ...
@ -531,13 +545,7 @@ int usb_device::open(libusb_device_handle** dev_handle)
if (!dev_desc_) if (!dev_desc_)
init(); init();
HANDLE h = open_usb(udev_.name.c_str()); HANDLE h = INVALID_HANDLE_VALUE;
if (h == INVALID_HANDLE_VALUE)
{
*dev_handle = NULL;
return online_ ? LIBUSB_ERROR_IO : LIBUSB_ERROR_NO_DEVICE;
}
USBSCAN_PIPE_CONFIGURATION upc = { 0 }; USBSCAN_PIPE_CONFIGURATION upc = { 0 };
DWORD cbr = 0; DWORD cbr = 0;
@ -555,6 +563,13 @@ int usb_device::open(libusb_device_handle** dev_handle)
{ {
VLOG_MINI_2(LOG_LEVEL_WARNING, "Nice: '%s' for '%s'.\r\n", root.c_str(), udev_.name.c_str()); VLOG_MINI_2(LOG_LEVEL_WARNING, "Nice: '%s' for '%s'.\r\n", root.c_str(), udev_.name.c_str());
} }
h = open_usb(root.c_str());
if (h == INVALID_HANDLE_VALUE)
{
*dev_handle = NULL;
return online_ ? LIBUSB_ERROR_IO : LIBUSB_ERROR_NO_DEVICE;
}
if (DeviceIoControl(h, IOCTL_GET_PIPE_CONFIGURATION, NULL, 0, &upc, sizeof(upc), &cbr, NULL)) if (DeviceIoControl(h, IOCTL_GET_PIPE_CONFIGURATION, NULL, 0, &upc, sizeof(upc), &cbr, NULL))
{ {
int type = PIPE_TYPE::WRITE_DATA_PIPE; int type = PIPE_TYPE::WRITE_DATA_PIPE;
@ -588,6 +603,7 @@ int usb_device::close(void)
CancelIo(pipes_[i].pipe); CancelIo(pipes_[i].pipe);
CloseHandle(pipes_[i].pipe); CloseHandle(pipes_[i].pipe);
} }
ovl_mgr_.notify_all();
pipes_.clear(); pipes_.clear();
if (handle_) if (handle_)
@ -627,7 +643,7 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
if (h) if (h)
{ {
ovl_cls* oc = ovl_mgr_.get_ovl(); ovl_cls* oc = ovl_mgr_.get_ovl(endpoint);
DWORD io = 0; DWORD io = 0;
BOOL result = FALSE; BOOL result = FALSE;
@ -652,11 +668,13 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
{ {
if (WaitForSingleObject(oc->over_lapped()->hEvent, timeout) == WAIT_OBJECT_0) if (WaitForSingleObject(oc->over_lapped()->hEvent, timeout) == WAIT_OBJECT_0)
{ {
GetOverlappedResult(h, oc->over_lapped(), oc->io_bytes(), FALSE); GetOverlappedResult(h, oc->over_lapped(), oc->io_bytes(), TRUE);
*length = *oc->io_bytes(); *length = *oc->io_bytes();
if (*length == 0 && oc->over_lapped()->Internal != ERROR_SUCCESS) if (*length == 0 && oc->over_lapped()->Internal != ERROR_SUCCESS)
{ {
ret = LIBUSB_ERROR_IO; ret = oc->over_lapped()->Internal == STATUS_CANCELLED ? /*LIBUSB_ERROR_TRY_AGAIN*/LIBUSB_ERROR_INTERRUPTED : oc->over_lapped()->Internal;
if (ret == ERROR_NO_MORE_ITEMS)
ret = LIBUSB_ERROR_TIMEOUT;
VLOG_MINI_2(LOG_LEVEL_WARNING, "Bulk-Transfer of endpoint 0x%02x failed with code 0x%08X\n", endpoint, oc->over_lapped()->Internal); VLOG_MINI_2(LOG_LEVEL_WARNING, "Bulk-Transfer of endpoint 0x%02x failed with code 0x%08X\n", endpoint, oc->over_lapped()->Internal);
} }
else else
@ -692,7 +710,7 @@ int usb_device::transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16
if ((HANDLE)handle_ != INVALID_HANDLE_VALUE) if ((HANDLE)handle_ != INVALID_HANDLE_VALUE)
{ {
DWORD io = 0; DWORD io = 0;
ovl_cls *oc = ovl_mgr_.get_ovl(); ovl_cls *oc = ovl_mgr_.get_ovl(0);
irp.bmRequestType = (type >> 5) & 0x03; irp.bmRequestType = (type >> 5) & 0x03;
irp.bRequest = req; irp.bRequest = req;
@ -705,7 +723,7 @@ int usb_device::transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16
{ {
if (irp.fTransferDirectionIn) if (irp.fTransferDirectionIn)
{ {
GetOverlappedResult((HANDLE)handle_, oc->over_lapped(), oc->io_bytes(), FALSE); GetOverlappedResult((HANDLE)handle_, oc->over_lapped(), oc->io_bytes(), TRUE);
ret = *oc->io_bytes(); ret = *oc->io_bytes();
} }
else else
@ -742,7 +760,7 @@ int usb_device::transfer_interrupt(unsigned endpoint, unsigned char* data, int*
*length = 0; *length = 0;
if (h) if (h)
{ {
ovl_cls* oc = ovl_mgr_.get_ovl(); ovl_cls* oc = ovl_mgr_.get_ovl(endpoint);
if (DeviceIoControl(h, IOCTL_WAIT_ON_DEVICE_EVENT, NULL, 0, data, len, oc->io_bytes(), oc->over_lapped())) if (DeviceIoControl(h, IOCTL_WAIT_ON_DEVICE_EVENT, NULL, 0, data, len, oc->io_bytes(), oc->over_lapped()))
{ {
ret = LIBUSB_SUCCESS; ret = LIBUSB_SUCCESS;
@ -755,7 +773,7 @@ int usb_device::transfer_interrupt(unsigned endpoint, unsigned char* data, int*
{ {
if (WaitForSingleObject(oc->over_lapped()->hEvent, timeout) == WAIT_OBJECT_0) if (WaitForSingleObject(oc->over_lapped()->hEvent, timeout) == WAIT_OBJECT_0)
{ {
GetOverlappedResult(h, oc->over_lapped(), oc->io_bytes(), FALSE); GetOverlappedResult(h, oc->over_lapped(), oc->io_bytes(), TRUE);
*length = *oc->io_bytes(); *length = *oc->io_bytes();
ret = LIBUSB_SUCCESS; ret = LIBUSB_SUCCESS;
} }
@ -779,6 +797,17 @@ int usb_device::transfer_interrupt(unsigned endpoint, unsigned char* data, int*
return ret; return ret;
} }
int usb_device::cancel_io(void)
{
for (auto& v : pipes_)
{
CancelIo(v.pipe);
}
ovl_mgr_.notify_all();
return LIBUSB_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// usb_monitor ... // usb_monitor ...
@ -1466,4 +1495,7 @@ uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device* device)
return ((usb_device*)device)->address(); return ((usb_device*)device)->address();
} }
int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer* transfer/*in windows, this is a libusb_device* object*/)
{
return ((usb_device*)transfer)->cancel_io();
}

View File

@ -48,9 +48,10 @@ class ovl_cls// : public refer
volatile long ref_; volatile long ref_;
OVERLAPPED ovl_; OVERLAPPED ovl_;
DWORD io_bytes_; DWORD io_bytes_;
uint32_t type_;
public: public:
ovl_cls(); ovl_cls(uint32_t type);
protected: protected:
~ovl_cls(); ~ovl_cls();
@ -73,6 +74,8 @@ public:
LPDWORD io_bytes(void); LPDWORD io_bytes(void);
void reset(void); void reset(void);
bool is_waited(void); bool is_waited(void);
void notify(void);
uint32_t type(void);
}; };
class ovl_mgr class ovl_mgr
{ {
@ -84,7 +87,8 @@ public:
~ovl_mgr(); ~ovl_mgr();
public: public:
ovl_cls* get_ovl(void); ovl_cls* get_ovl(uint32_t type);
void notify_all(void);
}; };
class usb_device // consider as libusb_device class usb_device // consider as libusb_device
@ -153,6 +157,8 @@ public:
int transfer_bulk(unsigned endpoint, unsigned char* data, int* length, unsigned int timeout); int transfer_bulk(unsigned endpoint, unsigned char* data, int* length, unsigned int timeout);
int transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16_t ind, unsigned char* data, uint16_t len, unsigned timeout); int transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16_t ind, unsigned char* data, uint16_t len, unsigned timeout);
int transfer_interrupt(unsigned endpoint, unsigned char* data, int* length, unsigned int timeout); int transfer_interrupt(unsigned endpoint, unsigned char* data, int* length, unsigned int timeout);
int cancel_io(void);
}; };
class usb_callback class usb_callback
{ {

View File

@ -197,7 +197,7 @@ void dlg_indicator::notify_working(void)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// dlg_choose_dev /// dlg_choose_dev
/// ///
dlg_choose_dev::dlg_choose_dev(HWND parent, const std::map<std::string, std::string>& devs) : dlg_base(parent, IDD_CHOOSE_DEV), item_(-1) dlg_choose_dev::dlg_choose_dev(HWND parent, const std::vector<DEVQUE>& devs) : dlg_base(parent, IDD_CHOOSE_DEV), item_(-1)
{ {
create(); create();
@ -218,11 +218,11 @@ dlg_choose_dev::dlg_choose_dev(HWND parent, const std::map<std::string, std::str
col.pszText = &text[0]; col.pszText = &text[0];
SendMessageW(lst, LVM_INSERTCOLUMN, ind++, (LPARAM)&col); SendMessageW(lst, LVM_INSERTCOLUMN, ind++, (LPARAM)&col);
for (std::map<std::string, std::string>::const_iterator it = devs.begin(); ind = 0;
it != devs.end(); ++it) for (const auto& v: devs)
{ {
std::wstring n(local_trans::a2u(it->first.c_str(), CP_UTF8)), std::wstring n(local_trans::a2u(v.name.c_str(), CP_UTF8)),
s(local_trans::a2u(it->second.c_str(), CP_UTF8)); s(local_trans::a2u(v.sn.c_str(), CP_UTF8));
LV_ITEM item = { 0 }; LV_ITEM item = { 0 };
int ind = 0; int ind = 0;
@ -235,7 +235,7 @@ dlg_choose_dev::dlg_choose_dev(HWND parent, const std::map<std::string, std::str
item.iSubItem = 1; item.iSubItem = 1;
item.iItem = ind; item.iItem = ind;
SendMessageW(lst, LVM_SETITEMTEXTW, ind, (LPARAM)&item); SendMessageW(lst, LVM_SETITEMTEXTW, ind, (LPARAM)&item);
if (it == devs.begin()) if (ind++ == 0)
{ {
item_ = 0; item_ = 0;
ListView_SetItemState(lst, ind, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); ListView_SetItemState(lst, ind, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);

View File

@ -30,6 +30,13 @@ public:
void notify_working(void); void notify_working(void);
}; };
typedef struct _dev_que
{
int id; // ID用户选中后返回该值
std::string name; // 设备名称
std::string sn; // 设备序列号
}DEVQUE;
class dlg_choose_dev : public dlg_base class dlg_choose_dev : public dlg_base
{ {
std::string sel_; std::string sel_;
@ -40,7 +47,7 @@ class dlg_choose_dev : public dlg_base
void handle_notify(UINT id, LPNMHDR pnhdr); void handle_notify(UINT id, LPNMHDR pnhdr);
public: public:
dlg_choose_dev(HWND parent, const std::map<std::string, std::string>& devs); dlg_choose_dev(HWND parent, const std::vector<DEVQUE>& devs);
~dlg_choose_dev(); ~dlg_choose_dev();
public: public:

View File

@ -12,6 +12,7 @@
#include "DlgSetting.h" #include "DlgSetting.h"
#include "gb_json.h" #include "gb_json.h"
#include "../../sdk/include/lang/app_language.h" #include "../../sdk/include/lang/app_language.h"
#include <functional>
#pragma comment(lib, "Shlwapi.lib") #pragma comment(lib, "Shlwapi.lib")
@ -325,6 +326,51 @@ namespace callback
else else
return to_default_language(in, nullptr); return to_default_language(in, nullptr);
} }
// UI ...
//
// events code, see SANE_Event
//
// callback events: SANE_EVENT_UI_CLOSE_CANCEL/SANE_EVENT_UI_CLOSE_NORMAL/SANE_EVENT_UI_SCAN_COMMAND/SANE_EVENT_UI_CLOSE_SETTING
//
// notify events: SANE_EVENT_WORKING - void*: unused, be NULL, flag - unused, be 0
// SANE_EVENT_SCAN_FINISHED - void*: (utf8*)message, flag - error code (0 is success)
// SANE_EVENT_USB_DATA_RECEIVED- void* unused, be NULL, flag - unused, be 0
// SANE_EVENT_IMAGE_OK - void* unused, be NULL, flag - unused, be 0
int (*choose_scanner)(const std::vector<DEVQUE>& devs) = NULL; // blocked. return selected DEVQUE::id or -1 if user cancelled
void (*apply_current_config)(const char* dev_name, SANE_Handle device, LPSANEAPI api) = NULL; // 应用设备的当前配置
void (*show_setting_ui)(SANE_Handle device, HWND parent, LPSANEAPI api, bool with_scan/*是否显示“扫描”按钮*/, std::function<void(int)> callback) = NULL;
void (*show_progress_ui)(HWND parent, std::function<void(int)> callback, std::function<void(int/*event*/, void*/*msg*/, int/*flag*/)>* notify) = NULL;
static void init_ui(void)
{
std::string root(hg_sane_middleware::sane_path());
HMODULE mod = NULL;
root += "twainui.dll";
mod = LoadLibraryA(root.c_str());
if (!mod)
{
std::wstring info(L"Load '" + local_trans::a2u(root.c_str(), CP_UTF8));
info += L"' failed: " + std::to_wstring(GetLastError()) + L"\r\n";
log_info(info.c_str(), 0);
}
else
{
#define GET_API(api) \
proc = (FARPROC*)&api; \
*proc = GetProcAddress(mod, #api);
FARPROC* proc = NULL;
GET_API(choose_scanner);
GET_API(apply_current_config);
GET_API(show_setting_ui);
GET_API(show_progress_ui);
}
}
} }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -335,8 +381,25 @@ scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BAS
, scanner_ev_handler_(NULL), evh_param_(NULL), app_wnd_(NULL), user_cancel_(false) , scanner_ev_handler_(NULL), evh_param_(NULL), app_wnd_(NULL), user_cancel_(false)
, max_img_mem_(1 * 1024), twain_set_(false), ev_cnt_(0) , max_img_mem_(1 * 1024), twain_set_(false), ev_cnt_(0)
{ {
sane_api_.sane_cancel_api = inner_sane_cancel;
sane_api_.sane_close_api = inner_sane_close;
sane_api_.sane_control_option_api = inner_sane_control_option;
sane_api_.sane_get_devices_api = inner_sane_get_devices;
sane_api_.sane_get_option_descriptor_api = inner_sane_get_option_descriptor;
sane_api_.sane_get_parameters_api = inner_sane_get_parameters;
sane_api_.sane_get_select_fd_api = inner_sane_get_select_fd;
sane_api_.sane_io_control_api = inner_sane_io_control;
sane_api_.sane_open_api = inner_sane_open;
sane_api_.sane_read_api = inner_sane_read;
sane_api_.sane_set_io_mode_api = inner_sane_set_io_mode;
sane_api_.sane_start_api = inner_sane_start;
sane_api_.sane_strstatus_api = inner_sane_strstatus;
if (!callback::show_setting_ui)
{
cfg_ = new gb::scanner_cfg(); cfg_ = new gb::scanner_cfg();
cfg_->set_language_transform(&callback::language_trans, NULL); cfg_->set_language_transform(&callback::language_trans, NULL);
}
tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str()); tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str());
{ {
@ -570,6 +633,9 @@ void scanner::transport_config_file(void)
} }
void scanner::update_config(void) void scanner::update_config(void)
{ {
if (!cfg_)
return;
gb::sane_config_schm* schm = cfg_->get_scheme(); gb::sane_config_schm* schm = cfg_->get_scheme();
std::string notice(""); std::string notice("");
@ -596,15 +662,23 @@ void scanner::update_config(void)
} }
void scanner::load_config(const wchar_t* file) void scanner::load_config(const wchar_t* file)
{ {
if (cfg_)
{
cfg_->load_file(local_trans::u2a(file).c_str()); cfg_->load_file(local_trans::u2a(file).c_str());
update_config(); update_config();
}
} }
void scanner::save_config(const wchar_t* file) void scanner::save_config(const wchar_t* file)
{ {
if(cfg_)
cfg_->save(local_trans::u2a(file).c_str()); cfg_->save(local_trans::u2a(file).c_str());
} }
void scanner::apply_config(void) void scanner::apply_config(void)
{ {
if (callback::apply_current_config)
callback::apply_current_config(local_trans::u2a(scanner_name_.c_str(), CP_UTF8).c_str(), handle_, &sane_api_);
else if (cfg_)
{
gb::sane_config_schm* schm = cfg_->get_scheme(); gb::sane_config_schm* schm = cfg_->get_scheme();
if (!schm) if (!schm)
@ -612,6 +686,7 @@ void scanner::apply_config(void)
apply_scheme(schm); apply_scheme(schm);
schm->release(); schm->release();
}
} }
void scanner::on_ui_event(int uev, void* sender) void scanner::on_ui_event(int uev, void* sender)
{ {
@ -689,8 +764,9 @@ std::string scanner::choose_scanner(const std::vector<std::string>& scanners)
if (scanners.empty()) if (scanners.empty())
return ""; return "";
std::map<std::string, std::string> devs; std::vector<DEVQUE> devs;
std::string sel(""); std::string sel("");
int id = 1;
for (size_t i = 0; i < scanners.size(); ++i) for (size_t i = 0; i < scanners.size(); ++i)
{ {
@ -702,7 +778,13 @@ std::string scanner::choose_scanner(const std::vector<std::string>& scanners)
std::string sn(""); std::string sn("");
scanner::control_read_string(h, IO_CTRL_CODE_GET_SERIAL, sn); scanner::control_read_string(h, IO_CTRL_CODE_GET_SERIAL, sn);
if (sn.length()) if (sn.length())
devs[scanners[i]] = sn; {
DEVQUE dev;
dev.id = id++;
dev.name = scanners[i];
dev.sn = sn;
devs.push_back(dev);
}
hg_sane_middleware::instance()->close_device(h); hg_sane_middleware::instance()->close_device(h);
} }
} }
@ -710,7 +792,22 @@ std::string scanner::choose_scanner(const std::vector<std::string>& scanners)
if (devs.size() == 0) if (devs.size() == 0)
sel = scanners[0]; sel = scanners[0];
else if (devs.size() == 1) else if (devs.size() == 1)
sel = devs.begin()->first; sel = devs[0].name;
else if (callback::choose_scanner)
{
id = callback::choose_scanner(devs);
if (id != -1)
{
for (auto& v : devs)
{
if (v.id == id)
{
sel = v.name;
break;
}
}
}
}
else else
{ {
dlg_choose_dev dlg(NULL, devs); dlg_choose_dev dlg(NULL, devs);
@ -814,7 +911,7 @@ int scanner::init_options_id(void)
default: default:
break; break;
} }
if (len) if (len && cfg_)
{ {
if (desc->type == SANE_TYPE_STRING) if (desc->type == SANE_TYPE_STRING)
{ {
@ -2758,6 +2855,8 @@ COM_API_IMPLEMENT(scanner, void, twain_set_compression(SANE_CompressionType comp
} }
COM_API_IMPLEMENT(scanner, int, twain_get_config(char* buf, size_t* len)) COM_API_IMPLEMENT(scanner, int, twain_get_config(char* buf, size_t* len))
{ {
if (cfg_)
{
std::string cont(cfg_->to_text_stream()); std::string cont(cfg_->to_text_stream());
if (*len < cont.length()) if (*len < cont.length())
@ -2767,12 +2866,13 @@ COM_API_IMPLEMENT(scanner, int, twain_get_config(char* buf, size_t* len))
return SCANNER_ERR_INSUFFICIENT_MEMORY; return SCANNER_ERR_INSUFFICIENT_MEMORY;
} }
strcpy(buf, cont.c_str()); strcpy(buf, cont.c_str());
}
return SCANNER_ERR_OK; return SCANNER_ERR_OK;
} }
COM_API_IMPLEMENT(scanner, int, twain_set_config(char* buf, size_t len)) COM_API_IMPLEMENT(scanner, int, twain_set_config(char* buf, size_t len))
{ {
if(cfg_->load_mem(buf)) if(cfg_ && cfg_->load_mem(buf))
{ {
update_config(); update_config();
apply_config(); apply_config();
@ -2791,8 +2891,16 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_main(HWND parent))
} }
COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan, bool indicator)) COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan, bool indicator))
{ {
SANEAPI api = { NULL }; if (callback::show_setting_ui)
{
auto cb = [&](int ev)
{
on_ui_event(ev, NULL);
};
callback::show_setting_ui(handle_, parent, &sane_api_, with_scan, cb);
}
else if (cfg_)
{
if (with_scan) if (with_scan)
{ {
events_.clear(); events_.clear();
@ -2801,24 +2909,10 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan, bo
scan_err_ = false; scan_err_ = false;
} }
api.sane_cancel_api = inner_sane_cancel;
api.sane_close_api = inner_sane_close;
api.sane_control_option_api = inner_sane_control_option;
api.sane_get_devices_api = inner_sane_get_devices;
api.sane_get_option_descriptor_api = inner_sane_get_option_descriptor;
api.sane_get_parameters_api = inner_sane_get_parameters;
api.sane_get_select_fd_api = inner_sane_get_select_fd;
api.sane_io_control_api = inner_sane_io_control;
api.sane_open_api = inner_sane_open;
api.sane_read_api = inner_sane_read;
api.sane_set_io_mode_api = inner_sane_set_io_mode;
api.sane_start_api = inner_sane_start;
api.sane_strstatus_api = inner_sane_strstatus;
size_t pid = scanner_name_.find(L" - "); size_t pid = scanner_name_.find(L" - ");
if (pid == -1) if (pid == -1)
pid = scanner_name_.length(); pid = scanner_name_.length();
setting_.reset(new dlg_setting(parent, &api, handle_, with_scan, scanner_name_.substr(0, pid).c_str())); setting_.reset(new dlg_setting(parent, &sane_api_, handle_, with_scan, scanner_name_.substr(0, pid).c_str()));
setting_->set_ui_event_notify(&scanner::ui_callback, this); setting_->set_ui_event_notify(&scanner::ui_callback, this);
setting_->set_config(cfg_, (cfg_path_ + scanner_name_.substr(0, pid) + L".cfg").c_str(), &scanner::apply_scheme, this, &twain_set_); setting_->set_config(cfg_, (cfg_path_ + scanner_name_.substr(0, pid) + L".cfg").c_str(), &scanner::apply_scheme, this, &twain_set_);
indicator_.reset(); indicator_.reset();
@ -2828,11 +2922,17 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan, bo
indicator_->set_ui_event_notify(&scanner::ui_callback, this); indicator_->set_ui_event_notify(&scanner::ui_callback, this);
} }
setting_->show(true); setting_->show(true);
}
return true; return true;
} }
COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent)) COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
{ {
if (callback::show_progress_ui)
{
}
else
{
if (setting_.get() && IsWindowVisible(setting_->hwnd())) if (setting_.get() && IsWindowVisible(setting_->hwnd()))
parent = setting_->hwnd(); parent = setting_->hwnd();
else if (!IsWindow(parent)) else if (!IsWindow(parent))
@ -2841,6 +2941,7 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
indicator_.reset(new dlg_indicator(parent)); indicator_.reset(new dlg_indicator(parent));
indicator_->set_ui_event_notify(&scanner::ui_callback, this); indicator_->set_ui_event_notify(&scanner::ui_callback, this);
indicator_->show(true); indicator_->show(true);
}
return true; return true;
} }
@ -3060,6 +3161,8 @@ extern "C"
int __stdcall initialize(void* reserve) int __stdcall initialize(void* reserve)
{ {
init_log(); init_log();
callback::init_ui();
hg_sane_middleware::set_callback(callback::sane_event_callback, NULL); hg_sane_middleware::set_callback(callback::sane_event_callback, NULL);
if (hg_sane_middleware::instance()->is_ready()) if (hg_sane_middleware::instance()->is_ready())
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;

View File

@ -56,6 +56,7 @@ class scanner : public ISaneInvoker, virtual public refer
std::unique_ptr<dlg_setting> setting_; std::unique_ptr<dlg_setting> setting_;
gb::scanner_cfg* cfg_; gb::scanner_cfg* cfg_;
bool twain_set_; bool twain_set_;
SANEAPI sane_api_;
int(__stdcall* scanner_ev_handler_)(int, void*); int(__stdcall* scanner_ev_handler_)(int, void*);
void* evh_param_; void* evh_param_;

View File

@ -74,7 +74,7 @@
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)..\..\sdk\include\;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir> <OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
<LibraryPath>$(LibraryPath)</LibraryPath> <LibraryPath>$(LibraryPath)</LibraryPath>
@ -84,13 +84,13 @@
<LibraryPath>$(LibraryPath)</LibraryPath> <LibraryPath>$(LibraryPath)</LibraryPath>
<TargetName>huagaotwain400.ds</TargetName> <TargetName>huagaotwain400.ds</TargetName>
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)..\..\sdk\include\;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir> <OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)..\..\sdk\include\;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir> <OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
<LibraryPath>$(LibraryPath)</LibraryPath> <LibraryPath>$(LibraryPath)</LibraryPath>
@ -100,7 +100,7 @@
<LibraryPath>$(LibraryPath)</LibraryPath> <LibraryPath>$(LibraryPath)</LibraryPath>
<TargetName>huagaotwain400.ds</TargetName> <TargetName>huagaotwain400.ds</TargetName>
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)..\..\sdk\include\;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir> <OutDir>$(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\</OutDir>
<IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup> </PropertyGroup>
@ -123,8 +123,12 @@
</AdditionalDependencies> </AdditionalDependencies>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command> <Command>copy "$(TargetPath)" C:\Windows\twain_32\HuagoTwain\$(TargetName) /y
</Command> move /Y "$(TargetPath)" "$(OutputPath)$(TargetName)"
mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
move /Y "$(OutputPath)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
move /Y "$(OutputPath)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -147,8 +151,12 @@
</AdditionalDependencies> </AdditionalDependencies>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command> <Command>copy "$(TargetPath)" C:\Windows\twain_64\HuagoTwain\$(TargetName) /y
</Command> move /Y "$(TargetPath)" "$(OutputPath)$(TargetName)"
mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
move /Y "$(OutputPath)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
move /Y "$(OutputPath)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"
move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao"</Command>
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -206,52 +214,51 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\sdk\include\huagao\brand.h" /> <ClInclude Include="..\..\sdk\include\huagao\brand.h" />
<ClInclude Include="..\..\sdk\include\twain\twpp.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\application.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\audio.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\capability.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\cie.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\curveresponse.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\customdata.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\datasource.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\deviceevent.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\element8.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\enums.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\env.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\event.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\exception.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\extimageinfo.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\filesystem.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\fix32.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\frame.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\identity.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\imageinfo.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\imagelayout.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\imagememxfer.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\imagenativexfer.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\internal.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\jpegcompression.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\memory.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\memoryops.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\palette8.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\passthrough.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\pendingxfers.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\setupfilexfer.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\setupmemxfer.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\status.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\strings.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\twglue.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\types.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\typesops.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\userinterface.hpp" />
<ClInclude Include="..\..\sdk\include\twain\twpp\utils.hpp" />
<ClInclude Include="..\sane\s2t_api.h" /> <ClInclude Include="..\sane\s2t_api.h" />
<ClInclude Include="load_sane.h" /> <ClInclude Include="load_sane.h" />
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
<ClInclude Include="twain\huagaods.hpp" /> <ClInclude Include="twain\huagaods.hpp" />
<ClInclude Include="twain\twain_2.4.h" />
<ClInclude Include="twain\twpp.hpp" />
<ClInclude Include="twain\twpp\application.hpp" />
<ClInclude Include="twain\twpp\audio.hpp" />
<ClInclude Include="twain\twpp\capability.hpp" />
<ClInclude Include="twain\twpp\cie.hpp" />
<ClInclude Include="twain\twpp\curveresponse.hpp" />
<ClInclude Include="twain\twpp\customdata.hpp" />
<ClInclude Include="twain\twpp\datasource.hpp" />
<ClInclude Include="twain\twpp\deviceevent.hpp" />
<ClInclude Include="twain\twpp\element8.hpp" />
<ClInclude Include="twain\twpp\enums.hpp" />
<ClInclude Include="twain\twpp\env.hpp" />
<ClInclude Include="twain\twpp\event.hpp" />
<ClInclude Include="twain\twpp\exception.hpp" />
<ClInclude Include="twain\twpp\extimageinfo.hpp" />
<ClInclude Include="twain\twpp\filesystem.hpp" />
<ClInclude Include="twain\twpp\fix32.hpp" />
<ClInclude Include="twain\twpp\frame.hpp" />
<ClInclude Include="twain\twpp\identity.hpp" />
<ClInclude Include="twain\twpp\imageinfo.hpp" />
<ClInclude Include="twain\twpp\imagelayout.hpp" />
<ClInclude Include="twain\twpp\imagememxfer.hpp" />
<ClInclude Include="twain\twpp\imagenativexfer.hpp" />
<ClInclude Include="twain\twpp\internal.hpp" />
<ClInclude Include="twain\twpp\jpegcompression.hpp" />
<ClInclude Include="twain\twpp\memory.hpp" />
<ClInclude Include="twain\twpp\memoryops.hpp" />
<ClInclude Include="twain\twpp\palette8.hpp" />
<ClInclude Include="twain\twpp\passthrough.hpp" />
<ClInclude Include="twain\twpp\pendingxfers.hpp" />
<ClInclude Include="twain\twpp\setupfilexfer.hpp" />
<ClInclude Include="twain\twpp\setupmemxfer.hpp" />
<ClInclude Include="twain\twpp\status.hpp" />
<ClInclude Include="twain\twpp\strings.hpp" />
<ClInclude Include="twain\twpp\twglue.hpp" />
<ClInclude Include="twain\twpp\types.hpp" />
<ClInclude Include="twain\twpp\typesops.hpp" />
<ClInclude Include="twain\twpp\userinterface.hpp" />
<ClInclude Include="twain\twpp\utils.hpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="dllmain.cpp" /> <ClCompile Include="dllmain.cpp" />

View File

@ -33,129 +33,9 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="twain\twain_2.4.h">
<Filter>twain</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\application.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\audio.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\capability.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\cie.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\curveresponse.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\customdata.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\datasource.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\deviceevent.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\element8.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\enums.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\env.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\event.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\exception.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\extimageinfo.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\filesystem.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\fix32.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\frame.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\identity.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\imageinfo.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\imagelayout.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\imagememxfer.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\imagenativexfer.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\internal.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\jpegcompression.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\memory.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\memoryops.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\palette8.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\passthrough.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\pendingxfers.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\setupfilexfer.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\setupmemxfer.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\status.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\strings.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\twglue.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\types.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\typesops.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\userinterface.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\twpp\utils.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="twain\huagaods.hpp"> <ClInclude Include="twain\huagaods.hpp">
<Filter>twain</Filter> <Filter>twain</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="twain\twpp.hpp">
<Filter>twain</Filter>
</ClInclude>
<ClInclude Include="pch.h"> <ClInclude Include="pch.h">
<Filter>Headers</Filter> <Filter>Headers</Filter>
</ClInclude> </ClInclude>
@ -174,6 +54,123 @@
<ClInclude Include="..\..\sdk\include\huagao\brand.h"> <ClInclude Include="..\..\sdk\include\huagao\brand.h">
<Filter>Headers</Filter> <Filter>Headers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\application.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\audio.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\capability.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\cie.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\curveresponse.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\customdata.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\datasource.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\deviceevent.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\element8.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\enums.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\env.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\event.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\exception.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\extimageinfo.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\filesystem.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\fix32.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\frame.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\identity.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\imageinfo.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\imagelayout.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\imagememxfer.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\imagenativexfer.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\internal.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\jpegcompression.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\memory.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\memoryops.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\palette8.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\passthrough.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\pendingxfers.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\setupfilexfer.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\setupmemxfer.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\status.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\strings.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\twglue.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\types.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\typesops.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\userinterface.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp\utils.hpp">
<Filter>twain\twpp</Filter>
</ClInclude>
<ClInclude Include="..\..\sdk\include\twain\twpp.hpp">
<Filter>twain</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="huagaotwain.rc"> <ResourceCompile Include="huagaotwain.rc">