From fdb5649ed2ef46246ecb1dc79c5112a7b545d3e5 Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Sat, 8 Oct 2022 14:13:09 +0800 Subject: [PATCH] =?UTF-8?q?TWAIN=E5=8D=87=E7=BA=A7=E8=80=81=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sane/gb_json.cpp | 151 +++++++++++++++++++++++++------------- sane/gb_json.h | 18 +++-- sane/scanner.cpp | 186 +++++++++++++++++++++++++++++++++++++---------- sane/scanner.h | 2 + 4 files changed, 260 insertions(+), 97 deletions(-) diff --git a/sane/gb_json.cpp b/sane/gb_json.cpp index 10262b2..6e8ff60 100644 --- a/sane/gb_json.cpp +++ b/sane/gb_json.cpp @@ -9,6 +9,7 @@ #define bzero(b, s) memset(b, 0, s) #endif + namespace gb { static std::vector split_with(const char* str, const char* splitor = "/") @@ -563,6 +564,28 @@ namespace gb return true; } + bool json::change_key(const char* old_key, const char* new_key) + { + if (!obj_ || !new_key || *new_key == 0 || !old_key || *old_key == 0) + return false; + + cJSON** addr = NULL, + *ele = find(old_key, false, &addr); + + if (!ele) + return false; + + if (strlen(ele->string) < strlen(new_key)) + { + int l = strlen(new_key) + 4; + free(ele->string); + ele->string = (char*)malloc(l); + memset(ele->string, 0, l); + } + strcpy(ele->string, new_key); + + return true; + } bool json::remove(const char* key) { if(!obj_) @@ -927,24 +950,8 @@ namespace gb memset(buf, 0, size + 4); fread(buf, 1, size, src); fclose(src); - - std::string raw(b64.decode(buf, size)); - + ret = load_from_mem(buf); delete[] buf; - - if (raw.length()) - { - jsn_ = new gb::json(); - if (jsn_->attach_text(&raw[0])) - { - ret = true; - } - else - { - delete jsn_; - jsn_ = NULL; - } - } } file_ = file; @@ -964,7 +971,7 @@ namespace gb return false; } - + return true; } bool sane_config::save_to(const wchar_t* file) @@ -989,21 +996,18 @@ namespace gb return ret; } - void sane_config::set_default_value(int sn, const char* title, const char* val, size_t bytes) + void sane_config::set_default_value(int sn, const char* name, const char* val, size_t bytes) { - std::string hex_t(to_hex_letter(title, lstrlenA(title))); - - id_title_[sn] = hex_t; - def_val_->set_value(hex_t.c_str(), to_hex_letter(val, bytes).c_str()); + id_name_[sn] = name; + def_val_->set_value(name, to_hex_letter(val, bytes).c_str()); } - bool sane_config::first_config(std::string& title, std::string& val) + bool sane_config::first_config(std::string& name, std::string& val) { bool ret = false; - std::string raw_n(""), raw_v(""); + std::string raw_v(""); - if (jsn_ && jsn_->first_child(raw_v, &raw_n)) + if (jsn_ && jsn_->first_child(raw_v, &name)) { - title = sane_config::from_hex_letter(raw_n.c_str(), raw_n.length()); val = sane_config::from_hex_letter(raw_v.c_str(), raw_v.length()); ret = true; @@ -1011,14 +1015,13 @@ namespace gb return ret; } - bool sane_config::next_config(std::string& title, std::string& val) + bool sane_config::next_config(std::string& name, std::string& val) { bool ret = false; - std::string raw_n(""), raw_v(""); + std::string raw_v(""); - if (jsn_ && jsn_->next_child(raw_v, &raw_n)) + if (jsn_ && jsn_->next_child(raw_v, &name)) { - title = sane_config::from_hex_letter(raw_n.c_str(), raw_n.length()); val = sane_config::from_hex_letter(raw_v.c_str(), raw_v.length()); ret = true; @@ -1040,38 +1043,36 @@ namespace gb jsn_->attach_text(&stream[0]); } } - void sane_config::config_changed(const char* title, const char* val, size_t bytes) + void sane_config::config_changed(const char* name, const char* val, size_t bytes) { - std::string hex_t(to_hex_letter(title, lstrlenA(title))), - hex_v(to_hex_letter(val, bytes)), - def(default_value(hex_t.c_str())); + std::string hex_v(to_hex_letter(val, bytes)), + def(default_value(name)); if (hex_v == def) - jsn_->remove(hex_t.c_str()); + jsn_->remove(name); else - jsn_->set_value(hex_t.c_str(), hex_v.c_str()); + jsn_->set_value(name, hex_v.c_str()); } void sane_config::config_changed(int sn, const char* val, size_t bytes) { - std::string hex_t(""), + std::string name(""), hex_v(to_hex_letter(val, bytes)), def(""); - if (id_title_.count(sn)) + if (id_name_.count(sn)) { - hex_t = id_title_[sn]; - def = default_value(hex_t.c_str()); + name = id_name_[sn]; + def = default_value(name.c_str()); if (hex_v == def) - jsn_->remove(hex_t.c_str()); + jsn_->remove(name.c_str()); else - jsn_->set_value(hex_t.c_str(), hex_v.c_str()); + jsn_->set_value(name.c_str(), hex_v.c_str()); } } - void sane_config::remove_config(const char* title) + void sane_config::remove_config(const char* name) { - std::string hex_t(to_hex_letter(title, lstrlenA(title))); if (jsn_) - jsn_->remove(hex_t.c_str()); + jsn_->remove(name); } void sane_config::end_setting(bool cancel) { @@ -1091,13 +1092,11 @@ namespace gb } in_setting_ = false; } - int sane_config::id_from_title(const char* title) + int sane_config::id_from_name(const char* name) { - std::string hex_t(to_hex_letter(title, lstrlenA(title))); - - for (const auto& v : id_title_) + for (const auto& v : id_name_) { - if (v.second == hex_t) + if (v.second == name) return v.first; } @@ -1132,4 +1131,54 @@ namespace gb return ver; } + void sane_config::update(bool(__stdcall* is_float)(int, void*), void* param, const char* (__stdcall* t2n)(const char*), std::string* discard) + { + std::string ver(get_version()), + name(""), + val(""); + int mv = atoi(ver.c_str()), + sv = ver.find("."); + bool changed = false; + char vs[40] = { 0 }; + + if (sv++ != -1) + sv = atoi(ver.c_str() + sv); + + // change title to name ... + if (mv <= 4 && sv < 30) + { + if (jsn_->first_child(val, &name)) + { + changed = true; + do + { + jsn_->change_key(name.c_str(), t2n(sane_config::from_hex_letter(name.c_str(), name.length()).c_str())); + } while (jsn_->next_child(val, &name)); + } + } + + // fix float does not convert to SANE_Fixed bug in eldest version .... (discard them) + if (ver.empty()) + { + if (jsn_->first_child(val, &name)) + { + do + { + int id = id_from_name(name.c_str()); + if (id == -1 || is_float(id, param)) + { + jsn_->remove(name.c_str()); + if (discard) + *discard += name + "\r\n"; + changed = true; + } + } while (jsn_->next_child(val, &name)); + } + } + sprintf_s(vs, _countof(vs) - 1, "%u.%u", VERSION_MAIN, VERSION_SUB); + jsn_->set_value("ver", vs); + + if (changed) + save_to(NULL); + } } diff --git a/sane/gb_json.h b/sane/gb_json.h index ad44ea6..565df29 100644 --- a/sane/gb_json.h +++ b/sane/gb_json.h @@ -59,6 +59,7 @@ namespace gb bool set_value(const char* key, const char* val); bool set_value(const char* key, json* obj); + bool change_key(const char* old_key, const char* new_key); bool remove(const char* key); }; @@ -88,12 +89,12 @@ namespace gb json* bkp_; json* def_val_; bool in_setting_; - std::map id_title_; + std::map id_name_; void clear(); std::string to_hex_letter(const char* data, size_t bytes); std::string from_hex_letter(const char* data, size_t bytes); - std::string default_value(const char* hex_title); + std::string default_value(const char* name); public: sane_config(); @@ -106,16 +107,17 @@ namespace gb bool load_from_file(const wchar_t* file); bool load_from_mem(const char* mem); bool save_to(const wchar_t* file); - void set_default_value(int sn, const char* title, const char* val, size_t bytes); - bool first_config(std::string& title, std::string& val); - bool next_config(std::string& title, std::string& val); + void set_default_value(int sn, const char* name, const char* val, size_t bytes); + bool first_config(std::string& name, std::string& val); + bool next_config(std::string& name, std::string& val); void begin_setting(bool restore = false); - void config_changed(const char* title, const char* val, size_t bytes); + void config_changed(const char* name, const char* val, size_t bytes); void config_changed(int sn, const char* val, size_t bytes); - void remove_config(const char* title); + void remove_config(const char* name); void end_setting(bool cancel); - int id_from_title(const char* title); + int id_from_name(const char* name); std::string to_text_stream(void); std::string get_version(void); + void update(bool(__stdcall* is_float)(int, void*), void* param, const char*(__stdcall* t2n)(const char*), std::string* discard = NULL); }; } diff --git a/sane/scanner.cpp b/sane/scanner.cpp index a9b684f..7125dc0 100644 --- a/sane/scanner.cpp +++ b/sane/scanner.cpp @@ -115,6 +115,115 @@ namespace callback if (it != g_scanner_instances.end()) g_scanner_instances.erase(it); } + + struct + { + const char* name; + const char* title; + }g_opts[] = { {SANE_STD_OPT_NAME_RESTORE , OPTION_TITLE_HFMRSZ} + , {SANE_STD_OPT_NAME_HELP , OPTION_TITLE_BZ} + , {SANE_STD_OPT_NAME_IS_MULTI_OUT , OPTION_TITLE_DLSC} + , {SANE_STD_OPT_NAME_MULTI_OUT_TYPE , OPTION_TITLE_DLSCLX} + , {SANE_STD_OPT_NAME_COLOR_MODE , OPTION_TITLE_YSMS} + , {SANE_STD_OPT_NAME_BINARY_THRESHOLD , OPTION_TITLE_HBTXYZ} + , {SANE_STD_OPT_NAME_REVERSE_01 , OPTION_TITLE_HBTXFSSC} + , {SANE_STD_OPT_NAME_FILTER , OPTION_TITLE_HDHHBTX_CSYZQ} + , {SANE_STD_OPT_NAME_RID_MULTIOUT_RED , OPTION_TITLE_24WCSTX_DLSCCH} + , {SANE_STD_OPT_NAME_RID_ANSWER_SHEET_RED , OPTION_TITLE_24WCSTX_DTKCH} + , {SANE_STD_OPT_NAME_ERASE_BACKGROUND , OPTION_TITLE_BJYC} + , {SANE_STD_OPT_NAME_BKG_COLOR_RANGE , OPTION_TITLE_BJSCFDFW} + , {SANE_STD_OPT_NAME_SHARPEN , OPTION_TITLE_RHYMH} + , {SANE_STD_OPT_NAME_RID_MORR , OPTION_TITLE_QCMW} + , {SANE_STD_OPT_NAME_RID_GRID , OPTION_TITLE_CWW} + , {SANE_STD_OPT_NAME_ERROR_EXTENSION , OPTION_TITLE_CWKS} + , {SANE_STD_OPT_NAME_NOISE_OPTIMIZE , OPTION_TITLE_HBTXZDYH} + , {SANE_STD_OPT_NAME_NOISE_SIZE , OPTION_TITLE_ZDYHCC} + , {SANE_STD_OPT_NAME_PAPER , OPTION_TITLE_ZZCC} + , {SANE_STD_OPT_NAME_CUSTOM_AREA , OPTION_TITLE_ZDYSMQY} + , {SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT , OPTION_TITLE_SMQYZCmm} + , {SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT , OPTION_TITLE_SMQYYCmm} + , {SANE_STD_OPT_NAME_CUSTOM_AREA_TOP , OPTION_TITLE_SMQYSCmm} + , {SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM , OPTION_TITLE_SMQYXCmm} + , {SANE_STD_OPT_NAME_SIZE_CHECK , OPTION_TITLE_CCJC} + , {SANE_STD_OPT_NAME_PAGE , OPTION_TITLE_SMYM} + , {SANE_STD_OPT_NAME_DISCARD_BLANK_SENS , OPTION_TITLE_TGKBYLMD} + , {SANE_STD_OPT_NAME_RESOLUTION , OPTION_TITLE_FBL} + , {SANE_STD_OPT_NAME_TIME_TO_SLEEP , OPTION_TITLE_XMSJ} + , {SANE_STD_OPT_NAME_IMAGE_QUALITY , OPTION_TITLE_HZ} + , {SANE_STD_OPT_NAME_EXCHANGE ,OPTION_TITLE_JHZFM} + , {SANE_STD_OPT_NAME_SPLIT ,OPTION_TITLE_TXCF } + , {SANE_STD_OPT_NAME_ANTI_SKEW , OPTION_TITLE_ZDJP} + , {SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA , OPTION_TITLE_QYSDQX} + , {SANE_STD_OPT_NAME_GAMMA , OPTION_TITLE_JMZ} + , {SANE_STD_OPT_NAME_BRIGHTNESS , OPTION_TITLE_LDZ} + , {SANE_STD_OPT_NAME_CONTRAST , OPTION_TITLE_DBD} + , {SANE_STD_OPT_NAME_IS_PHOTO_MODE , OPTION_TITLE_ZPMS} + , {SANE_STD_OPT_NAME_ERASE_BLACK_FRAME , OPTION_TITLE_XCHK} + , {SANE_STD_OPT_NAME_DARK_SAMPLE , OPTION_TITLE_SSYZ} + , {SANE_STD_OPT_NAME_THRESHOLD , OPTION_TITLE_YZ} + , {SANE_STD_OPT_NAME_ANTI_NOISE_LEVEL , OPTION_TITLE_BJKZDJ} + , {SANE_STD_OPT_NAME_MARGIN , OPTION_TITLE_BYSJ} + , {SANE_STD_OPT_NAME_FILL_BKG_MODE , OPTION_TITLE_BJTCFS} + , {SANE_STD_OPT_NAME_IS_ANTI_PERMEATE , OPTION_TITLE_FZST} + , {SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL , OPTION_TITLE_FZSTDJ} + , {SANE_STD_OPT_NAME_RID_HOLE_L , OPTION_TITLE_CKYCZC} + , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_L , OPTION_TITLE_ZCCKSSFWZFMBL} + , {SANE_STD_OPT_NAME_RID_HOLE_R , OPTION_TITLE_CKYCYC} + , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_R , OPTION_TITLE_YCCKSSFWZFMBL} + , {SANE_STD_OPT_NAME_RID_HOLE_T , OPTION_TITLE_CKYCSC} + , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_T , OPTION_TITLE_SCCKSSFWZFMBL} + , {SANE_STD_OPT_NAME_RID_HOLE_B , OPTION_TITLE_CKYCXC} + , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_B , OPTION_TITLE_XCCKSSFWZFMBL} + , {SANE_STD_OPT_NAME_IS_FILL_COLOR , OPTION_TITLE_SCTC} + , {SANE_STD_OPT_NAME_IS_ULTROSONIC_CHECK , OPTION_TITLE_CSBJC} + , {SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE , OPTION_TITLE_SZTPCL} + , {SANE_STD_OPT_NAME_IS_CHECK_STAPLE , OPTION_TITLE_ZDJC} + , {SANE_STD_OPT_NAME_SCAN_MODE , OPTION_TITLE_SMZS} + , {SANE_STD_OPT_NAME_SCAN_COUNT , OPTION_TITLE_SMSL} + , {SANE_STD_OPT_NAME_TEXT_DIRECTION , OPTION_TITLE_WGFX} + , {SANE_STD_OPT_NAME_IS_ROTATE_BKG_180 , OPTION_TITLE_BMXZ180} + , {SANE_STD_OPT_NAME_IS_CHECK_DOG_EAR , OPTION_TITLE_ZJJC} + , {SANE_STD_OPT_NAME_DOG_EAR_SIZE , OPTION_TITLE_ZJDX} + , {SANE_STD_OPT_NAME_IS_CHECK_ASKEW , OPTION_TITLE_WXJC} + , {SANE_STD_OPT_NAME_ASKEW_RANGE , OPTION_TITLE_WXRRD} + , {SANE_STD_OPT_NAME_FEED_STRENGTH , OPTION_TITLE_FZQD} + , {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , OPTION_TITLE_ZDFZQD} + , {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , OPTION_TITLE_JZSBL} + , {SANE_STD_OPT_NAME_WAIT_TO_SCAN , OPTION_TITLE_DZSM} + }, + g_discard[] = { {SANE_STD_OPT_NAME_REVERSE_01 , "\351\273\221\347\231\275\345\233\276\345\203\217\345\217\215\350\211\262\350\276\223\345\207\272\357\274\210\346\255\243\345\270\270\351\242\234\350\211\262\344\270\272\357\274\2320-\351\273\221\350\211\262\357\274\2331-\347\231\275\350\211\262\357\274\211"} // 黑白图像反色输出(正常颜色为:0-黑色;1-白色) + , {SANE_STD_OPT_NAME_FILTER , "\347\201\260\345\272\246\346\210\226\351\273\221\347\231\275\345\233\276\345\203\217 - \351\231\244\350\211\262"} // 灰度或黑白图像 - 除色 + , {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // 自动搓纸强度 + , {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " 搓纸阈值" + }; + const char* __stdcall option_title_2_name(const char* title) + { + while (*title == ' ') + title++; + + for (size_t i = 0; i < _countof(g_discard); ++i) + { + if (strcmp(title, g_discard[i].title) == 0) + return g_discard[i].name; + } + for (size_t i = 0; i < _countof(g_opts); ++i) + { + if (strcmp(title, g_opts[i].title) == 0) + return g_opts[i].name; + } + + return ""; + } + const char* __stdcall option_name_2_title(const char* name) + { + for (size_t i = 0; i < _countof(g_opts); ++i) + { + if (strcmp(name, g_opts[i].name) == 0) + return g_opts[i].title; + } + + return ""; + } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -215,6 +324,15 @@ void __stdcall scanner::ui_callback(int uev, void* sender, void* param) { ((scanner*)param)->on_ui_event(uev, sender); } +bool __stdcall scanner::is_option_float(int sn, void* param) +{ + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor((SANE_Handle)param, sn); + + if (desc) + return desc->type == SANE_TYPE_FIXED; + else + return false; +} // IRef COM_API_IMPLEMENT(scanner, long, add_ref(void)) @@ -226,9 +344,28 @@ COM_API_IMPLEMENT(scanner, long, release(void)) return refer::release(); } +void scanner::update_config(void) +{ + std::string notice(""); + cfg_->update(&scanner::is_option_float, handle_, &callback::option_title_2_name, ¬ice); + if (notice.length()) + { + std::wstring msg(L"\u4E0B\u5217\u914D\u7F6E\u6570\u636E\u9519\u8BEF\uFF0C\u5DF2\u7ECF\u6062\u590D\u5230\u9ED8\u8BA4\u503C\u3002\u5982\u679C\u9700\u8981\uFF0C\u8BF7\u91CD\u65B0\u8BBE\u7F6E\uFF1A\r\n\r\n"); + size_t pos = notice.find("\r\n"); + + while (pos != std::string::npos) + { + msg += local_trans::a2u(callback::option_name_2_title(notice.substr(0, pos).c_str()), CP_UTF8) + L"\r\n"; + notice.erase(0, pos + 2); + pos = notice.find("\r\n"); + } + MessageBoxW(NULL, msg.c_str(), L"\u52A0\u8F7D\u914D\u7F6E", MB_OK | MB_ICONINFORMATION); + } +} void scanner::load_config(const wchar_t* file) { cfg_->load_from_file(file); + update_config(); } void scanner::save_config(const wchar_t* file) { @@ -236,14 +373,13 @@ void scanner::save_config(const wchar_t* file) } void scanner::apply_config(void) { - std::string t(""), v(""), ver(cfg_->get_version()); + std::string n(""), v(""), ver(cfg_->get_version()); std::wstring notice(L""); - if (cfg_->first_config(t, v)) + if (cfg_->first_config(n, v)) { - bool rewrite = false; do { - int id = cfg_->id_from_title(t.c_str()); + int id = cfg_->id_from_name(n.c_str()); if (id != -1) { void* data = &v[0]; @@ -251,8 +387,9 @@ void scanner::apply_config(void) const SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, id); if (desc) { - char* buf = NULL; - bool omit = false; + char* buf = NULL; + SANE_Int after = 0; + if (desc->type == SANE_TYPE_STRING) { buf = new char[desc->size + 4]; @@ -260,42 +397,13 @@ void scanner::apply_config(void) strcpy(buf, v.c_str()); data = buf; } - else if (ver.empty() && desc->type == SANE_TYPE_FIXED) // 升级早期版本没将float转为SANE_Fixed的BUG - { - cfg_->remove_config(t.c_str()); - rewrite = true; - omit = true; + hg_sane_middleware::instance()->set_option(handle_, id, SANE_ACTION_SET_VALUE, data, &after); - { - wchar_t msg[128] = { 0 }; - std::wstring name(local_trans::a2u(t.c_str(), CP_UTF8)); - unsigned char* f = (unsigned char*)&v[0]; - - notice += name + L"\r\n"; - name.insert(0, L"Discard old configuration '"); - swprintf_s(msg, _countof(msg) - 1, L"' of value '%02X%02X%02X%02X'\r\n", f[0], f[1], f[2], f[3]); - log_info((name + msg).c_str(), 0); - } - } - if (!omit) - { - SANE_Int after = 0; - hg_sane_middleware::instance()->set_option(handle_, id, SANE_ACTION_SET_VALUE, data, &after); - } if (buf) delete[] buf; } } - } while (cfg_->next_config(t, v)); - if (rewrite) - { - cfg_->save_to(NULL); - if (notice.length()) - { - notice.insert(0, L"\u4E0B\u5217\u914D\u7F6E\u6570\u636E\u9519\u8BEF\uFF0C\u5DF2\u7ECF\u6062\u590D\u5230\u9ED8\u8BA4\u503C\u3002\u5982\u679C\u9700\u8981\uFF0C\u8BF7\u91CD\u65B0\u8BBE\u7F6E\uFF1A\r\n\r\n"); - MessageBoxW(NULL, notice.c_str(), L"\u52A0\u8F7D\u914D\u7F6E", MB_OK | MB_ICONINFORMATION); - } - } + } while (cfg_->next_config(n, v)); } } void scanner::on_ui_event(int uev, void* sender) @@ -391,7 +499,7 @@ int scanner::init_options_id(void) break; } if (len) - cfg_->set_default_value(op_id, desc->title, (char*)val, len); + cfg_->set_default_value(op_id, desc->name, (char*)val, len); local_utility::free_memory(val); } @@ -501,6 +609,7 @@ int scanner::init_options_id(void) ea.ex_api = &scanner::handle_ex_search_hole_range; ex_opts_.push_back(ea); } + return ret; } int scanner::control_read_string(int code, std::string& ret) @@ -2205,6 +2314,7 @@ COM_API_IMPLEMENT(scanner, int, twain_set_config(char* buf, size_t len)) { if(cfg_->load_from_mem(buf)) { + update_config(); apply_config(); return SCANNER_ERR_OK; diff --git a/sane/scanner.h b/sane/scanner.h index e79e1fb..7851577 100644 --- a/sane/scanner.h +++ b/sane/scanner.h @@ -53,6 +53,7 @@ class scanner : public ISaneInvoker, virtual public refer std::unique_ptr setting_; gb::sane_config* cfg_; + void update_config(void); void load_config(const wchar_t* file); void save_config(const wchar_t* file); void apply_config(void); @@ -177,6 +178,7 @@ class scanner : public ISaneInvoker, virtual public refer static int __stdcall to_int(SANE_Int v); static float __stdcall to_float(SANE_Fixed v); static void __stdcall ui_callback(int uev, void* sender, void* param); + static bool __stdcall is_option_float(int sn, void* param); public: scanner(SCANNERID id);