将start_scan调用,移到独立线程

This commit is contained in:
gb 2023-05-29 09:11:09 +08:00
parent 70b6a2e317
commit d03b679add
2 changed files with 79 additions and 55 deletions

View File

@ -21,6 +21,8 @@
#pragma comment(lib, "Shlwapi.lib") #pragma comment(lib, "Shlwapi.lib")
#define START_SCAN_IN_THREAD
static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt); static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
#define SET_SANE_OPT_ID(id, id_name, name, val, extension) \ #define SET_SANE_OPT_ID(id, id_name, name, val, extension) \
@ -490,6 +492,10 @@ scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BAS
scanner::~scanner() scanner::~scanner()
{ {
close(); close();
if (thread_starting_.get() && thread_starting_->joinable())
thread_starting_->join();
thread_starting_.reset();
if (cfg_) if (cfg_)
{ {
cfg_->release(); cfg_->release();
@ -1388,6 +1394,67 @@ int scanner::set_is_multiout(bool enable)
return ret; return ret;
} }
int scanner::thread_start(void)
{
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 ...
if (ret == SANE_STATUS_NO_DOCS && prev_start_result_ == SANE_STATUS_GOOD)
ret = hg_sane_middleware::instance()->start(handle_, NULL);
if (ret == SANE_STATUS_GOOD)
{
/*if (indicator_.get() && !IsWindowVisible(indicator_->hwnd()))
indicator_->show(true);*/
unsigned int l = sizeof(img_fmt_);
SANE_CompressionType cmprsn = img_fmt_.compress.compression;
if (hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_FINAL_IMAGE_FORMAT, &img_fmt_, &l))
img_fmt_.img_format = SANE_IMAGE_TYPE_BMP;
img_fmt_.compress.compression = cmprsn;
}
//else if (indicator_.get())
//{
// indicator_->notify_scan_over(hg_scanner_err_description(ret), true);
//}
else
{
// display error message on progress UI, may be closed immediately by APP, so we hide progress UI and call message_box ...
//
//if (callback::show_progress_ui && is_bIndicator)
//{
// int ev = SANE_EVENT_WORKING;
//
//// on_ui_event(ev, (void*)ev);
// ui_notify(SANE_EVENT_SCAN_FINISHED, (void *)hg_scanner_err_description(ret), ret);
//}
//else
{
if (callback::close_ui)
callback::close_ui(UI_INDICATOR);
if (callback::show_messagebox_ui)
{
callback::show_messagebox_ui(app_wnd_, ret, (void*)hg_scanner_err_description(ret), 0);
}
else
{
std::wstring msg(local_trans::a2u(hg_scanner_err_description(ret), CP_UTF8));
//if (indicator_.get())
// indicator_->show(false);
if (!IsWindow(app_wnd_))
callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_START_FAILED).c_str());
MessageBoxW(app_wnd_, msg.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_START_FAILED).c_str(), MB_OK | MB_ICONERROR);
}
}
is_scanning_ = false;
}
prev_start_result_ = ret;
return ret;
}
scanner::EXAPIPOS scanner::find_ex_api(int op_id) scanner::EXAPIPOS scanner::find_ex_api(int op_id)
{ {
return std::find(ex_opts_.begin(), ex_opts_.end(), op_id); return std::find(ex_opts_.begin(), ex_opts_.end(), op_id);
@ -2452,64 +2519,18 @@ COM_API_IMPLEMENT(scanner, int, start(void))
scan_err_ = false; scan_err_ = false;
user_cancel_ = false; user_cancel_ = false;
fetch_imgs_ = 0; fetch_imgs_ = 0;
is_scanning_ = true;
app_wnd_ = setting_.get() ? setting_->hwnd() : callback::find_main_wnd(); app_wnd_ = setting_.get() ? setting_->hwnd() : callback::find_main_wnd();
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 ... if (thread_starting_.get() && thread_starting_->joinable())
if(ret == SANE_STATUS_NO_DOCS && prev_start_result_ == SANE_STATUS_GOOD) thread_starting_->join();
ret = hg_sane_middleware::instance()->start(handle_, NULL); #ifdef START_SCAN_IN_THREAD
thread_starting_.reset(new std::thread(&scanner::thread_start, this));
#else
ret = thread_start();
#endif
if (ret == SANE_STATUS_GOOD) return ret;
{
/*if (indicator_.get() && !IsWindowVisible(indicator_->hwnd()))
indicator_->show(true);*/
unsigned int l = sizeof(img_fmt_);
SANE_CompressionType cmprsn = img_fmt_.compress.compression;
if (hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_FINAL_IMAGE_FORMAT, &img_fmt_, &l))
img_fmt_.img_format = SANE_IMAGE_TYPE_BMP;
img_fmt_.compress.compression = cmprsn;
}
//else if (indicator_.get())
//{
// indicator_->notify_scan_over(hg_scanner_err_description(ret), true);
//}
else
{
// display error message on progress UI, may be closed immediately by APP, so we hide progress UI and call message_box ...
//
//if (callback::show_progress_ui && is_bIndicator)
//{
// int ev = SANE_EVENT_WORKING;
//
//// on_ui_event(ev, (void*)ev);
// ui_notify(SANE_EVENT_SCAN_FINISHED, (void *)hg_scanner_err_description(ret), ret);
//}
//else
{
if (callback::close_ui)
callback::close_ui(UI_INDICATOR);
if (callback::show_messagebox_ui)
{
callback::show_messagebox_ui(app_wnd_, ret, (void*)hg_scanner_err_description(ret), 0);
}
else
{
std::wstring msg(local_trans::a2u(hg_scanner_err_description(ret), CP_UTF8));
//if (indicator_.get())
// indicator_->show(false);
if (!IsWindow(app_wnd_))
callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_START_FAILED).c_str());
MessageBoxW(app_wnd_, msg.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_START_FAILED).c_str(), MB_OK | MB_ICONERROR);
}
}
}
prev_start_result_ = ret;
is_scanning_ = ret == SANE_STATUS_GOOD;
return local_utility::sane_statu_2_scanner_err(ret);
} }
COM_API_IMPLEMENT(scanner, int, stop(void)) COM_API_IMPLEMENT(scanner, int, stop(void))
{ {

View File

@ -104,6 +104,9 @@ class scanner : public ISaneInvoker, virtual public refer
int set_option_value(int sn, SANE_Value_Type type, int size, void* data); int set_option_value(int sn, SANE_Value_Type type, int size, void* data);
int set_is_multiout(bool enable); int set_is_multiout(bool enable);
int thread_start(void);
std::unique_ptr<std::thread> thread_starting_;
typedef struct _ex_api typedef struct _ex_api
{ {
unsigned int ind; unsigned int ind;