调整UI与APP交互方式,设备层回调不直接调用UI;屏蔽Twpp框架中自动调用“notifyXferReady()”,统一为在事件队列eventProcess中通知;所有弹出窗口自动禁用其父窗口,退出时再启用父窗口并在前方显示
This commit is contained in:
parent
fdd12a953c
commit
6cbe8f125c
|
@ -64,7 +64,7 @@ BOOL dlg_indicator::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
|||
ret = FALSE;
|
||||
break;
|
||||
case WM_SCAN_WORKING:
|
||||
notify_ui_event(UI_EVENT_SCAN_WORKING);
|
||||
notify_ui_event(SANE_EVENT_WORKING);
|
||||
break;
|
||||
case WM_SCAN_FINISHED:
|
||||
if (lp)
|
||||
|
@ -117,7 +117,7 @@ void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl)
|
|||
}
|
||||
void dlg_indicator::notify_over(bool cancel)
|
||||
{
|
||||
notify_ui_event(cancel ? UI_EVENT_CLOSE_CANCEL : UI_EVENT_CLOSE_NORMAL);
|
||||
notify_ui_event(cancel ? SANE_EVENT_UI_CLOSE_CANCEL : SANE_EVENT_SCAN_FINISHED);
|
||||
}
|
||||
|
||||
HWND dlg_indicator::window(void)
|
||||
|
@ -128,25 +128,6 @@ HWND dlg_indicator::parent(void)
|
|||
{
|
||||
return parent_;
|
||||
}
|
||||
void dlg_indicator::show()
|
||||
{
|
||||
RECT rp, r;
|
||||
|
||||
if (IsWindow(parent_))
|
||||
GetWindowRect(parent_, &rp);
|
||||
else
|
||||
GetWindowRect(GetDesktopWindow(), &rp);
|
||||
GetWindowRect(hwnd_, &r);
|
||||
|
||||
rp.left += (rp.right - rp.left - (r.right - r.left)) / 2;
|
||||
rp.top += (rp.bottom - rp.top - (r.bottom - r.top)) / 2;
|
||||
SetWindowPos(hwnd_, HWND_TOPMOST, rp.left, rp.top, r.right - r.left, r.bottom - r.top, SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
UpdateWindow(hwnd_);
|
||||
}
|
||||
void dlg_indicator::hide(void)
|
||||
{
|
||||
ShowWindow(hwnd_, SW_HIDE);
|
||||
}
|
||||
void dlg_indicator::notify_data_arrived(bool image)
|
||||
{
|
||||
PostMessage(hwnd_, image ? WM_IMAGE_RECEIVED : WM_USB_PACKET_RECEIVED, 0, 0);
|
||||
|
|
|
@ -24,8 +24,6 @@ public:
|
|||
public:
|
||||
HWND window(void);
|
||||
HWND parent(void);
|
||||
void show(void);
|
||||
void hide(void);
|
||||
void notify_data_arrived(bool image);
|
||||
void notify_scan_over(const char* msg, bool err);
|
||||
void notify_working(void);
|
||||
|
|
|
@ -31,8 +31,13 @@ dlg_base::dlg_base(HWND parent, UINT idd) : parent_(parent), hwnd_(NULL), idd_(i
|
|||
}
|
||||
dlg_base::~dlg_base()
|
||||
{
|
||||
if(IsWindow(hwnd_))
|
||||
DestroyWindow(hwnd_);
|
||||
if (IsWindow(hwnd_))
|
||||
{
|
||||
//if (GetCurrentThreadId() == GetWindowThreadProcessId(hwnd_, NULL))
|
||||
DestroyWindow(hwnd_);
|
||||
}
|
||||
EnableWindow(parent_, TRUE);
|
||||
BringWindowToTop(parent_);
|
||||
}
|
||||
|
||||
BOOL CALLBACK dlg_base::dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
|
@ -44,12 +49,21 @@ BOOL CALLBACK dlg_base::dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||
SetPropW(hwnd, dlg_base::prop_name.c_str(), (HANDLE)obj);
|
||||
obj->hwnd_ = hwnd;
|
||||
}
|
||||
else if (msg == WM_DESTROY)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -101,7 +115,7 @@ void dlg_base::create(void)
|
|||
{
|
||||
hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, &dlg_base::dlg_proc, (LPARAM)this);
|
||||
}
|
||||
void dlg_base::notify_ui_event(ui_event ev)
|
||||
void dlg_base::notify_ui_event(int ev)
|
||||
{
|
||||
if (ui_event_notify_)
|
||||
ui_event_notify_(ev, this, ui_notify_param_);
|
||||
|
@ -115,7 +129,7 @@ gb::sane_config* dlg_base::get_config(void)
|
|||
return cfg;
|
||||
}
|
||||
|
||||
void dlg_base::set_ui_event_notify(void(__stdcall* notify)(ui_event, void*, void*), void* param)
|
||||
void dlg_base::set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param)
|
||||
{
|
||||
ui_event_notify_ = notify;
|
||||
ui_notify_param_ = param;
|
||||
|
@ -163,11 +177,12 @@ void dlg_base::show(bool visible)
|
|||
pt.y = r0.bottom - RECT_H(rme);
|
||||
if (pt.y < r0.top)
|
||||
pt.y = r0.top;
|
||||
SetWindowPos(hwnd_, HWND_TOPMOST, pt.x, pt.y, RECT_W(rme), RECT_H(rme), SWP_NOSIZE);
|
||||
SetWindowPos(hwnd_, HWND_TOP, pt.x, pt.y, RECT_W(rme), RECT_H(rme), SWP_NOSIZE);
|
||||
UpdateWindow(hwnd_);
|
||||
}
|
||||
}
|
||||
ShowWindow(hwnd_, cmd);
|
||||
EnableWindow(parent_, !visible);
|
||||
}
|
||||
void dlg_base::enable(bool enable)
|
||||
{
|
||||
|
|
|
@ -13,13 +13,6 @@
|
|||
#define WM_REFRESH_OPTION WM_USER + 111 // WPARAM: source option SN, LPARAM: unused now
|
||||
#define WM_GET_CONFIG_OBJ WM_USER + 112 // WPARAM: not use, LPARAM: to receive the gb::sane_config* object
|
||||
|
||||
enum ui_event
|
||||
{
|
||||
UI_EVENT_CLOSE_NORMAL = 0,
|
||||
UI_EVENT_CLOSE_CANCEL,
|
||||
UI_EVENT_BEGIN_SCANNING, // setting ui notify button 'scan' clicked
|
||||
UI_EVENT_SCAN_WORKING, // scanner thread notify working
|
||||
};
|
||||
|
||||
extern HMODULE g_my_inst;
|
||||
namespace gb
|
||||
|
@ -33,7 +26,7 @@ protected:
|
|||
HWND hwnd_;
|
||||
HWND parent_;
|
||||
UINT idd_;
|
||||
void(__stdcall* ui_event_notify_)(ui_event uev, void* sender, void* param);
|
||||
void(__stdcall* ui_event_notify_)(int uev, void* sender, void* param);
|
||||
void* ui_notify_param_;
|
||||
static std::wstring prop_name;
|
||||
static BOOL CALLBACK dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
|
||||
|
@ -41,7 +34,7 @@ protected:
|
|||
virtual BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp);
|
||||
virtual void on_font_changed(void);
|
||||
void create(void);
|
||||
void notify_ui_event(ui_event ev);
|
||||
void notify_ui_event(int ev);
|
||||
gb::sane_config* get_config(void);
|
||||
|
||||
public:
|
||||
|
@ -52,7 +45,7 @@ public:
|
|||
static bool get_max_size(SIZE& dst, int cx, int cy); // return whether changed dst
|
||||
|
||||
public:
|
||||
void set_ui_event_notify(void(__stdcall* notify)(ui_event, void*, void*), void* param);
|
||||
void set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param);
|
||||
HWND hwnd(void);
|
||||
void show(bool visible);
|
||||
void enable(bool enable);
|
||||
|
|
|
@ -95,13 +95,13 @@ void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl)
|
|||
}
|
||||
else if (id == IDC_BUTTON_SCAN)
|
||||
{
|
||||
enable(false);
|
||||
notify_ui_event(UI_EVENT_BEGIN_SCANNING);
|
||||
// enable(false);
|
||||
notify_ui_event(SANE_EVENT_UI_SCAN_COMMAND);
|
||||
}
|
||||
}
|
||||
void dlg_setting::notify_over(void)
|
||||
{
|
||||
notify_ui_event(UI_EVENT_CLOSE_NORMAL);
|
||||
notify_ui_event(SANE_EVENT_UI_CLOSE_NORMAL);
|
||||
}
|
||||
void dlg_setting::on_init_dialog(void)
|
||||
{
|
||||
|
@ -380,19 +380,8 @@ void dlg_setting::hide(void)
|
|||
{
|
||||
ShowWindow(hwnd_, SW_HIDE);
|
||||
}
|
||||
void dlg_setting::notify_data_arrived(bool image)
|
||||
void dlg_setting::notify_scan_over(void)
|
||||
{
|
||||
PostMessage(hwnd_, image ? WM_IMAGE_RECEIVED : WM_USB_PACKET_RECEIVED, 0, 0);
|
||||
}
|
||||
void dlg_setting::notify_scan_over(const char* msg, bool err)
|
||||
{
|
||||
std::string* mstr(new std::string(msg ? msg : ""));
|
||||
|
||||
err_ = err;
|
||||
if (!PostMessage(hwnd_, WM_SCAN_FINISHED, (WPARAM)mstr, (LPARAM)err))
|
||||
{
|
||||
delete mstr;
|
||||
notify_over();
|
||||
}
|
||||
enable(true);
|
||||
}
|
||||
// CDlgIndicator 消息处理程序
|
||||
|
|
|
@ -60,6 +60,5 @@ public:
|
|||
HWND parent(void);
|
||||
//void show(void);
|
||||
void hide(void);
|
||||
void notify_data_arrived(bool image);
|
||||
void notify_scan_over(const char* msg, bool err);
|
||||
void notify_scan_over(void);
|
||||
};
|
||||
|
|
|
@ -148,7 +148,7 @@ __declspec(novtable) struct ISaneInvoker : public IRef
|
|||
{
|
||||
COM_API_DECLARE(int, start(void));
|
||||
COM_API_DECLARE(int, stop(void));
|
||||
COM_API_DECLARE(void, set_event_callback(void(*cb)(int ev_type, void* data, unsigned int* len, void* param), void* param));
|
||||
COM_API_DECLARE(int, get_event(void));
|
||||
COM_API_DECLARE(bool, wait_image(DWORD milliseconds = -1));
|
||||
COM_API_DECLARE(int, get_scanned_images(DWORD milliseconds = 0));
|
||||
COM_API_DECLARE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz
|
||||
|
@ -258,7 +258,7 @@ __declspec(novtable) struct ISaneInvoker : public IRef
|
|||
|
||||
// ui ...
|
||||
COM_API_DECLARE(bool, ui_show_main(HWND parent));
|
||||
COM_API_DECLARE(bool, ui_show_setting(HWND parent, bool with_scan));
|
||||
COM_API_DECLARE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true));
|
||||
COM_API_DECLARE(bool, ui_show_progress(HWND parent));
|
||||
COM_API_DECLARE(void, ui_hide(void));
|
||||
COM_API_DECLARE(bool, ui_is_ok(void));
|
||||
|
|
|
@ -719,57 +719,36 @@ safe_img_queue::~safe_img_queue()
|
|||
clear();
|
||||
}
|
||||
|
||||
size_t safe_img_queue::count(void)
|
||||
void __stdcall safe_img_queue::access_image(scanned_img* img)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
|
||||
return queue_.size();
|
||||
img->add_ref();
|
||||
}
|
||||
bool safe_img_queue::save(scanned_img* img)
|
||||
void __stdcall safe_img_queue::free_image(scanned_img* img)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
|
||||
queue_.push_back(img);
|
||||
|
||||
return true;
|
||||
img->release();
|
||||
}
|
||||
|
||||
bool safe_img_queue::get_header(SANE_Parameters* header, size_t* bytes)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
bool ok = false;
|
||||
scanned_img *img = take(false, &safe_img_queue::access_image);
|
||||
bool ok = false;
|
||||
|
||||
if (bytes)
|
||||
*bytes = 0;
|
||||
if (queue_.size())
|
||||
if (img)
|
||||
{
|
||||
if(header)
|
||||
queue_[0]->copy_header(header);
|
||||
img->copy_header(header);
|
||||
if(bytes)
|
||||
*bytes = queue_[0]->bytes();
|
||||
*bytes = img->bytes();
|
||||
ok = true;
|
||||
img->release();
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
scanned_img* safe_img_queue::take(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
scanned_img* img = NULL;
|
||||
|
||||
if (queue_.size())
|
||||
{
|
||||
img = queue_[0];
|
||||
queue_.erase(queue_.begin());
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
void safe_img_queue::clear()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
|
||||
for (size_t i = 0; i < queue_.size(); ++i)
|
||||
queue_[i]->release();
|
||||
queue_.clear();
|
||||
safe_queue<scanned_img*>::clear(&safe_img_queue::free_image);
|
||||
}
|
||||
|
||||
|
|
|
@ -98,20 +98,73 @@ public:
|
|||
COM_API_OVERRIDE(void, copy_header(SANE_Parameters* head));
|
||||
};
|
||||
|
||||
class safe_img_queue
|
||||
template<class T>
|
||||
class safe_queue
|
||||
{
|
||||
std::mutex que_lock_;
|
||||
std::vector<scanned_img*> queue_;
|
||||
std::mutex lock_;
|
||||
std::vector<T> queue_;
|
||||
|
||||
public:
|
||||
safe_queue()
|
||||
{}
|
||||
virtual ~safe_queue()
|
||||
{}
|
||||
|
||||
public:
|
||||
size_t count(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
|
||||
return queue_.size();
|
||||
}
|
||||
bool save(T v)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
|
||||
queue_.push_back(v);
|
||||
|
||||
return true;
|
||||
}
|
||||
T take(bool remove = true, void(__stdcall* first)(T) = NULL)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
T t = 0;
|
||||
|
||||
if (queue_.size())
|
||||
{
|
||||
t = queue_[0];
|
||||
if(remove)
|
||||
queue_.erase(queue_.begin());
|
||||
if (first)
|
||||
first(t);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
void clear(void(__stdcall* tfree)(T) = NULL)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
|
||||
if (tfree)
|
||||
{
|
||||
for (auto& v : queue_)
|
||||
tfree(v);
|
||||
}
|
||||
queue_.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class safe_img_queue : public safe_queue<scanned_img*>
|
||||
{
|
||||
static void __stdcall access_image(scanned_img* img);
|
||||
static void __stdcall free_image(scanned_img* img);
|
||||
|
||||
public:
|
||||
safe_img_queue();
|
||||
~safe_img_queue();
|
||||
|
||||
public:
|
||||
size_t count(void);
|
||||
bool save(scanned_img* img);
|
||||
bool get_header(SANE_Parameters* header, size_t* bytes = NULL);
|
||||
scanned_img* take(void);
|
||||
void clear();
|
||||
};
|
||||
|
||||
|
|
131
sane/scanner.cpp
131
sane/scanner.cpp
|
@ -78,7 +78,7 @@ namespace callback
|
|||
std::vector<SCNINST>::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), hdev);
|
||||
|
||||
if (it != g_scanner_instances.end())
|
||||
return it->invoker->handle_event(code, data, len);
|
||||
return it->invoker->handle_device_event(code, data, len);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -109,8 +109,8 @@ namespace callback
|
|||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class scanner
|
||||
scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BASE), prev_start_result_(SCANNER_ERR_NOT_START)
|
||||
, dpi_(200), tmp_path_(L""), img_ind_(0), cb_invoker_(NULL), cb_param_(NULL), working_(false)
|
||||
, ui_quit_(true), scanner_name_(L""), cfg_(NULL)
|
||||
, dpi_(200), tmp_path_(L""), img_ind_(0)
|
||||
, scanner_name_(L""), cfg_(NULL)
|
||||
{
|
||||
cfg_ = new gb::sane_config();
|
||||
tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str());
|
||||
|
@ -190,9 +190,9 @@ float __stdcall scanner::to_float(SANE_Fixed v)
|
|||
{
|
||||
return SANE_UNFIX(v);
|
||||
}
|
||||
void __stdcall scanner::ui_callback(ui_event uev, void* sender, void* param)
|
||||
void __stdcall scanner::ui_callback(int uev, void* sender, void* param)
|
||||
{
|
||||
((scanner*)param)->on_ui_quit(uev, sender);
|
||||
((scanner*)param)->on_ui_event(uev, sender);
|
||||
}
|
||||
|
||||
// IRef
|
||||
|
@ -244,46 +244,9 @@ void scanner::apply_config(void)
|
|||
} while (cfg_->next_config(t, v));
|
||||
}
|
||||
}
|
||||
void scanner::on_ui_quit(ui_event uev, void* sender)
|
||||
void scanner::on_ui_event(int uev, void* sender)
|
||||
{
|
||||
switch (uev)
|
||||
{
|
||||
case UI_EVENT_CLOSE_CANCEL: // post from indicator
|
||||
stop();
|
||||
case UI_EVENT_CLOSE_NORMAL: // post from indicator & dlg_setting
|
||||
if (/*sender == indicator_.get() &&*/ setting_.get())
|
||||
{
|
||||
setting_->hide();
|
||||
setting_.reset();
|
||||
}
|
||||
/*else*/ if (/*sender == setting_.get() &&*/ indicator_.get())
|
||||
{
|
||||
indicator_->hide();
|
||||
indicator_.reset();
|
||||
}
|
||||
ui_quit_ = true;
|
||||
break;
|
||||
case UI_EVENT_BEGIN_SCANNING: // post from dlg_setting, so we show indicator ...
|
||||
if (start() == SANE_STATUS_GOOD)
|
||||
{
|
||||
if (indicator_.get())
|
||||
{
|
||||
indicator_->show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setting_->enable(true);
|
||||
return;
|
||||
}
|
||||
case UI_EVENT_SCAN_WORKING:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (cb_invoker_)
|
||||
cb_invoker_(ui_quit_ ? SANE_EVENT_SCAN_FINISHED : SANE_EVENT_WORKING, NULL, NULL, cb_param_);
|
||||
events_.save(uev);
|
||||
}
|
||||
int scanner::open(void)
|
||||
{
|
||||
|
@ -1583,7 +1546,10 @@ COM_API_IMPLEMENT(scanner, int, start(void))
|
|||
|
||||
scan_msg_ = "OK";
|
||||
scan_err_ = false;
|
||||
hg_sane_middleware::instance()->start(handle_, NULL);
|
||||
ret = hg_sane_middleware::instance()->start(handle_, NULL);
|
||||
|
||||
if (indicator_.get() && !IsWindowVisible(indicator_->hwnd()))
|
||||
indicator_->show(true);
|
||||
|
||||
// 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)
|
||||
|
@ -1596,7 +1562,6 @@ COM_API_IMPLEMENT(scanner, int, start(void))
|
|||
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;
|
||||
working_ = true;
|
||||
}
|
||||
prev_start_result_ = ret;
|
||||
|
||||
|
@ -1604,13 +1569,11 @@ COM_API_IMPLEMENT(scanner, int, start(void))
|
|||
}
|
||||
COM_API_IMPLEMENT(scanner, int, stop(void))
|
||||
{
|
||||
working_ = false;
|
||||
return hg_sane_middleware::instance()->stop(handle_);
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, void, set_event_callback(void(*cb)(int ev_type, void* data, unsigned int* len, void* param), void* param))
|
||||
COM_API_IMPLEMENT(scanner, int, get_event(void))
|
||||
{
|
||||
cb_invoker_ = cb;
|
||||
cb_param_ = param;
|
||||
return events_.take();
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, bool, wait_image(DWORD milliseconds))
|
||||
{
|
||||
|
@ -1621,7 +1584,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();
|
||||
bool notify = true;
|
||||
DWORD elapse = 10;
|
||||
|
||||
while (count == 0 && milliseconds)
|
||||
{
|
||||
|
@ -1631,24 +1594,33 @@ COM_API_IMPLEMENT(scanner, int, get_scanned_images(DWORD milliseconds))
|
|||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
Sleep(10);
|
||||
if (!working_)
|
||||
{
|
||||
if (notify && indicator_.get())
|
||||
{
|
||||
notify = false;
|
||||
indicator_->notify_scan_over(scan_msg_.c_str(), scan_err_); // Ending by UI
|
||||
}
|
||||
else if(ui_quit_)
|
||||
break;
|
||||
}
|
||||
Sleep(elapse);
|
||||
|
||||
int ev = get_event();
|
||||
|
||||
count = images_.count();
|
||||
if (ev == SANE_EVENT_SCAN_FINISHED)
|
||||
{
|
||||
ui_hide();
|
||||
break;
|
||||
}
|
||||
else if (ev == SANE_EVENT_UI_CLOSE_CANCEL)
|
||||
{
|
||||
stop();
|
||||
ui_hide();
|
||||
break;
|
||||
}
|
||||
else if (ev == SANE_EVENT_UI_CLOSE_NORMAL)
|
||||
{
|
||||
ui_hide();
|
||||
break;
|
||||
}
|
||||
if (milliseconds != -1)
|
||||
{
|
||||
if (milliseconds <= 10)
|
||||
if (milliseconds <= elapse)
|
||||
break;
|
||||
|
||||
milliseconds -= 10;
|
||||
milliseconds -= elapse;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1992,7 +1964,7 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_main(HWND parent))
|
|||
{
|
||||
return false;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan))
|
||||
COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan, bool indicator))
|
||||
{
|
||||
SANEAPI api = { NULL };
|
||||
|
||||
|
@ -2014,15 +1986,13 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan))
|
|||
setting_->set_ui_event_notify(&scanner::ui_callback, this);
|
||||
setting_->set_config(cfg_, (cfg_path_ + scanner_name_).c_str());
|
||||
cfg_->begin_setting();
|
||||
if (with_scan)
|
||||
indicator_.reset();
|
||||
if (indicator)
|
||||
{
|
||||
indicator_.reset(new dlg_indicator(parent));
|
||||
indicator_.reset(new dlg_indicator(setting_->hwnd()));
|
||||
indicator_->set_ui_event_notify(&scanner::ui_callback, this);
|
||||
}
|
||||
else
|
||||
indicator_.reset();
|
||||
setting_->show(true);
|
||||
ui_quit_ = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2030,8 +2000,7 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
|
|||
{
|
||||
indicator_.reset(new dlg_indicator(parent));
|
||||
indicator_->set_ui_event_notify(&scanner::ui_callback, this);
|
||||
indicator_->show();
|
||||
ui_quit_ = false;
|
||||
indicator_->show(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2050,12 +2019,14 @@ COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void))
|
|||
|
||||
|
||||
// called from device-layer ...
|
||||
int scanner::handle_event(int ev_code, void* data, unsigned int* len)
|
||||
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
|
||||
events_.save(ev_code);
|
||||
}
|
||||
else if (ev_code == SANE_EVENT_IMAGE_OK)
|
||||
{
|
||||
|
@ -2068,29 +2039,25 @@ int scanner::handle_event(int ev_code, void* data, unsigned int* len)
|
|||
if (img->bytes() /*>= simg->bytes*/)
|
||||
{
|
||||
images_.save(img);
|
||||
if (cb_invoker_) // added for notify twain-app XferReady ...
|
||||
cb_invoker_(ev_code, NULL, NULL, cb_param_);
|
||||
}
|
||||
else
|
||||
{
|
||||
img->release();
|
||||
}
|
||||
if (indicator_)
|
||||
if (indicator_.get())
|
||||
indicator_->notify_data_arrived(true);
|
||||
}
|
||||
else if (ev_code == SANE_EVENT_USB_DATA_RECEIVED)
|
||||
{
|
||||
if (indicator_)
|
||||
if (indicator_.get())
|
||||
indicator_->notify_data_arrived(false);
|
||||
}
|
||||
else if (ev_code == SANE_EVENT_SCAN_FINISHED)
|
||||
{
|
||||
if (indicator_.get())
|
||||
{
|
||||
scan_msg_ = (char*)data;
|
||||
scan_err_ = *len != SCANNER_ERR_OK;
|
||||
}
|
||||
working_ = false;
|
||||
indicator_->notify_scan_over((char*)data, *len != SCANNER_ERR_OK);
|
||||
else
|
||||
events_.save(ev_code);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -34,8 +34,6 @@ class scanner : public ISaneInvoker, virtual public refer
|
|||
SANE_Handle handle_;
|
||||
SCANNERID id_;
|
||||
int err_;
|
||||
void(*cb_invoker_)(int ev_type, void* data, unsigned int* len, void* param);
|
||||
void* cb_param_;
|
||||
int ex_id_;
|
||||
int prev_start_result_;
|
||||
int dpi_;
|
||||
|
@ -47,8 +45,7 @@ class scanner : public ISaneInvoker, virtual public refer
|
|||
bool scan_err_;
|
||||
twain_xfer xfer_;
|
||||
safe_img_queue images_;
|
||||
volatile bool working_;
|
||||
bool ui_quit_;
|
||||
safe_queue<int> events_; //如果有界面,则全部保存从界面传回的消息;否则只保存开始扫描和结束扫描的事件
|
||||
SANE_FinalImgFormat img_fmt_;
|
||||
std::unique_ptr<dlg_indicator> indicator_;
|
||||
std::unique_ptr<dlg_setting> setting_;
|
||||
|
@ -57,7 +54,7 @@ class scanner : public ISaneInvoker, virtual public refer
|
|||
void load_config(const wchar_t* file);
|
||||
void save_config(const wchar_t* file);
|
||||
void apply_config(void);
|
||||
void on_ui_quit(ui_event uev, void* sender);
|
||||
void on_ui_event(int uev, void* sender);
|
||||
int open(void);
|
||||
int close(void);
|
||||
int init_options_id(void);
|
||||
|
@ -175,7 +172,7 @@ class scanner : public ISaneInvoker, virtual public refer
|
|||
|
||||
static int __stdcall to_int(SANE_Int v);
|
||||
static float __stdcall to_float(SANE_Fixed v);
|
||||
static void __stdcall ui_callback(ui_event uev, void* sender, void* param);
|
||||
static void __stdcall ui_callback(int uev, void* sender, void* param);
|
||||
|
||||
public:
|
||||
scanner(SCANNERID id);
|
||||
|
@ -196,7 +193,7 @@ public:
|
|||
public:
|
||||
COM_API_OVERRIDE(int, start(void));
|
||||
COM_API_OVERRIDE(int, stop(void));
|
||||
COM_API_OVERRIDE(void, set_event_callback(void(*cb)(int ev_type, void* data, unsigned int* len, void* param), void* param));
|
||||
COM_API_OVERRIDE(int, get_event(void));
|
||||
COM_API_OVERRIDE(bool, wait_image(DWORD milliseconds = -1));
|
||||
COM_API_OVERRIDE(int, get_scanned_images(DWORD milliseconds = 0));
|
||||
COM_API_OVERRIDE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz
|
||||
|
@ -294,7 +291,7 @@ public:
|
|||
|
||||
// ui ...
|
||||
COM_API_OVERRIDE(bool, ui_show_main(HWND parent));
|
||||
COM_API_OVERRIDE(bool, ui_show_setting(HWND parent, bool with_scan));
|
||||
COM_API_OVERRIDE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true));
|
||||
COM_API_OVERRIDE(bool, ui_show_progress(HWND parent));
|
||||
COM_API_OVERRIDE(void, ui_hide(void));
|
||||
COM_API_OVERRIDE(bool, ui_is_ok(void));
|
||||
|
@ -307,5 +304,5 @@ public:
|
|||
|
||||
// methods:
|
||||
public:
|
||||
int handle_event(int ev_code, void* data, unsigned int* len);
|
||||
int handle_device_event(int ev_code, void* data, unsigned int* len);
|
||||
};
|
|
@ -126,6 +126,11 @@ enum CapTypeEx : unsigned short {
|
|||
// END for SANE设备层原始设置项透传属性
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
enum // .twain/first.cfg: [twain-app] flow=0
|
||||
{
|
||||
TWAIN_APP_TRANSFER_NORMAL = 0, // first get head and then bits
|
||||
TWAIN_APP_TRANSFER_REVERSE, // first get bits and then head
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -618,10 +623,6 @@ void huagao_ds::showmsg(const char* msg, int err)
|
|||
{
|
||||
ShellExecuteA(NULL, "open", huagao_ds::get_hidedlg_path().c_str(), msg, NULL, SW_HIDE);
|
||||
}
|
||||
void huagao_ds::scan_event(int sane_event, void* data, unsigned int* len, void* param)
|
||||
{
|
||||
((huagao_ds*)param)->on_scan_event(sane_event, data, len);
|
||||
}
|
||||
|
||||
const Identity& huagao_ds::defaultIdentity() noexcept {
|
||||
// remember, we return a reference, therefore the identity must not be placed on the stack of this method
|
||||
|
@ -709,6 +710,25 @@ Result huagao_ds::eventProcess(const Identity&, Event& event)
|
|||
{
|
||||
const MSG* msg = (const MSG*)event.event();
|
||||
// event.setMessage(Msg::Null);
|
||||
if (scanner_.get())
|
||||
{
|
||||
switch (scanner_->get_event())
|
||||
{
|
||||
case SANE_EVENT_WORKING:
|
||||
notifyXferReady();
|
||||
break;
|
||||
case SANE_EVENT_UI_CLOSE_CANCEL:
|
||||
scanner_->stop();
|
||||
notifyEndWithoutImages();
|
||||
case SANE_EVENT_UI_CLOSE_NORMAL:
|
||||
scanner_->ui_hide();
|
||||
notifyCloseOk();
|
||||
break;
|
||||
case SANE_EVENT_UI_SCAN_COMMAND:
|
||||
scanner_->start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { ReturnCode::NotDsEvent, ConditionCode::Success };
|
||||
}
|
||||
|
@ -763,7 +783,13 @@ Result huagao_ds::identityOpenDs(const Identity& id)
|
|||
return { ReturnCode::Failure, huagao_ds::condition_code_from_hg_error(err) };
|
||||
}
|
||||
// ui_.reset(new twain_ui(local_utility::reg_get_app_installing_path().c_str()));
|
||||
scanner_->set_event_callback(&huagao_ds::scan_event, this);
|
||||
if (get_config_number(L"twain-app", L"flow") == TWAIN_APP_TRANSFER_REVERSE)
|
||||
{
|
||||
cur_head_ = new SANE_Parameters;
|
||||
memset(cur_head_, 0, sizeof(SANE_Parameters));
|
||||
}
|
||||
|
||||
m_compression = Compression::None;
|
||||
init_support_caps();
|
||||
m_fileXfer.setFormat(ImageFileFormat::Bmp);
|
||||
|
||||
|
@ -846,7 +872,8 @@ Result huagao_ds::setupMemXferGet(const Identity& id, SetupMemXfer& data)
|
|||
}
|
||||
Result huagao_ds::userInterfaceDisable(const Identity&, UserInterface& ui)
|
||||
{
|
||||
scanner_->ui_hide();
|
||||
if (scanner_.get())
|
||||
scanner_->stop();
|
||||
|
||||
return success();
|
||||
}
|
||||
|
@ -854,8 +881,6 @@ Result huagao_ds::userInterfaceEnable(const Identity&, UserInterface& ui)
|
|||
{
|
||||
if (!ui.showUi())
|
||||
{
|
||||
bool xfer_ready = !m_bIndicator;
|
||||
|
||||
if (m_bIndicator && !scanner_->ui_show_progress((HWND)ui.parent().raw()))
|
||||
return seqError();
|
||||
|
||||
|
@ -863,14 +888,11 @@ Result huagao_ds::userInterfaceEnable(const Identity&, UserInterface& ui)
|
|||
|
||||
if (scanner_->start() == SCANNER_ERR_OK)
|
||||
{
|
||||
if (xfer_ready)
|
||||
notifyXferReady();
|
||||
|
||||
return success();
|
||||
}
|
||||
else
|
||||
{
|
||||
return seqError();
|
||||
return bummer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,7 +919,10 @@ Result huagao_ds::imageInfoGet(const Identity&, ImageInfo& data)
|
|||
else
|
||||
{
|
||||
if (!scanner_->wait_image())
|
||||
{
|
||||
notifyCloseOk();
|
||||
return bummer();
|
||||
}
|
||||
ok = scanner_->get_first_image_header(&head);
|
||||
}
|
||||
|
||||
|
@ -914,7 +939,10 @@ Result huagao_ds::imageInfoGet(const Identity&, ImageInfo& data)
|
|||
data.bitsPerSample()[0] = 8;
|
||||
}
|
||||
data.setHeight(head.lines);
|
||||
data.setPixelType(head.format == SANE_FRAME_RGB ? PixelType::Rgb : PixelType::Gray);
|
||||
if (m_compression == Compression::Group4)
|
||||
data.setPixelType(PixelType::BlackWhite);
|
||||
else
|
||||
data.setPixelType(head.format == SANE_FRAME_RGB ? PixelType::Rgb : PixelType::Gray);
|
||||
data.setPlanar(false);
|
||||
data.setWidth(head.pixels_per_line);
|
||||
|
||||
|
@ -924,7 +952,7 @@ Result huagao_ds::imageInfoGet(const Identity&, ImageInfo& data)
|
|||
data.setYResolution(res);
|
||||
data.compression(m_compression);
|
||||
}
|
||||
|
||||
|
||||
return success();
|
||||
}
|
||||
Result huagao_ds::imageLayoutGet(const Identity&, ImageLayout& data)
|
||||
|
@ -964,9 +992,18 @@ Result huagao_ds::imageLayoutReset(const Identity& origin, ImageLayout& data)
|
|||
}
|
||||
Result huagao_ds::imageMemXferGet(const Identity& origin, ImageMemXfer& data)
|
||||
{
|
||||
if (!scanner_.get() || (scanner_->get_scanned_images() == 0 && !pending_xfer_.img))
|
||||
if (!scanner_.get())
|
||||
return seqError();
|
||||
|
||||
if (scanner_->get_scanned_images() == 0 && !pending_xfer_.img)
|
||||
{
|
||||
if (!cur_head_ || !scanner_->wait_image())
|
||||
{
|
||||
notifyCloseOk();
|
||||
return seqError();
|
||||
}
|
||||
}
|
||||
|
||||
IScanImg *img = pending_xfer_.img ? pending_xfer_.img : scanner_->take_first_image(TWAIN_XFER_Memory);
|
||||
unsigned long long off = pending_xfer_.img ? pending_xfer_.off : 0;
|
||||
unsigned char *dst = (unsigned char*)data.memory().data().data();
|
||||
|
@ -1227,7 +1264,7 @@ Result huagao_ds::capCommon(const Identity&, Msg msg, Capability& data) {
|
|||
Twpp::Result huagao_ds::showTwainUI(Twpp::UserInterface& data, bool bUiOnly)
|
||||
{
|
||||
// display user UI ... (setting UI, can we show my own main window here ?)
|
||||
return scanner_->ui_show_setting((HWND)data.parent().raw(), !bUiOnly) ? success() : seqError();
|
||||
return scanner_->ui_show_setting((HWND)data.parent().raw(), !bUiOnly, m_bIndicator) ? success() : seqError();
|
||||
}
|
||||
void huagao_ds::init_support_caps(void)
|
||||
{
|
||||
|
@ -2587,23 +2624,29 @@ void huagao_ds::init_support_caps_ex(void)
|
|||
ADD_SANE_CAP(skew_range);
|
||||
ADD_SANE_CAP(black_white_threshold);
|
||||
}
|
||||
void huagao_ds::on_scan_event(int sane_event, void* data, unsigned int* len)
|
||||
std::wstring huagao_ds::get_config_file(void)
|
||||
{
|
||||
if (scanner_.get())
|
||||
{
|
||||
/*if (sane_event == SANE_EVENT_IMAGE_OK)
|
||||
{
|
||||
notifyDeviceEvent();
|
||||
}
|
||||
else*/ if (sane_event == SANE_EVENT_SCAN_FINISHED)
|
||||
{
|
||||
notifyCloseCancel();
|
||||
}
|
||||
else if (sane_event == SANE_EVENT_WORKING)
|
||||
{
|
||||
notifyXferReady();
|
||||
}
|
||||
}
|
||||
wchar_t path[MAX_PATH] = { 0 }, * name = NULL;
|
||||
|
||||
GetModuleFileNameW(me_, path, _countof(path) - 1);
|
||||
name = wcsrchr(path, L'\\');
|
||||
if (name++ == NULL)
|
||||
name = path;
|
||||
wcscpy_s(name, _countof(path) - 1 - (name - path), L"first.cfg");
|
||||
|
||||
return path;
|
||||
}
|
||||
std::wstring huagao_ds::get_config_value(const wchar_t* sec, const wchar_t* key)
|
||||
{
|
||||
wchar_t v[256] = { 0 };
|
||||
|
||||
GetPrivateProfileStringW(sec, key, L"", v, _countof(v) - 1, get_config_file().c_str());
|
||||
|
||||
return v;
|
||||
}
|
||||
DWORD huagao_ds::get_config_number(const wchar_t* sec, const wchar_t* key)
|
||||
{
|
||||
return GetPrivateProfileIntW(sec, key, 0, get_config_file().c_str());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -44,14 +44,15 @@ class huagao_ds : public Twpp::SourceFromThis<huagao_ds> {
|
|||
|
||||
static std::string get_hidedlg_path(void);
|
||||
static void showmsg(const char* msg, int err);
|
||||
static void scan_event(int sane_event, void* data, unsigned int* len, void* param);
|
||||
|
||||
void CapabilityPrintf(Twpp::Msg msg, std::string capability, std::string value = "");
|
||||
Twpp::Result capCommon(const Twpp::Identity& origin, Twpp::Msg msg, Twpp::Capability& data);
|
||||
Twpp::Result showTwainUI(Twpp::UserInterface& data, bool bUiOnly = false);
|
||||
void init_support_caps(void);
|
||||
void init_support_caps_ex(void);
|
||||
void on_scan_event(int sane_event, void* data, unsigned int* len);
|
||||
std::wstring get_config_file(void);
|
||||
std::wstring get_config_value(const wchar_t* sec, const wchar_t* key);
|
||||
DWORD get_config_number(const wchar_t* sec, const wchar_t* key);
|
||||
|
||||
typedef struct _pending_xfer
|
||||
{
|
||||
|
|
|
@ -302,6 +302,11 @@ namespace Twpp {
|
|||
return notifyApp(Msg::XferReady);
|
||||
}
|
||||
|
||||
/// Notifies application scanning complete with no image got - added on 2022-07-02
|
||||
ReturnCode notifyEndWithoutImages() noexcept {
|
||||
return notifyApp(Msg::Null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Root of source TWAIN calls.
|
||||
|
@ -1185,8 +1190,8 @@ namespace Twpp {
|
|||
if (Twpp::success(rc) || rc == ReturnCode::CheckStatus) {
|
||||
if (inState(DsState::Open)) { // allow userInterfaceEnable to transfer to higher states
|
||||
setState(DsState::Enabled);
|
||||
if(!data.showUi())
|
||||
notifyXferReady();
|
||||
//if(!data.showUi())
|
||||
// notifyXferReady();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue