From 0ad34a90c4bd55a634db5078dbfe91a6bc6aeb46 Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Mon, 23 Oct 2023 11:14:25 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=95=8C=E9=9D=A2=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=EF=BC=8C=E5=85=BC=E5=AE=B9=E6=A8=A1=E5=9D=97=E9=A2=91?= =?UTF-8?q?=E7=B9=81=E5=8A=A0=E8=BD=BD&=E5=8D=B8=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sane/DlgIndicator.cpp | 16 ++- sane/DlgIndicator.h | 2 +- sane/DlgPage.cpp | 219 ++++++++++++++++++++++++++++++++++++------ sane/DlgPage.h | 21 +++- sane/DlgSetting.cpp | 60 +++++++----- sane/DlgSetting.h | 3 +- sane/scanner.cpp | 112 ++++++++++++--------- sane/scanner.h | 4 +- 8 files changed, 327 insertions(+), 110 deletions(-) diff --git a/sane/DlgIndicator.cpp b/sane/DlgIndicator.cpp index c466461..7d48369 100644 --- a/sane/DlgIndicator.cpp +++ b/sane/DlgIndicator.cpp @@ -12,10 +12,11 @@ // CDlgIndicator 对话框 -dlg_indicator::dlg_indicator(HWND parent) : dlg_base(parent, IDD_INDICATOR) +dlg_indicator::dlg_indicator(HWND parent, bool sole_thread) : dlg_base(parent, IDD_INDICATOR) , papers_(0), images_(0), err_(false), finish_(false) { - create(); + del_at_destroy_ = true; + create(sole_thread); SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW); if (!dlg_base::is_language_pack_default_code_page()) @@ -34,9 +35,9 @@ dlg_indicator::dlg_indicator(HWND parent) : dlg_base(parent, IDD_INDICATOR) set_item_text(IDCANCEL, text.c_str()); int paper = get_width_diff_as_text_length(IDC_STATIC_PAPER), - img = get_width_diff_as_text_length(IDC_STATIC_IMAGE), - btn = get_width_diff_as_text_length(IDCANCEL), - diff = paper >= img + btn ? paper : img + btn; + img = get_width_diff_as_text_length(IDC_STATIC_IMAGE), + btn = get_width_diff_as_text_length(IDCANCEL), + diff = paper >= img + btn ? paper : img + btn; if (diff > 0) { @@ -157,7 +158,11 @@ void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl) { if (id == IDCANCEL) { + KillTimer(hwnd(), 1); + EnableWindow((HWND)ctrl, FALSE); notify_over(!finish_); + if (!finish_) + SetWindowTextW(hwnd(), local_trans::lang_trans_between_hz936(L"\u6B63\u5728\u505C\u6B62\u626B\u63CF\u2026\u2026").c_str()); } } void dlg_indicator::notify_over(bool cancel) @@ -187,6 +192,7 @@ void dlg_indicator::notify_scan_over(const char* msg, bool err) delete mstr; notify_over(false); } + EnableWindow(get_item(IDCANCEL), TRUE); } void dlg_indicator::notify_working(void) { diff --git a/sane/DlgIndicator.h b/sane/DlgIndicator.h index 8329e44..e66fc47 100644 --- a/sane/DlgIndicator.h +++ b/sane/DlgIndicator.h @@ -20,7 +20,7 @@ class dlg_indicator : public dlg_base void notify_over(bool cancel); public: - dlg_indicator(HWND parent); + dlg_indicator(HWND parent, bool sole_thread); ~dlg_indicator(); public: diff --git a/sane/DlgPage.cpp b/sane/DlgPage.cpp index 6a58247..f99b186 100644 --- a/sane/DlgPage.cpp +++ b/sane/DlgPage.cpp @@ -24,49 +24,129 @@ static IMPLEMENT_OPTION_STRING_COMPARE(is_sane_opt); extern HMODULE g_my_inst; std::wstring dlg_base::prop_name = L"dlg_base_object_prop_name"; +volatile bool dlg_base::msg_thread_exited_ = true; dlg_base::dlg_base(HWND parent, UINT idd) : parent_(parent), hwnd_(NULL), idd_(idd), ui_event_notify_(NULL), ui_notify_param_(NULL) + , msg_thread_id_(0), destroyed_(false), child_(false), del_at_destroy_(false) { } dlg_base::~dlg_base() { - if (IsWindow(hwnd_)) - { - SetPropW(hwnd_, dlg_base::prop_name.c_str(), NULL); - //if (GetCurrentThreadId() == GetWindowThreadProcessId(hwnd_, NULL)) - DestroyWindow(hwnd_); - } - EnableWindow(parent_, TRUE); - BringWindowToTop(parent_); + //if (IsWindow(hwnd_)) + //{ + // //SetPropW(hwnd_, dlg_base::prop_name.c_str(), NULL); + // //if (GetCurrentThreadId() == GetWindowThreadProcessId(hwnd_, NULL)) + // // DestroyWindow(hwnd_); + // //show(false); + // //PostMessage(hwnd_, WM_DESTROY, 0, 0); + //} + + //if (!child_) + //{ + // EnableWindow(parent_, TRUE); + // BringWindowToTop(parent_); + //} + + //if (msg_thread_.get()) + //{ + // PostThreadMessageW(msg_thread_id_, WM_QUIT_MSG_THREAD, 0, 0); + // if (msg_thread_->joinable()) + // msg_thread_->join(); + //} + //else + //{ + // destroyed_ = false; + // //PostMessageW(hwnd(), WM_DESTROY, 0, 0); + // //while (!destroyed_) + // //{ + // // MSG msg = { 0 }; + // // PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE); + // //} + //} } BOOL CALLBACK dlg_base::dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { + // https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nc-winuser-dlgproc: + // 尽管对话框过程类似于窗口过程,但它不得调用 DefWindowProc 函数来处理不需要的消息 + dlg_base* obj = (dlg_base*)GetPropW(hwnd, dlg_base::prop_name.c_str()); + BOOL ret = FALSE; + if (msg == WM_INITDIALOG) { - dlg_base* obj = (dlg_base*)lp; + obj = (dlg_base*)lp; SetPropW(hwnd, dlg_base::prop_name.c_str(), (HANDLE)obj); obj->hwnd_ = hwnd; + obj->child_ = (GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD) == WS_CHILD; } - else if (msg == WM_DESTROY) + else if (msg == WM_NCDESTROY) { - dlg_base* obj = (dlg_base*)GetPropW(hwnd, dlg_base::prop_name.c_str()); SetPropW(hwnd, dlg_base::prop_name.c_str(), NULL); - - return FALSE; } - dlg_base *obj = (dlg_base*)GetPropW(hwnd, dlg_base::prop_name.c_str()); - BOOL ret = FALSE; - if (obj) { ret = obj->handle_message(msg, wp, lp); + if (msg == WM_INITDIALOG) + obj->ready_ = true; + else if (msg == WM_CLOSE) + { + DestroyWindow(hwnd); + ret = TRUE; + } + else if (msg == WM_NCDESTROY) + { + if (!obj->child_) + { + EnableWindow(obj->parent_, TRUE); + BringWindowToTop(obj->parent_); + } + obj->destroyed_ = true; + if(obj->del_at_destroy_) + delete obj; + } } return ret; } +DWORD WINAPI dlg_base::start_thread(LPVOID lp) +{ + dlg_base::msg_thread_exited_ = false; + ((dlg_base*)lp)->thread_pump_message(); + dlg_base::msg_thread_exited_ = true; + + return 0; +} + +void dlg_base::thread_pump_message(void) +{ + msg_thread_id_ = GetCurrentThreadId(); + hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, (DLGPROC)&dlg_base::dlg_proc, (LPARAM)this); + if (IsWindow(hwnd_)) + { + MSG msg = { 0 }; + BOOL ret = TRUE; + HWND hwnd = hwnd_; + while ((ret = GetMessageW(&msg, NULL, 0, 0))) + { + + if (ret == -1 || msg.message == WM_QUIT_MSG_THREAD) + break; + + TranslateMessage(&msg); + DispatchMessageW(&msg); + //if (msg.message == WM_DESTROY) + //{ + // if (msg.hwnd == hwnd) + // break; + //} + } + DestroyWindow(hwnd); + //if (del_at_destroy_) + // delete this; + } +} void dlg_base::screen_2_client(HWND wnd, LPRECT r) { @@ -178,6 +258,10 @@ void dlg_base::center_window(HWND wnd, HWND parent) OffsetRect(&rme, x - rme.left, y - rme.top); MoveWindow(wnd, rme.left, rme.top, RECT_W(rme), RECT_H(rme), FALSE); } +bool dlg_base::is_message_thread_exited(void) +{ + return dlg_base::msg_thread_exited_; +} int dlg_base::list_insert_column(HWND list_wnd, const wchar_t* text, int cx, int ind) { LVCOLUMNW col = { 0 }; @@ -259,15 +343,63 @@ void dlg_base::on_font_changed(void) { } -void dlg_base::create(void) +void dlg_base::create(bool sole_thread) { // InitCommonControls(); - hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, (DLGPROC)&dlg_base::dlg_proc, (LPARAM)this); + if (sole_thread) + { + HANDLE h = CreateThread(NULL, 0, &dlg_base::start_thread, this, 0, &msg_thread_id_); + if (h) + { + CloseHandle(h); + while (!IsWindow(hwnd_)) + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } + else + hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, (DLGPROC)&dlg_base::dlg_proc, (LPARAM)this); +} +namespace notify +{ + typedef struct _notify_param + { + void(__stdcall* ui_event_notify)(int uev, void* sender, void* param); + void* param; + int ev; + void* sender; + }NOTIFYPARAM, *LPNOTIFYPARAM; + static DWORD WINAPI thread_notify(LPVOID lp) + { + LPNOTIFYPARAM param = (LPNOTIFYPARAM)lp; + + param->ui_event_notify(param->ev, param->sender, param->param); + delete param; + + return 0; + } + static void notify(void(__stdcall* f)(int, void*, void*), int ev, void* sender, void* param) + { + LPNOTIFYPARAM p = new NOTIFYPARAM; + HANDLE h = NULL; + + p->ui_event_notify = f; + p->sender = sender; + p->ev = ev; + p->param = param; + + h = CreateThread(NULL, 0, thread_notify, p, 0, NULL); + if (h) + CloseHandle(h); + else + delete p; + } } void dlg_base::notify_ui_event(int ev) { - if (ui_event_notify_) + if (ev == SANE_EVENT_UI_SCAN_COMMAND && ui_event_notify_) ui_event_notify_(ev, this, ui_notify_param_); + else + notify::notify(ui_event_notify_, ev, this, ui_notify_param_); } gb::sane_config_schm* dlg_base::get_config(bool* create) { @@ -289,6 +421,12 @@ HWND dlg_base::hwnd(void) } void dlg_base::show(bool visible, bool hold) { + while (!ready_) + { + MSG msg = { 0 }; + PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE); + } + UINT cmd = visible ? SW_SHOW : SW_HIDE; DWORD style = GetWindowLong(hwnd_, GWL_STYLE); @@ -329,6 +467,7 @@ void dlg_base::show(bool visible, bool hold) pt.y = r0.top; SetWindowPos(hwnd_, after, pt.x, pt.y, RECT_W(rme), RECT_H(rme), SWP_NOSIZE); UpdateWindow(hwnd_); + center_window(hwnd_, parent_); } EnableWindow(parent_, !visible); } @@ -353,7 +492,8 @@ void dlg_base::show(bool visible, bool hold) int dlg_base::do_modal(HWND parent) { BOOL enable_parent = FALSE, - got = TRUE; + got = TRUE, + wait_destory = FALSE; MSG msg = { 0 }; modal_exit_ = 0; @@ -378,13 +518,21 @@ int dlg_base::do_modal(HWND parent) TranslateMessage(&msg); DispatchMessage(&msg); if (modal_exit_) - break; - } - ShowWindow(hwnd(), SW_HIDE); + { + if (destroyed_) + break; + else if (!wait_destory) + { + wait_destory = true; + ShowWindow(hwnd(), SW_HIDE); - if (enable_parent) - { - EnableWindow(parent, TRUE); + if (enable_parent) + { + EnableWindow(parent, TRUE); + } + close(); + } + } } return modal_exit_; @@ -394,6 +542,13 @@ void dlg_base::quit_modal(int non_zero_code) // assert ( non_zero_code ); modal_exit_ = non_zero_code; } +void dlg_base::close(void) +{ + if(msg_thread_id_) // 独立的消息循环,则退出 + PostMessageW(hwnd_, WM_QUIT, 0, 0); + else // 共用父窗口消息循环,则关闭窗口。关闭窗口消息由自己处理,不提交到默认过程 + PostMessageW(hwnd_, WM_CLOSE, 0, 0); +} void dlg_base::enable(bool enable) { EnableWindow(hwnd_, enable); @@ -640,16 +795,16 @@ dlg_page::dlg_page(HWND parent, const wchar_t* name , id_custom_gamma_(-1), id_paper_(-1), paper_(L"A4"), id_dpi_(-1), dpi_(200), vsb_pos_(0), hsb_pos_(0) , vsb_(false), hsb_(false) { + del_at_destroy_ = true; + create(); + tips_wnd_.create(hwnd()); + size_.cx = size_.cy = 0; pos_.x = 12; pos_.y = 15; - create(); - tips_wnd_.create(hwnd()); } dlg_page::~dlg_page() { - for (auto& v : ctrls_) - DestroyWindow(v); } BOOL dlg_page::handle_message(UINT msg, WPARAM wp, LPARAM lp) @@ -679,6 +834,10 @@ BOOL dlg_page::handle_message(UINT msg, WPARAM wp, LPARAM lp) track_mouse_hover(); on_mouse_hover(LOWORD(lp), HIWORD(lp), wp); break; + case WM_DESTROY: + for (auto& v : ctrls_) + DestroyWindow(v); + break; default: ret = FALSE; } diff --git a/sane/DlgPage.h b/sane/DlgPage.h index 103bb80..9b76f82 100644 --- a/sane/DlgPage.h +++ b/sane/DlgPage.h @@ -21,6 +21,7 @@ #define RECT_W(r) (r.right - r.left) #define RECT_H(r) (r.bottom - r.top) +#define WM_QUIT_MSG_THREAD WM_USER + 300 #define WM_SCAN_WORKING WM_USER + 301 // WPARAM: unused; LPARAM: unsed #define WM_USB_PACKET_RECEIVED WM_USER + 302 #define WM_IMAGE_RECEIVED WM_USER + 303 @@ -35,15 +36,29 @@ namespace gb class sane_config_schm; } +#include +#include + class dlg_base { int modal_exit_; // set non-ZERO code to exit modal dialog + DWORD msg_thread_id_; + volatile bool destroyed_; + bool child_; + + static volatile bool msg_thread_exited_; + + static DWORD WINAPI start_thread(LPVOID lp); + void thread_pump_message(void); protected: HWND hwnd_; HWND parent_; UINT idd_; bool abandon_hold_; + bool del_at_destroy_; // 是否在窗口销毁时,自动释放对象 + volatile bool ready_ = false; + void(__stdcall* ui_event_notify_)(int uev, void* sender, void* param); void* ui_notify_param_; static std::wstring prop_name; @@ -51,7 +66,7 @@ protected: virtual BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp); virtual void on_font_changed(void); - void create(void); + void create(bool sole_thread = false); void notify_ui_event(int ev); gb::sane_config_schm* get_config(bool* create); @@ -68,6 +83,7 @@ public: static bool is_language_pack_default_code_page(void); static std::wstring get_menu_text(HMENU menu, int ind); static void center_window(HWND wnd, HWND parent); + static bool is_message_thread_exited(void); static int list_insert_column(HWND list_wnd, const wchar_t* text, int cx = 20, int ind = -1); static int list_insert_item(HWND list_wnd, const wchar_t* text, int ind = -1); @@ -81,8 +97,9 @@ public: void set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param); HWND hwnd(void); void show(bool visible, bool hold = false); - int do_modal(HWND parent); + int do_modal(HWND parent); // 该函数调用之后,自动销毁窗口。如果要反复使用,需要调整窗口创建时机,放到该函数入口处。(FIXED ME ...) void quit_modal(int non_zero_code); + void close(void); void enable(bool enable); void screen_2_client(LPRECT r); void client_2_screen(LPRECT r); diff --git a/sane/DlgSetting.cpp b/sane/DlgSetting.cpp index bd709fc..7e7cb33 100644 --- a/sane/DlgSetting.cpp +++ b/sane/DlgSetting.cpp @@ -19,39 +19,25 @@ static IMPLEMENT_OPTION_STRING_COMPARE(cmp_sane_opt); -dlg_setting::dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name) : dlg_base(parent, IDD_SETTING) +dlg_setting::dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name, bool sole_thread) : dlg_base(parent, IDD_SETTING) , sane_api_(*api), sane_dev_(dev), with_scan_(with_scan) , papers_(0), images_(0), err_(false), tab_(NULL), cfg_(NULL), cfg_file_(L""), twain_set_(nullptr), twain_schm_(nullptr) - , schm_from_empty_(false) + , schm_from_empty_(false), name_(name ? name : L"") { - std::wstring setting(local_trans::lang_trans_between_hz936(CONST_STRING_SETTING)); - - create(); - SetWindowTextW(hwnd(), (std::wstring(name) + L" " + setting).c_str()); + del_at_destroy_ = true; cfg_menu_ = CreatePopupMenu(); InsertMenuW(cfg_menu_, 0, MF_BYPOSITION, MENU_CMD_0, local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_CUR_CFG_AS).c_str()); InsertMenuA(cfg_menu_, 1, MF_BYPOSITION | MF_SEPARATOR, MENU_CMD_0 + 1, ""); + + std::wstring setting(local_trans::lang_trans_between_hz936(CONST_STRING_SETTING)); + + create(sole_thread); + SetWindowTextW(hwnd(), (name_ + L" " + setting).c_str()); } dlg_setting::~dlg_setting() { - if (IsWindow(tab_)) - { - for (int i = 0; i < get_tab_count(); ++i) - { - TCITEMW item = { 0 }; - - item.mask = TCIF_PARAM; - TabCtrl_GetItem(tab_, i, &item); - if (item.lParam) - delete (dlg_page*)item.lParam; - } - DestroyWindow(tab_); - } - if (twain_schm_) - twain_schm_->release(); - - cfg_->save(local_trans::u2a(cfg_file_.c_str()).c_str()); - DestroyMenu(cfg_menu_); + if (cfg_) + cfg_->release(); } BOOL dlg_setting::handle_message(UINT msg, WPARAM wp, LPARAM lp) @@ -100,6 +86,26 @@ BOOL dlg_setting::handle_message(UINT msg, WPARAM wp, LPARAM lp) } } break; + case WM_DESTROY: + if (IsWindow(tab_)) + { + for (int i = 0; i < get_tab_count(); ++i) + { + TCITEMW item = { 0 }; + + item.mask = TCIF_PARAM; + TabCtrl_GetItem(tab_, i, &item); + if (item.lParam) + DestroyWindow(((dlg_page*)item.lParam)->hwnd()); + } + DestroyWindow(tab_); + } + if (twain_schm_) + twain_schm_->release(); + + cfg_->save(local_trans::u2a(cfg_file_.c_str()).c_str()); + DestroyMenu(cfg_menu_); + break; default: ret = FALSE; break; @@ -195,6 +201,8 @@ void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl) { save_changes_to_cur_scheme(SAVE_REASON_QUIT_UI); notify_over(); + //PostMessageW(hwnd(), WM_CLOSE, 0, 0); + //PostQuitMessage(0); } else if (id == IDC_BUTTON_HELP) { @@ -624,11 +632,15 @@ void dlg_setting::save_changes_to_cur_scheme(int reason) void dlg_setting::set_config(gb::scanner_cfg* cfg, const wchar_t* file, void(__stdcall* apply)(gb::sane_config_schm*, void*), void* param, bool* twain_set) { + if (cfg_) + cfg_->release(); cfg_ = cfg; cfg_file_ = file; apply_scheme_ = apply; apply_param_ = param; twain_set_ = twain_set; + if(cfg_) + cfg_->add_ref(); if (twain_set && *twain_set && cfg_) { diff --git a/sane/DlgSetting.h b/sane/DlgSetting.h index 612e459..8e77729 100644 --- a/sane/DlgSetting.h +++ b/sane/DlgSetting.h @@ -34,6 +34,7 @@ class dlg_setting : public dlg_base bool *twain_set_; gb::sane_config_schm* twain_schm_; bool schm_from_empty_; + std::wstring name_; HMENU cfg_menu_; void(__stdcall* apply_scheme_)(gb::sane_config_schm*, void*); @@ -59,7 +60,7 @@ class dlg_setting : public dlg_base void save_changes_to_cur_scheme(int reason); public: - dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name); + dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name, bool sole_thread); ~dlg_setting(); public: diff --git a/sane/scanner.cpp b/sane/scanner.cpp index 2b68b65..5e4e797 100644 --- a/sane/scanner.cpp +++ b/sane/scanner.cpp @@ -558,6 +558,12 @@ scanner::~scanner() cfg_->remove_all_schemes(); // schemes would add_ref on cfg_, so we clear them first. NOTE: do not call save after this !!! cfg_->release(); cfg_ = NULL; + + while (!dlg_base::is_message_thread_exited()) + { + MSG msg = { 0 }; + PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE); + } } } @@ -788,28 +794,30 @@ void scanner::scan_done(void) while (images_.count()) std::this_thread::sleep_for(std::chrono::milliseconds(5)); - if (indicator_.get()) + if (indicator_) 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; + //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; } @@ -927,14 +935,16 @@ void scanner::on_ui_event(int uev, void* sender) { // setting UI closed ... is_scanning_ = is_show_setting_ = false; - if (setting_.get()) - setting_.reset(); + if (setting_) + setting_->close(); + setting_ = NULL; } else if (uev == SANE_EVENT_UI_CLOSE_NORMAL) { // scan complete - if (indicator_.get()) - indicator_.reset(); + if (indicator_) + indicator_->close(); + indicator_ = NULL; // FIX on 2023-05-30: restore scan finished status, whether close UI is up to APP //is_scanning_ = is_show_setting_; @@ -944,8 +954,9 @@ void scanner::on_ui_event(int uev, void* sender) else if (uev == SANE_EVENT_UI_CLOSE_CANCEL) { // scan cancelled - if (indicator_.get()) - indicator_.reset(); + //if (indicator_) + // indicator_->close(); + //indicator_ = NULL; stop(); // nothing to do, the finishing work do in SANE_EVENT_SCAN_FINISHED } @@ -2719,7 +2730,7 @@ COM_API_IMPLEMENT(scanner, int, start(void)) user_cancel_ = false; fetch_imgs_ = 0; is_scanning_ = true; - app_wnd_ = setting_.get() ? setting_->hwnd() : callback::find_main_wnd(); + app_wnd_ = setting_ ? setting_->hwnd() : callback::find_main_wnd(); if (thread_starting_.get() && thread_starting_->joinable()) thread_starting_->join(); @@ -2866,7 +2877,7 @@ COM_API_IMPLEMENT(scanner, int, image_fetched(IScanImg* tx)) fetch_imgs_++; if (ui_notify) ui_notify(SANE_EVENT_IMG_UPLOADED, NULL, fetch_imgs_); - else if (indicator_.get()) + else if (indicator_) indicator_->notify_data_arrived(false); { @@ -3478,15 +3489,16 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan, bo size_t pid = scanner_name_.find(L" - "); if (pid == -1) pid = scanner_name_.length(); - setting_.reset(new dlg_setting(parent, &sane_api_, handle_, with_scan, scanner_name_.substr(0, pid).c_str())); + if (setting_) + setting_->close(); + setting_ = new dlg_setting(parent, &sane_api_, handle_, with_scan, scanner_name_.substr(0, pid).c_str(), true); setting_->set_ui_event_notify(&scanner::ui_callback, this); setting_->set_config(cfg_, (cfg_path_ + scanner_name_.substr(0, pid) + L".cfg").c_str(), &scanner::apply_scheme, this, &twain_set_); - indicator_.reset(); - if (indicator) - { - indicator_.reset(new dlg_indicator(setting_->hwnd())); - indicator_->set_ui_event_notify(&scanner::ui_callback, this); - } + //if (indicator) + //{ + // indicator_.reset(new dlg_indicator(setting_->hwnd(), false)); + // indicator_->set_ui_event_notify(&scanner::ui_callback, this); + //} setting_->show(true); } @@ -3528,12 +3540,18 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent, bool bIndicator)) } else if(bIndicator) { - if (setting_.get() && IsWindowVisible(setting_->hwnd())) + bool sole_thread = true; + if (setting_ && IsWindowVisible(setting_->hwnd())) + { parent = setting_->hwnd(); + sole_thread = false; + } else if (!IsWindow(parent)) parent = callback::find_main_wnd(); - indicator_.reset(new dlg_indicator(parent)); + if (indicator_) + indicator_->close(); + indicator_ = new dlg_indicator(parent, sole_thread); indicator_->set_ui_event_notify(&scanner::ui_callback, this); indicator_->show(true); } @@ -3542,10 +3560,13 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent, bool bIndicator)) } COM_API_IMPLEMENT(scanner, void, ui_hide(void)) { - if (indicator_.get()) - indicator_.reset(); - if (setting_.get()) - setting_.reset(); + if (indicator_) + indicator_->close(); + indicator_ = NULL; + + if (setting_) + setting_->close(); + setting_ = NULL; if (callback::close_ui) callback::close_ui(UI_INDICATOR | UI_SETTING | UI_MSG_BOX); @@ -3562,11 +3583,12 @@ COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void)) // called from device-layer ... int scanner::handle_device_event(int ev_code, void* data, unsigned int* len) { + dlg_indicator* prog = indicator_; if (ev_code == SANE_EVENT_WORKING) { img_ind_ = 0; - if (indicator_.get()) - indicator_->notify_working(); + if (prog) + prog->notify_working(); else if (callback::show_progress_ui && is_bIndicator) ui_notify(ev_code, data, *len); on_ui_event(ev_code, (void*)ev_code); @@ -3627,8 +3649,8 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len) { img->release(); } - if (indicator_.get()) - indicator_->notify_data_arrived(true); + if (prog) + prog->notify_data_arrived(true); else if (ui_notify) ui_notify(ev_code, data, img_ind_); @@ -3640,8 +3662,8 @@ 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 (prog) + // prog->notify_data_arrived(false); //else if (ui_notify) // ui_notify(ev_code, data, 0); } diff --git a/sane/scanner.h b/sane/scanner.h index 1cf6b5f..62f6981 100644 --- a/sane/scanner.h +++ b/sane/scanner.h @@ -74,8 +74,8 @@ class scanner : public ISaneInvoker, virtual public refer safe_queue events_; //如果有界面,则全部保存从界面传回的消息;否则只保存开始扫描和结束扫描的事件 int ev_cnt_; SANE_FinalImgFormat img_fmt_; - std::unique_ptr indicator_; - std::unique_ptr setting_; + dlg_indicator* indicator_ = NULL; + dlg_setting* setting_ = NULL; gb::scanner_cfg* cfg_; bool twain_set_; SANEAPI sane_api_;