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;
break;
case WM_SCAN_WORKING:
notify_ui_event(SANE_EVENT_WORKING);
// notify_ui_event(SANE_EVENT_WORKING);
break;
case WM_SCAN_FINISHED:
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)
, 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)
, 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_close_api = inner_sane_close;
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)
{
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;
}
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 (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() &&
(ev_cnt_ >= 5 || (ev_cnt_ > 1 && !is_scanning_)))
{
// maybe no event has been handled by APP, triggered by callback
int(__stdcall * h)(int, void*) = scanner_ev_handler_;
if (h)
{
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_);
ev_cnt_--;
h(events_.take(), evh_param_);
}
}
//if (ev_cnt_ == events_.count() &&
// (ev_cnt_ >= 5 || (ev_cnt_ > 1 && !is_scanning_)))
//{
// // maybe no event has been handled by APP, triggered by callback
// int(__stdcall * h)(int, void*) = scanner_ev_handler_;
// if (h)
// {
// 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_);
// ev_cnt_--;
// h(events_.take(), evh_param_);
// }
//}
}
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))
{
size_t count = images_.count();
DWORD elapse = 10;
DWORD elapse = 2;
is_ui_wait_img_ = true;
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))
{
is_show_ui_ = with_scan;
is_show_setting_ = true;
events_.clear();
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))
{
is_bIndicator = bIndicator;
ui_notify = std::function<void(int, void*, int)>();
auto ui_process = [this](ui_result res)
{
int uev = SANE_EVENT_SCAN_FINISHED;
@ -3161,14 +3172,14 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent, bool bIndicator))
}
else
{
/*if (setting_.get() && IsWindowVisible(setting_->hwnd()))
if (setting_.get() && IsWindowVisible(setting_->hwnd()))
parent = setting_->hwnd();
else if (!IsWindow(parent))
parent = callback::find_main_wnd();
indicator_.reset(new dlg_indicator(parent));
indicator_->set_ui_event_notify(&scanner::ui_callback, this);
indicator_->show(true);*/
indicator_->show(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 (indicator_.get())
// indicator_->notify_working();
//else on_ui_event(ev_code, (void*)ev_code);
if (callback::show_progress_ui && is_bIndicator)
if (indicator_.get())
indicator_->notify_working();
else if (callback::show_progress_ui && is_bIndicator)
ui_notify(ev_code, data, *len);
//else
on_ui_event(ev_code, (void*)ev_code);
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();
}
//if (indicator_.get())
// indicator_->notify_data_arrived(true);
if (indicator_.get())
indicator_->notify_data_arrived(true);
else if (ui_notify)
ui_notify(ev_code, data, 1);
{
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)
{
//if (indicator_.get())
// indicator_->notify_data_arrived(false);
if (indicator_.get())
indicator_->notify_data_arrived(false);
else if (ui_notify)
ui_notify(ev_code, data, 0);
}
else if (ev_code == SANE_EVENT_SCAN_FINISHED)
{
err_ = *len;
//if (indicator_.get())
// indicator_->notify_scan_over((char*)data, *len != SCANNER_ERR_OK);
if (callback::show_progress_ui && is_bIndicator)
if (indicator_.get())
indicator_->notify_scan_over((char*)data, *len != SCANNER_ERR_OK);
else if (ui_notify)
ui_notify(ev_code, data, *len);
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);
}
else if (*len) //错误弹出
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;

View File

@ -47,6 +47,7 @@ class scanner : public ISaneInvoker, virtual public refer
int prev_start_result_;
int dpi_;
bool is_bIndicator;
bool is_show_setting_;
unsigned int img_ind_;
std::wstring scanner_name_;
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;
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(); });
}
@ -939,6 +940,7 @@ Result huagao_ds::identityOpenDs(const Identity& id)
//
// return { ReturnCode::Failure, ConditionCode::CapBadOperation };
//}
is_getting_count_ = false;
if (!load_sane_util::is_ok())
load_sane_util::initialize(me_);
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)
{
if (scanner_.get())
{
scanner_->stop();
scanner_->ui_hide();
}
return success();
}
@ -1565,6 +1570,37 @@ Twpp::Result huagao_ds::setupFileXferReset(const Twpp::Identity& origin, Twpp::S
return badProtocol();
}
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 {
// 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)));
@ -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));
load_sane_util::log_info(buf, 0);
}
in_calling = calling;
return rt;
}
catch (const CapabilityException& e) {
//FileTools::writelog(log_ERROR, e.what());
UNREFERENCED_PARAMETER(e);
in_calling = calling;
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
//break;
case SANE_EVENT_UI_CLOSE_NORMAL:
case SANE_EVENT_UI_CLOSE_SETTING:
scanner_->ui_hide();
case SANE_EVENT_SCAN_FINISHED:
scanner_status_ = SCANNER_STATUS_STOPPED;
//notifyCloseOk();
//break;
case SANE_EVENT_UI_CLOSE_SETTING:
rc = notifyCloseCancel();
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)
{
is_getting_count_ = true;
int cnt = scanner_->get_scanned_images(timeout);
//if (cnt == -1)
@ -3582,6 +3622,7 @@ int huagao_ds::get_scanned_image_count(DWORD timeout)
// scanner_->ui_hide();
// notifyCloseCancel();
//}
is_getting_count_ = false;
return cnt;
}

View File

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