DS_Entry在嵌套调用时,不处理事件消息以确保事件时序正确;驱动事件暂时不调用回调,依靠APP主动触发

This commit is contained in:
gb 2023-05-13 18:33:36 +08:00
parent 78a9c23b3f
commit 957c901dc9
5 changed files with 136 additions and 78 deletions

View File

@ -108,7 +108,7 @@ BOOL dlg_indicator::handle_message(UINT msg, WPARAM wp, LPARAM lp)
ret = FALSE; ret = FALSE;
break; break;
case WM_SCAN_WORKING: case WM_SCAN_WORKING:
notify_ui_event(SANE_EVENT_WORKING); // notify_ui_event(SANE_EVENT_WORKING);
break; break;
case WM_SCAN_FINISHED: case WM_SCAN_FINISHED:
finish_ = true; finish_ = true;

View File

@ -388,8 +388,10 @@ scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BAS
, dpi_(200), tmp_path_(L""), img_ind_(0) , dpi_(200), tmp_path_(L""), img_ind_(0)
, scanner_name_(L""), cfg_(NULL), is_ui_wait_img_(false), is_scanning_(false) , scanner_name_(L""), cfg_(NULL), is_ui_wait_img_(false), is_scanning_(false)
, 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), is_bIndicator(false) , max_img_mem_(1 * 1024), twain_set_(false), ev_cnt_(0), is_bIndicator(false), is_show_setting_(false)
{ {
ui_notify = std::function<void(int, void*, int)>();
sane_api_.sane_cancel_api = inner_sane_cancel; sane_api_.sane_cancel_api = inner_sane_cancel;
sane_api_.sane_close_api = inner_sane_close; sane_api_.sane_close_api = inner_sane_close;
sane_api_.sane_control_option_api = inner_sane_control_option; sane_api_.sane_control_option_api = inner_sane_control_option;
@ -711,50 +713,57 @@ void scanner::apply_config(void)
} }
void scanner::on_ui_event(int uev, void* sender) void scanner::on_ui_event(int uev, void* sender)
{ {
if (uev == SANE_EVENT_UI_SCAN_COMMAND) //UI主动通知 if (uev == SANE_EVENT_SCAN_FINISHED || uev == SANE_EVENT_UI_CLOSE_CANCEL || uev == SANE_EVENT_UI_CLOSE_NORMAL)
{ {
int(__stdcall * h)(int, void*) = scanner_ev_handler_;
if (h)
{
//wchar_t info[128] = { 0 };
//(info, _countof(info) - 1, L"[CRAZY]%d scanner events stored but APP has no action, we try to trigger it ONCE ...\r\n", ev_cnt_);
ev_cnt_;
h(SANE_EVENT_UI_SCAN_COMMAND, evh_param_);
return;
}
}
if (uev == SANE_EVENT_SCAN_FINISHED || uev == SANE_EVENT_UI_CLOSE_NORMAL || uev == SANE_EVENT_UI_CLOSE_CANCEL)
{
if (uev == SANE_EVENT_UI_CLOSE_CANCEL)
stop();
is_scanning_ = false; is_scanning_ = false;
} }
if (uev == SANE_EVENT_UI_CLOSE_CANCEL || uev == SANE_EVENT_UI_CLOSE_NORMAL || uev == SANE_EVENT_UI_CLOSE_SETTING)
{
events_.clear();
uev = SANE_EVENT_UI_CLOSE_SETTING;
}
events_.save(uev, sizeof(uev)); events_.save(uev, sizeof(uev));
ev_cnt_++;
//if (uev == SANE_EVENT_UI_SCAN_COMMAND) //UI主动通知
//{
// int(__stdcall * h)(int, void*) = scanner_ev_handler_;
// if (h)
// {
// //wchar_t info[128] = { 0 };
// //(info, _countof(info) - 1, L"[CRAZY]%d scanner events stored but APP has no action, we try to trigger it ONCE ...\r\n", ev_cnt_);
// ev_cnt_;
// h(SANE_EVENT_UI_SCAN_COMMAND, evh_param_);
// return;
// }
//}
//if (uev == SANE_EVENT_SCAN_FINISHED || uev == SANE_EVENT_UI_CLOSE_NORMAL || uev == SANE_EVENT_UI_CLOSE_CANCEL)
//{
// if (uev == SANE_EVENT_UI_CLOSE_CANCEL)
// stop();
// is_scanning_ = false;
//}
//if (uev == SANE_EVENT_UI_CLOSE_CANCEL || uev == SANE_EVENT_UI_CLOSE_NORMAL || uev == SANE_EVENT_UI_CLOSE_SETTING)
//{
// events_.clear();
// uev = SANE_EVENT_UI_CLOSE_SETTING;
//}
//events_.save(uev, sizeof(uev));
//ev_cnt_++;
if (ev_cnt_ == events_.count() && //if (ev_cnt_ == events_.count() &&
(ev_cnt_ >= 5 || (ev_cnt_ > 1 && !is_scanning_))) // (ev_cnt_ >= 5 || (ev_cnt_ > 1 && !is_scanning_)))
{ //{
// maybe no event has been handled by APP, triggered by callback // // maybe no event has been handled by APP, triggered by callback
int(__stdcall * h)(int, void*) = scanner_ev_handler_; // int(__stdcall * h)(int, void*) = scanner_ev_handler_;
if (h) // if (h)
{ // {
wchar_t info[128] = { 0 }; // wchar_t info[128] = { 0 };
swprintf_s(info, _countof(info) - 1, L"[CRAZY]%d scanner events stored but APP has no action, we try to trigger it ONCE ...\r\n", ev_cnt_); // swprintf_s(info, _countof(info) - 1, L"[CRAZY]%d scanner events stored but APP has no action, we try to trigger it ONCE ...\r\n", ev_cnt_);
ev_cnt_--; // ev_cnt_--;
h(events_.take(), evh_param_); // h(events_.take(), evh_param_);
} // }
} //}
} }
std::string scanner::choose_scanner(const std::vector<std::string>& scanners) std::string scanner::choose_scanner(const std::vector<std::string>& scanners)
{ {
@ -2483,7 +2492,7 @@ COM_API_IMPLEMENT(scanner, bool, wait_image(DWORD milliseconds))
COM_API_IMPLEMENT(scanner, int, get_scanned_images(DWORD milliseconds)) COM_API_IMPLEMENT(scanner, int, get_scanned_images(DWORD milliseconds))
{ {
size_t count = images_.count(); size_t count = images_.count();
DWORD elapse = 10; DWORD elapse = 2;
is_ui_wait_img_ = true; is_ui_wait_img_ = true;
while (is_scanning_ && count == 0 && milliseconds) while (is_scanning_ && count == 0 && milliseconds)
@ -3035,6 +3044,7 @@ 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))
{ {
is_show_ui_ = with_scan; is_show_ui_ = with_scan;
is_show_setting_ = true;
events_.clear(); events_.clear();
if (callback::show_setting_ui) if (callback::show_setting_ui)
{ {
@ -3123,6 +3133,7 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan, bo
COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent, bool bIndicator)) COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent, bool bIndicator))
{ {
is_bIndicator = bIndicator; is_bIndicator = bIndicator;
ui_notify = std::function<void(int, void*, int)>();
auto ui_process = [this](ui_result res) auto ui_process = [this](ui_result res)
{ {
int uev = SANE_EVENT_SCAN_FINISHED; int uev = SANE_EVENT_SCAN_FINISHED;
@ -3161,14 +3172,14 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent, bool bIndicator))
} }
else 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))
parent = callback::find_main_wnd(); parent = callback::find_main_wnd();
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;
@ -3192,13 +3203,10 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len)
{ {
if (ev_code == SANE_EVENT_WORKING) if (ev_code == SANE_EVENT_WORKING)
{ {
//if (indicator_.get()) if (indicator_.get())
// indicator_->notify_working(); indicator_->notify_working();
//else on_ui_event(ev_code, (void*)ev_code); else if (callback::show_progress_ui && is_bIndicator)
if (callback::show_progress_ui && is_bIndicator)
ui_notify(ev_code, data, *len); ui_notify(ev_code, data, *len);
//else
on_ui_event(ev_code, (void*)ev_code); on_ui_event(ev_code, (void*)ev_code);
log_info(L"Scanning ...\r\n", 0); log_info(L"Scanning ...\r\n", 0);
} }
@ -3232,8 +3240,10 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len)
{ {
img->release(); img->release();
} }
//if (indicator_.get()) if (indicator_.get())
// indicator_->notify_data_arrived(true); indicator_->notify_data_arrived(true);
else if (ui_notify)
ui_notify(ev_code, data, 1);
{ {
wchar_t msg[128] = { 0 }; wchar_t msg[128] = { 0 };
@ -3243,29 +3253,34 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len)
} }
else if (ev_code == SANE_EVENT_USB_DATA_RECEIVED) else if (ev_code == SANE_EVENT_USB_DATA_RECEIVED)
{ {
//if (indicator_.get()) if (indicator_.get())
// indicator_->notify_data_arrived(false); indicator_->notify_data_arrived(false);
else if (ui_notify)
ui_notify(ev_code, data, 0);
} }
else if (ev_code == SANE_EVENT_SCAN_FINISHED) else if (ev_code == SANE_EVENT_SCAN_FINISHED)
{ {
err_ = *len; err_ = *len;
//if (indicator_.get()) if (indicator_.get())
// indicator_->notify_scan_over((char*)data, *len != SCANNER_ERR_OK); indicator_->notify_scan_over((char*)data, *len != SCANNER_ERR_OK);
if (callback::show_progress_ui && is_bIndicator) else if (ui_notify)
ui_notify(ev_code, data, *len); ui_notify(ev_code, data, *len);
else else
{ {
if (callback::show_messagebox_ui && *len) if (*len)
{
if (callback::show_messagebox_ui)
{ {
callback::show_messagebox_ui(app_wnd_, ev_code, (void*)data, 0); callback::show_messagebox_ui(app_wnd_, ev_code, (void*)data, 0);
} }
else if (*len) //错误弹出 else // windows message box ...
{ {
std::wstring msg(local_trans::a2u((char*)data, CP_UTF8)); std::wstring msg(local_trans::a2u((char*)data, CP_UTF8));
if (!IsWindow(app_wnd_)) if (!IsWindow(app_wnd_))
callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str()); 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); 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); on_ui_event(ev_code, (void*)ev_code);
} }
// is_scanning_ = false; // is_scanning_ = false;

View File

@ -47,6 +47,7 @@ class scanner : public ISaneInvoker, virtual public refer
int prev_start_result_; int prev_start_result_;
int dpi_; int dpi_;
bool is_bIndicator; bool is_bIndicator;
bool is_show_setting_;
unsigned int img_ind_; unsigned int img_ind_;
std::wstring scanner_name_; std::wstring scanner_name_;
std::wstring tmp_path_; std::wstring tmp_path_;

View File

@ -775,7 +775,8 @@ static const SCANNERID scanner_guid = MAKE_SCANNER_ID(PRODUCT_PID, PRODUCT_VID);
static std::once_flag oc; static std::once_flag oc;
huagao_ds::huagao_ds() : cur_head_(NULL), dpi_(200), xfer_ready_failed_(false), log_all_triple_(false), scanner_status_(SCANNER_STATUS_NOT_INIT),count_(-1), bUiOnly_(false) huagao_ds::huagao_ds() : cur_head_(NULL), dpi_(200), xfer_ready_failed_(false), log_all_triple_(false), scanner_status_(SCANNER_STATUS_NOT_INIT)
,count_(-1), bUiOnly_(false), is_getting_count_(false)
{ {
//std::call_once(oc, [&]() { log4cplus::Initializer(); }); //std::call_once(oc, [&]() { log4cplus::Initializer(); });
} }
@ -939,6 +940,7 @@ Result huagao_ds::identityOpenDs(const Identity& id)
// //
// return { ReturnCode::Failure, ConditionCode::CapBadOperation }; // return { ReturnCode::Failure, ConditionCode::CapBadOperation };
//} //}
is_getting_count_ = false;
if (!load_sane_util::is_ok()) if (!load_sane_util::is_ok())
load_sane_util::initialize(me_); load_sane_util::initialize(me_);
if (!load_sane_util::is_ok()) if (!load_sane_util::is_ok())
@ -1088,7 +1090,10 @@ Result huagao_ds::setupMemXferGet(const Identity& id, SetupMemXfer& data)
Result huagao_ds::userInterfaceDisable(const Identity&, UserInterface& ui) Result huagao_ds::userInterfaceDisable(const Identity&, UserInterface& ui)
{ {
if (scanner_.get()) if (scanner_.get())
{
scanner_->stop(); scanner_->stop();
scanner_->ui_hide();
}
return success(); return success();
} }
@ -1565,6 +1570,37 @@ Twpp::Result huagao_ds::setupFileXferReset(const Twpp::Identity& origin, Twpp::S
return badProtocol(); return badProtocol();
} }
Result huagao_ds::call(const Identity& origin, DataGroup dg, Dat dat, Msg msg, void* data) { Result huagao_ds::call(const Identity& origin, DataGroup dg, Dat dat, Msg msg, void* data) {
static bool in_calling = false;
bool calling = in_calling;
if (calling)
{
wchar_t buf[128] = { 0 }, dgs[20] = { 0 }, dts[20] = { 0 }, ms[20] = { 0 }, ss[20] = { 0 }, rcs[20] = { 0 }, cs[20] = { 0 };
if (dg == DataGroup::Control && dat == Dat::Event && msg == Msg::ProcessEvent)
{
if (is_getting_count_ && scanner_status_ == SCANNER_STATUS_SCAN_1)
{
// let it go ...
}
else
{
load_sane_util::log_info(L"Nested Call: discard 'Msg::ProcessEvent'!\r\n", 0);
return { ReturnCode::NotDsEvent, ConditionCode::Success };
}
}
else
{
swprintf_s(buf, _countof(buf) - 1, L"Nested Call: [%x - %s]DSEntry(%s, %s, %s) called in another operation! \r\n", GetCurrentThreadId(), desc_state(state(), ss),
desc_data_group(dg, dgs), desc_data(dat, dts), desc_msg(msg, ms));
load_sane_util::log_info(buf, 0);
}
}
else
{
in_calling = true;
}
try { try {
// we can override almost anything from SourceFromThis, even the top-most source instance call // we can override almost anything from SourceFromThis, even the top-most source instance call
//FileTools::write_log("D:\\1.txt", "call:datagroup-"+to_string((int)dg)+"dat-"+to_string(int(dat))+"msg-"+to_string(int(msg))); //FileTools::write_log("D:\\1.txt", "call:datagroup-"+to_string((int)dg)+"dat-"+to_string(int(dat))+"msg-"+to_string(int(msg)));
@ -1580,11 +1616,14 @@ Result huagao_ds::call(const Identity& origin, DataGroup dg, Dat dat, Msg msg, v
desc_data_group(dg, dgs), desc_data(dat, dts), desc_msg(msg, ms), desc_return_code(rt, rcs), desc_condition_code((ConditionCode)(Status)rt, cs)); desc_data_group(dg, dgs), desc_data(dat, dts), desc_msg(msg, ms), desc_return_code(rt, rcs), desc_condition_code((ConditionCode)(Status)rt, cs));
load_sane_util::log_info(buf, 0); load_sane_util::log_info(buf, 0);
} }
in_calling = calling;
return rt; return rt;
} }
catch (const CapabilityException& e) { catch (const CapabilityException& e) {
//FileTools::writelog(log_ERROR, e.what()); //FileTools::writelog(log_ERROR, e.what());
UNREFERENCED_PARAMETER(e); UNREFERENCED_PARAMETER(e);
in_calling = calling;
return badValue(); return badValue();
} }
} }
@ -3522,12 +3561,12 @@ int huagao_ds::handle_scanner_event(int ev, bool from_event_proc)
//notifyCloseCancel(); // 修复点击进度框"取消"按钮UI不能正常结束的BUG - added on 2023-02-14 //notifyCloseCancel(); // 修复点击进度框"取消"按钮UI不能正常结束的BUG - added on 2023-02-14
//break; //break;
case SANE_EVENT_UI_CLOSE_NORMAL: case SANE_EVENT_UI_CLOSE_NORMAL:
case SANE_EVENT_UI_CLOSE_SETTING:
scanner_->ui_hide(); scanner_->ui_hide();
case SANE_EVENT_SCAN_FINISHED: case SANE_EVENT_SCAN_FINISHED:
scanner_status_ = SCANNER_STATUS_STOPPED; scanner_status_ = SCANNER_STATUS_STOPPED;
//notifyCloseOk(); //notifyCloseOk();
//break; //break;
case SANE_EVENT_UI_CLOSE_SETTING:
rc = notifyCloseCancel(); rc = notifyCloseCancel();
if (!Twpp::success(rc)) if (!Twpp::success(rc))
{ {
@ -3573,6 +3612,7 @@ int huagao_ds::handle_scanner_event(int ev, bool from_event_proc)
} }
int huagao_ds::get_scanned_image_count(DWORD timeout) int huagao_ds::get_scanned_image_count(DWORD timeout)
{ {
is_getting_count_ = true;
int cnt = scanner_->get_scanned_images(timeout); int cnt = scanner_->get_scanned_images(timeout);
//if (cnt == -1) //if (cnt == -1)
@ -3582,6 +3622,7 @@ int huagao_ds::get_scanned_image_count(DWORD timeout)
// scanner_->ui_hide(); // scanner_->ui_hide();
// notifyCloseCancel(); // notifyCloseCancel();
//} //}
is_getting_count_ = false;
return cnt; return cnt;
} }

View File

@ -56,6 +56,7 @@ class huagao_ds : public Twpp::SourceFromThis<huagao_ds> {
bool app_trigger_event_; bool app_trigger_event_;
bool bUiOnly_; bool bUiOnly_;
int count_; int count_;
volatile bool is_getting_count_;
static std::string get_hidedlg_path(void); static std::string get_hidedlg_path(void);
static void showmsg(const char* msg, int err); static void showmsg(const char* msg, int err);
static int __stdcall on_scanner_event(int ev, void* param); static int __stdcall on_scanner_event(int ev, void* param);