进度条,放到最后一张图片被取走后才关闭。(改原来事件中直接调用,为在新线程中等待图片取完后再调用)

This commit is contained in:
gb 2023-10-11 13:54:17 +08:00
parent ed9a477328
commit 6a8631625d
2 changed files with 64 additions and 37 deletions

View File

@ -781,6 +781,38 @@ void __stdcall scanner::apply_scheme(gb::sane_config_schm* schm, void* param)
((scanner*)param)->apply_scheme(schm); ((scanner*)param)->apply_scheme(schm);
} }
void scanner::scan_done(void)
{
std::string msg(scan_msg_);
while (images_.count())
std::this_thread::sleep_for(std::chrono::milliseconds(5));
if (indicator_.get())
indicator_->notify_scan_over(&msg[0], err_ != SCANNER_ERR_OK);
else if (ui_notify)
ui_notify(SANE_EVENT_SCAN_FINISHED, &msg[0], err_);
else
{
if (err_)
{
if (callback::show_messagebox_ui)
{
callback::show_messagebox_ui(app_wnd_, SANE_EVENT_SCAN_FINISHED, (void*)&msg[0], 0);
}
else // windows message box ...
{
std::wstring text(local_trans::a2u(msg.c_str(), CP_UTF8));
if (!IsWindow(app_wnd_))
callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str());
MessageBoxW(app_wnd_, text.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str(), MB_OK);
}
}
on_ui_event(SANE_EVENT_SCAN_FINISHED, (void*)SANE_EVENT_SCAN_FINISHED);
}
// is_scanning_ = false;
}
// IRef // IRef
COM_API_IMPLEMENT(scanner, long, add_ref(void)) COM_API_IMPLEMENT(scanner, long, add_ref(void))
{ {
@ -1071,6 +1103,10 @@ int scanner::open(void)
} }
int scanner::close(void) int scanner::close(void)
{ {
images_.clear();
if (done_.get() && done_->joinable())
done_->join();
scanner_ev_handler_ = NULL; scanner_ev_handler_ = NULL;
ui_hide(); ui_hide();
callback::unreg_callback(this); callback::unreg_callback(this);
@ -1551,6 +1587,8 @@ int scanner::set_is_multiout(bool enable)
int scanner::thread_start(void) int scanner::thread_start(void)
{ {
scan_over_ = false;
int ret = hg_sane_middleware::instance()->start(handle_, NULL); int ret = hg_sane_middleware::instance()->start(handle_, NULL);
// the third-APPs in linux will call 'stop' after every start, but it not happens in windows-apps, so we handle this as following ... // the third-APPs in linux will call 'stop' after every start, but it not happens in windows-apps, so we handle this as following ...
@ -1586,6 +1624,7 @@ int scanner::thread_start(void)
else else
#endif #endif
{ {
scan_over_ = true;
if (callback::close_ui) if (callback::close_ui)
callback::close_ui(UI_INDICATOR); callback::close_ui(UI_INDICATOR);
@ -3597,29 +3636,13 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len)
else if (ev_code == SANE_EVENT_SCAN_FINISHED) else if (ev_code == SANE_EVENT_SCAN_FINISHED)
{ {
err_ = *len; err_ = *len;
if (indicator_.get()) scan_over_ = true;
indicator_->notify_scan_over((char*)data, *len != SCANNER_ERR_OK); scan_msg_ = data ? (char*)data : "OK";
else if (ui_notify)
ui_notify(ev_code, data, *len); if (done_.get() && done_->joinable())
else done_->join();
{ done_.reset(new std::thread(&scanner::scan_done, this));
if (*len) // scan_done(); // invoking move to the last image fetched
{
if (callback::show_messagebox_ui)
{
callback::show_messagebox_ui(app_wnd_, ev_code, (void*)data, 0);
}
else // windows message box ...
{
std::wstring msg(local_trans::a2u((char*)data, CP_UTF8));
if (!IsWindow(app_wnd_))
callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str());
MessageBoxW(app_wnd_, msg.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str(), MB_OK);
}
}
on_ui_event(ev_code, (void*)ev_code);
}
// is_scanning_ = false;
{ {
wchar_t msg[128] = { 0 }; wchar_t msg[128] = { 0 };

View File

@ -57,12 +57,13 @@ class scanner : public ISaneInvoker, virtual public refer
bool scan_err_; bool scan_err_;
volatile bool is_ui_wait_img_; volatile bool is_ui_wait_img_;
volatile bool is_scanning_; volatile bool is_scanning_;
volatile bool scan_over_;
volatile bool user_cancel_; volatile bool user_cancel_;
twain_xfer xfer_; twain_xfer xfer_;
safe_img_queue images_; safe_img_queue images_;
size_t max_img_mem_; size_t max_img_mem_;
size_t wait_fetch_; // ms, wait time when image-queue is great than max_img_mem_, default 1min size_t wait_fetch_; // ms, wait time when image-queue is great than max_img_mem_, default 1min
safe_queue<int> events_; //如果有界面,则全部保存从界面传回的消息;否则只保存开始扫描和结束扫描的事件 safe_queue<int> events_; //å¦æžœæœ‰ç•Œé<EFBFBD>¢ï¼Œåˆ™å…¨éƒ¨ä¿<EFBFBD>存从界é<EFBFBD>¢ä¼ åžçš„消æ<EFBFBD>¯ï¼å<EFBFBD>¦åˆ™å<EFBFBD>ªä¿<EFBFBD>存开å§æ‰«æ<EFBFBD><EFBFBD>åŒç»“æ<EFBFBD>Ÿæ‰«æ<EFBFBD><EFBFBD>çš„äºä»?
int ev_cnt_; int ev_cnt_;
SANE_FinalImgFormat img_fmt_; SANE_FinalImgFormat img_fmt_;
std::unique_ptr<dlg_indicator> indicator_; std::unique_ptr<dlg_indicator> indicator_;
@ -70,6 +71,7 @@ class scanner : public ISaneInvoker, virtual public refer
gb::scanner_cfg* cfg_; gb::scanner_cfg* cfg_;
bool twain_set_; bool twain_set_;
SANEAPI sane_api_; SANEAPI sane_api_;
std::unique_ptr<std::thread> done_;
std::map<sane_option_id, int> sane_ids_; // <fix-id, sane-option-sn> std::map<sane_option_id, int> sane_ids_; // <fix-id, sane-option-sn>
std::function<void(int, void*, int)> ui_notify; std::function<void(int, void*, int)> ui_notify;
int(__stdcall* scanner_ev_handler_)(int, void*); int(__stdcall* scanner_ev_handler_)(int, void*);
@ -192,6 +194,8 @@ class scanner : public ISaneInvoker, virtual public refer
static bool is_option_float(int sn, void* param); static bool is_option_float(int sn, void* param);
static void __stdcall apply_scheme(gb::sane_config_schm* schm, void* param); static void __stdcall apply_scheme(gb::sane_config_schm* schm, void* param);
void scan_done(void);
public: public:
scanner(SCANNERID id); scanner(SCANNERID id);
protected: protected:
@ -246,7 +250,7 @@ public:
SANE_OPTION_ID(background_color_range); SANE_OPTION_ID(background_color_range);
SANE_OPTION_ID(sharpen); SANE_OPTION_ID(sharpen);
SANE_OPTION_ID(erase_morr); SANE_OPTION_ID(erase_morr);
SANE_OPTION_ID(erase_grids); // 除网纹 SANE_OPTION_ID(erase_grids); // 除网çº?
SANE_OPTION_ID(error_extend); SANE_OPTION_ID(error_extend);
SANE_OPTION_ID(is_noise_modify); SANE_OPTION_ID(is_noise_modify);
SANE_OPTION_ID(noise_threshold); SANE_OPTION_ID(noise_threshold);
@ -261,7 +265,7 @@ public:
SANE_OPTION_ID(blank_page_threshold); // 跳过空白页灵敏度 SANE_OPTION_ID(blank_page_threshold); // 跳过空白页灵敏度
SANE_OPTION_ID(resolution); SANE_OPTION_ID(resolution);
SANE_OPTION_ID(image_quality); SANE_OPTION_ID(image_quality);
SANE_OPTION_ID(is_swap); // 交换正反面 SANE_OPTION_ID(is_swap); // 交æ<EFBFBD>¢æ­£å<EFBFBD><EFBFBD>é<EFBFBD>?
SANE_OPTION_ID(is_split); // 图像拆分 SANE_OPTION_ID(is_split); // 图像拆分
SANE_OPTION_ID(is_auto_deskew); // 自动纠偏 SANE_OPTION_ID(is_auto_deskew); // 自动纠偏
SANE_OPTION_ID(is_custom_gamma); SANE_OPTION_ID(is_custom_gamma);
@ -289,25 +293,25 @@ public:
SANE_OPTION_ID(dogear_size); SANE_OPTION_ID(dogear_size);
SANE_OPTION_ID(is_check_skew); SANE_OPTION_ID(is_check_skew);
SANE_OPTION_ID(skew_range); SANE_OPTION_ID(skew_range);
SANE_OPTION_ID(black_white_threshold); // 二值化图像阈值 SANE_OPTION_ID(black_white_threshold); // 二值åŒå¾åƒ<EFBFBD>阈å€?
SANE_OPTION_ID(is_photo_mode); // 照片模式 SANE_OPTION_ID(is_photo_mode); // 照片模式
SANE_OPTION_ID(double_feed_handle); // 双张图片处理 SANE_OPTION_ID(double_feed_handle); // 双张图片处理
SANE_OPTION_ID(scan_when_paper_on); // 待纸扫描 SANE_OPTION_ID(scan_when_paper_on); // 待纸扫描
SANE_OPTION_ID(feed_strength); // 分纸强度 SANE_OPTION_ID(feed_strength); // 分纸强度
SANE_OPTION_ID(power_scheme); // 休眠时间 SANE_OPTION_ID(power_scheme); // 休眠时间
SANE_OPTION_ID(is_auto_strength); // 自动搓纸强度 SANE_OPTION_ID(is_auto_strength); // 自动搓纸强度
SANE_OPTION_ID(feed_strength_value); // 自动搓纸强度设定值 SANE_OPTION_ID(feed_strength_value); // 自动æ<EFBFBD>“纸强度设定å€?
SANE_OPTION_ID(is_reverse_bw); // 黑白图像反色输出 SANE_OPTION_ID(is_reverse_bw); // 黑白图像反色输出
SANE_OPTION_ID(is_erase_hole_l); // 穿孔移除 - 左 SANE_OPTION_ID(is_erase_hole_l); // 穿孔移除 - å·?
SANE_OPTION_ID(search_hole_range_l); // 穿孔搜索范围 - 左 SANE_OPTION_ID(search_hole_range_l); // ç©¿å­”æ<EFBFBD>œç´¢èŒƒå´ - å·?
SANE_OPTION_ID(is_erase_hole_r); // 穿孔移除 - 右 SANE_OPTION_ID(is_erase_hole_r); // 穿孔移除 - å<>?
SANE_OPTION_ID(search_hole_range_r); // 穿孔搜索范围 - 右 SANE_OPTION_ID(search_hole_range_r); // ç©¿å­”æ<EFBFBD>œç´¢èŒƒå´ - å<>?
SANE_OPTION_ID(is_erase_hole_t); // 穿孔移除 - 上 SANE_OPTION_ID(is_erase_hole_t); // 穿孔移除 - ä¸?
SANE_OPTION_ID(search_hole_range_t); // 穿孔搜索范围 - 上 SANE_OPTION_ID(search_hole_range_t); // ç©¿å­”æ<EFBFBD>œç´¢èŒƒå´ - ä¸?
SANE_OPTION_ID(is_erase_hole_b); // 穿孔移除 - 下 SANE_OPTION_ID(is_erase_hole_b); // 穿孔移除 - ä¸?
SANE_OPTION_ID(search_hole_range_b); // 穿孔搜索范围 - 下 SANE_OPTION_ID(search_hole_range_b); // ç©¿å­”æ<EFBFBD>œç´¢èŒƒå´ - ä¸?
SANE_OPTION_ID(fold_direction); // 对折模式 SANE_OPTION_ID(fold_direction); // 对折模式
SANE_OPTION_ID(discardblank); // 跳过空白页 SANE_OPTION_ID(discardblank); // 跳过空白é¡?
// SANE-ex option ID: // SANE-ex option ID:
SANE_OPTION_ID(ex_multiout_type); // int SANE_OPTION_ID(ex_multiout_type); // int