添加扫描指示器UI

This commit is contained in:
gb 2022-06-18 16:48:41 +08:00
parent 79f8208ea4
commit eec6290cf4
9 changed files with 521 additions and 9 deletions

244
sane/DlgIndicator.cpp Normal file
View File

@ -0,0 +1,244 @@
// DlgIndicator.cpp: 实现文件
//
#include "DlgIndicator.h"
#include "resource.h"
#include "scanned_img.h" // for local_trans
// CDlgIndicator 对话框
#define WM_USB_PACKET_RECEIVED WM_USER + 1
#define WM_IMAGE_RECEIVED WM_USER + 2
#define WM_SCAN_FINISHED WM_USER + 3 // WPARAM: std::string* msg; LPARAM: boo err
ATOM dlg_indicator::indicator_class_atom = 0;
std::wstring dlg_indicator::handle_name = L"dlg_indicator_prop_handle";
std::wstring dlg_indicator::indicator_class_name = L"dlg_indicator_class";
extern HMODULE g_my_inst;
dlg_indicator::dlg_indicator() : hwnd_(NULL), papers_(0), images_(0), notify_(NULL), notify_param_(NULL), parent_(NULL), err_(false)
{
HANDLE wait = CreateEvent(NULL, TRUE, FALSE, NULL);
#ifdef USE_SOLE_WIN_THREAD
thread_.reset(new std::thread(&dlg_indicator::create, this, wait));
#else
create(wait);
#endif
WaitForSingleObject(wait, INFINITE);
CloseHandle(wait);
}
dlg_indicator::~dlg_indicator()
{
#ifdef USE_SOLE_WIN_THREAD
if (IsWindow(hwnd_))
PostMessage(hwnd_, WM_QUIT, 0, 0);
if (thread_.get() && thread_->joinable())
thread_->join();
thread_.reset();
#else
if (IsWindow(hwnd_))
DestroyWindow(hwnd_);
#endif
}
BOOL CALLBACK dlg_indicator::dlg_indicator_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
if (msg == WM_INITDIALOG)
{
dlg_indicator *obj = (dlg_indicator*)lp;
SetPropW(hwnd, dlg_indicator::handle_name.c_str(), (HANDLE)obj);
}
dlg_indicator* obj = (dlg_indicator*)GetPropW(hwnd, dlg_indicator::handle_name.c_str());
BOOL handled = FALSE, ret = FALSE;
if (obj)
ret = obj->handle_msg(msg, wp, lp);
return ret;
}
ATOM dlg_indicator::register_indicator_class(void)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEXW);
wcex.style = WS_POPUP;
wcex.lpfnWndProc = (WNDPROC)dlg_indicator::dlg_indicator_proc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = g_my_inst;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = dlg_indicator::indicator_class_name.c_str();
wcex.hIconSm = NULL;
return RegisterClassExW(&wcex);
}
void dlg_indicator::create(HANDLE wait)
{
MSG msg = { 0 };
BOOL ret = TRUE;
hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(IDD_INDICATOR), NULL, &dlg_indicator::dlg_indicator_proc, (LPARAM)this);
SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW);
SetEvent(wait);
#ifdef USE_SOLE_WIN_THREAD
while ((ret = GetMessage(&msg, NULL, 0, 0)))
{
if (ret == -1)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hwnd_);
#endif
}
BOOL dlg_indicator::handle_msg(UINT msg, WPARAM wp, LPARAM lp)
{
wchar_t text[40] = { 0 };
BOOL ret = TRUE;
switch (msg)
{
case WM_INITDIALOG:
swprintf_s(text, _countof(text) - 1, L"%u", papers_);
SetDlgItemTextW(hwnd_, IDC_EDIT_IMAGE, text);
SetDlgItemTextW(hwnd_, IDC_EDIT_PAPER, text);
break;
case WM_USB_PACKET_RECEIVED:
papers_++;
swprintf_s(text, _countof(text) - 1, L"%u", papers_);
SetDlgItemTextW(hwnd_, IDC_EDIT_PAPER, text);
UpdateWindow(hwnd_);
break;
case WM_IMAGE_RECEIVED:
images_++;
swprintf_s(text, _countof(text) - 1, L"%u", images_);
SetDlgItemTextW(hwnd_, IDC_EDIT_IMAGE, text);
UpdateWindow(hwnd_);
break;
case WM_COMMAND:
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
break;
case WM_DRAWITEM:
if (wp == IDC_STATIC_ERR)
{
DRAWITEMSTRUCT* ds = (DRAWITEMSTRUCT*)lp;
wchar_t text[128] = { 0 };
SetTextColor(ds->hDC, err_ ? RGB(255, 0, 0) : RGB(0, 0, 0));
SetBkMode(ds->hDC, TRANSPARENT);
GetWindowTextW(ds->hwndItem, text, _countof(text) - 1);
TextOutW(ds->hDC, 0, 0, text, lstrlenW(text));
}
ret = FALSE;
break;
case WM_SCAN_FINISHED:
if (lp)
{
std::string* str = (std::string*)wp;
std::wstring err(local_trans::a2u(str->c_str(), CP_UTF8));
SetDlgItemTextW(hwnd_, IDC_STATIC_ERR, err.c_str());
delete str;
}
else
{
wchar_t msg[128] = { 0 };
std::string* str = (std::string*)wp;
swprintf_s(msg, _countof(msg) - 1, L"\u603b\u8ba1\u626b\u63cf\u56fe\u7247\uff1a%u \u5f20", images_);
SetDlgItemTextW(hwnd_, IDC_STATIC_ERR, msg);
delete str;
SetTimer(hwnd_, 1, 3000, NULL);
}
SetDlgItemTextW(hwnd_, IDCANCEL, L"\u5173\u95ed");
ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_PAPER), SW_HIDE);
ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_IMAGE), SW_HIDE);
ShowWindow(GetDlgItem(hwnd_, IDC_EDIT_PAPER), SW_HIDE);
ShowWindow(GetDlgItem(hwnd_, IDC_EDIT_IMAGE), SW_HIDE);
ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_ERR), SW_SHOW);
SetWindowTextW(hwnd_, L"\u626b\u63cf\u7ed3\u675f");
UpdateWindow(hwnd_);
break;
case WM_TIMER:
if (wp == 1)
{
KillTimer(hwnd_, wp);
notify_over();
break;
}
default:
ret = FALSE;
break;
}
return ret;
}
void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl)
{
if (id == IDCANCEL)
{
notify_over();
}
}
void dlg_indicator::notify_over(void)
{
if (notify_)
notify_(true, notify_param_);
}
void dlg_indicator::set_quit_notify(void(__stdcall* notify)(bool, void*), void* param)
{
notify_ = notify;
notify_param_ = param;
}
HWND dlg_indicator::window(void)
{
return hwnd_;
}
HWND dlg_indicator::parent(void)
{
return parent_;
}
void dlg_indicator::show(HWND parent)
{
RECT rp, r;
if (IsWindow(parent))
GetWindowRect(parent, &rp);
else
GetWindowRect(GetDesktopWindow(), &rp);
GetWindowRect(hwnd_, &r);
parent_ = parent;
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);
}
void dlg_indicator::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();
}
}
// CDlgIndicator 消息处理程序

50
sane/DlgIndicator.h Normal file
View File

@ -0,0 +1,50 @@
#pragma once
#include <Windows.h>
#include <string>
// CDlgIndicator 对话框
//#define USE_SOLE_WIN_THREAD
#ifdef USE_SOLE_WIN_THREAD
#include <thread>
#include <memory>
#endif
class dlg_indicator
{
HWND hwnd_;
HWND parent_;
unsigned int papers_;
unsigned int images_;
bool err_;
#ifdef USE_SOLE_WIN_THREAD
std::unique_ptr<std::thread> thread_;
#endif
void(__stdcall* notify_)(bool, void*);
void* notify_param_;
static ATOM indicator_class_atom;
static std::wstring handle_name;
static std::wstring indicator_class_name;
static BOOL CALLBACK dlg_indicator_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
static ATOM register_indicator_class(void);
void create(HANDLE wait);
BOOL handle_msg(UINT msg, WPARAM wp, LPARAM lp);
void handle_command(WORD code, WORD id, HANDLE ctrl);
void notify_over(void);
public:
dlg_indicator();
~dlg_indicator();
public:
void set_quit_notify(void(__stdcall* notify)(bool cancel, void*), void* param);
HWND window(void);
HWND parent(void);
void show(HWND parent);
void hide(void);
void notify_data_arrived(bool image);
void notify_scan_over(const char* msg, bool err);
};

21
sane/resource.h Normal file
View File

@ -0,0 +1,21 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 sane.rc 使用
//
#define IDD_INDICATOR 101
#define IDC_EDIT_PAPER 1001
#define IDC_EDIT_IMAGE 1002
#define IDC_STATIC_PAPER 1003
#define IDC_STATIC_IMAGE 1004
#define IDC_STATIC_ERR 1005
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1006
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

110
sane/sane.rc Normal file
View File

@ -0,0 +1,110 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_INDICATOR DIALOGEX 0, 0, 145, 38
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
CAPTION "正在扫描……"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "取消扫描",IDCANCEL,96,19,42,12
LTEXT "纸张:",IDC_STATIC_PAPER,7,7,25,8
LTEXT "图片:",IDC_STATIC_IMAGE,7,21,24,8
EDITTEXT IDC_EDIT_PAPER,28,5,39,12,ES_AUTOHSCROLL | ES_READONLY
EDITTEXT IDC_EDIT_IMAGE,28,19,39,12,ES_AUTOHSCROLL | ES_READONLY
LTEXT "",IDC_STATIC_ERR,7,7,131,9,NOT WS_VISIBLE
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_INDICATOR, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 138
TOPMARGIN, 7
BOTTOMMARGIN, 31
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_INDICATOR AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -197,6 +197,7 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$
<ClCompile Include="..\..\code_device\hgsane\main.c" /> <ClCompile Include="..\..\code_device\hgsane\main.c" />
<ClCompile Include="..\..\code_device\hgsane\sane_hg_mdw.cpp" /> <ClCompile Include="..\..\code_device\hgsane\sane_hg_mdw.cpp" />
<ClCompile Include="..\..\code_device\hgsane\sane_option.cpp" /> <ClCompile Include="..\..\code_device\hgsane\sane_option.cpp" />
<ClCompile Include="DlgIndicator.cpp" />
<ClCompile Include="sane_option_trans.cpp" /> <ClCompile Include="sane_option_trans.cpp" />
<ClCompile Include="scanned_img.cpp" /> <ClCompile Include="scanned_img.cpp" />
<ClCompile Include="scanner.cpp" /> <ClCompile Include="scanner.cpp" />
@ -214,6 +215,8 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$
<ClInclude Include="..\..\sdk\include\sane\sanei_debug.h" /> <ClInclude Include="..\..\sdk\include\sane\sanei_debug.h" />
<ClInclude Include="..\..\sdk\include\sane\sane_ex.h" /> <ClInclude Include="..\..\sdk\include\sane\sane_ex.h" />
<ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h" /> <ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h" />
<ClInclude Include="DlgIndicator.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="s2t_api.h" /> <ClInclude Include="s2t_api.h" />
<ClInclude Include="sane_option_trans.h" /> <ClInclude Include="sane_option_trans.h" />
<ClInclude Include="scanned_img.h" /> <ClInclude Include="scanned_img.h" />
@ -225,6 +228,9 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$
<ItemGroup> <ItemGroup>
<Text Include="..\..\code_device\hgsane\CMakeLists.txt" /> <Text Include="..\..\code_device\hgsane\CMakeLists.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="sane.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -42,6 +42,9 @@
<ClCompile Include="scanner.cpp"> <ClCompile Include="scanner.cpp">
<Filter>sane2twain</Filter> <Filter>sane2twain</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="DlgIndicator.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\code_device\hgsane\cJSON.h"> <ClInclude Include="..\..\code_device\hgsane\cJSON.h">
@ -92,6 +95,12 @@
<ClInclude Include="scanner.h"> <ClInclude Include="scanner.h">
<Filter>sane2twain</Filter> <Filter>sane2twain</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="resource.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="DlgIndicator.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="sane.def"> <None Include="sane.def">
@ -101,4 +110,9 @@
<ItemGroup> <ItemGroup>
<Text Include="..\..\code_device\hgsane\CMakeLists.txt" /> <Text Include="..\..\code_device\hgsane\CMakeLists.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="sane.rc">
<Filter>资源文件</Filter>
</ResourceCompile>
</ItemGroup>
</Project> </Project>

View File

@ -7,7 +7,7 @@
#include "sane_option_trans.h" #include "sane_option_trans.h"
#include <chrono> #include <chrono>
#include <mutex> #include <mutex>
#include "DlgIndicator.h"
static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt); static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
@ -87,6 +87,7 @@ namespace callback
// class scanner // class scanner
scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BASE), prev_start_result_(SCANNER_ERR_NOT_START) 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) , dpi_(200), tmp_path_(L""), img_ind_(0), cb_invoker_(NULL), cb_param_(NULL), working_(false)
, ui_quit_(true)
{ {
tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str()); tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str());
tmp_path_ += L"imgs"; tmp_path_ += L"imgs";
@ -158,6 +159,10 @@ float __stdcall scanner::to_float(SANE_Fixed v)
{ {
return SANE_UNFIX(v); return SANE_UNFIX(v);
} }
void __stdcall scanner::ui_callback(bool cancel, void* param)
{
((scanner*)param)->on_ui_quit(cancel);
}
// IRef // IRef
COM_API_IMPLEMENT(scanner, long, add_ref(void)) COM_API_IMPLEMENT(scanner, long, add_ref(void))
@ -169,6 +174,17 @@ COM_API_IMPLEMENT(scanner, long, release(void))
return refer::release(); return refer::release();
} }
void scanner::on_ui_quit(bool cancel)
{
if (cancel)
stop();
ui_quit_ = true;
if (cb_invoker_)
{
cb_invoker_(SANE_EVENT_SCAN_FINISHED, NULL, NULL, cb_param_);
}
}
int scanner::open(void) int scanner::open(void)
{ {
int ret = close(); int ret = close();
@ -1429,7 +1445,11 @@ EX_OPTION_HANDLER_IMPL(ip)
// ISaneInvoker // ISaneInvoker
COM_API_IMPLEMENT(scanner, int, start(void)) COM_API_IMPLEMENT(scanner, int, start(void))
{ {
int ret = hg_sane_middleware::instance()->start(handle_, NULL); int ret = SANE_STATUS_GOOD;
scan_msg_ = "OK";
scan_err_ = false;
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 ... // 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) if(ret == SANE_STATUS_NO_DOCS && prev_start_result_ == SANE_STATUS_GOOD)
@ -1465,10 +1485,27 @@ 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();
bool notify = true;
while (count == 0 && milliseconds && working_) while (count == 0 && milliseconds)
{ {
MSG msg = { 0 };
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
Sleep(10); 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;
}
count = images_.count(); count = images_.count();
if (milliseconds != -1) if (milliseconds != -1)
{ {
@ -1781,14 +1818,26 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_main(HWND parent))
} }
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))
{ {
return false; indicator_.reset(new dlg_indicator());
indicator_->set_quit_notify(&scanner::ui_callback, this);
indicator_->show(parent);
ui_quit_ = false;
return true;
} }
COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent)) COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
{ {
return false; indicator_.reset(new dlg_indicator());
indicator_->set_quit_notify(&scanner::ui_callback, this);
indicator_->show(parent);
ui_quit_ = false;
return true;
} }
COM_API_IMPLEMENT(scanner, void, ui_hide(void)) COM_API_IMPLEMENT(scanner, void, ui_hide(void))
{ {
if (indicator_.get())
indicator_.reset();
} }
COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void)) COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void))
{ {
@ -1816,12 +1865,22 @@ int scanner::handle_event(int ev_code, void* data, unsigned int* len)
{ {
img->release(); img->release();
} }
if (indicator_)
indicator_->notify_data_arrived(true);
}
else if (ev_code == SANE_EVENT_USB_DATA_RECEIVED)
{
if (indicator_)
indicator_->notify_data_arrived(false);
} }
else if (ev_code == SANE_EVENT_SCAN_FINISHED) else if (ev_code == SANE_EVENT_SCAN_FINISHED)
{ {
if (indicator_.get())
{
scan_msg_ = (char*)data;
scan_err_ = *len != SCANNER_ERR_OK;
}
working_ = false; working_ = false;
//if (cb_invoker_) // calling this when UI exited
// cb_invoker_(ev_code, data, len, cb_param_);
} }
return 0; return 0;

View File

@ -3,7 +3,7 @@
#include "scanned_img.h" #include "scanned_img.h"
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <memory>
#define SANE_OPTION_ID(name) \ #define SANE_OPTION_ID(name) \
SANE_OPTION_ID_OVERRIDE(name); \ SANE_OPTION_ID_OVERRIDE(name); \
@ -21,6 +21,8 @@
#define EXTENSION_ID_BASE 0x300 #define EXTENSION_ID_BASE 0x300
class dlg_indicator;
class scanner : public ISaneInvoker, virtual public refer class scanner : public ISaneInvoker, virtual public refer
{ {
SANE_Handle handle_; SANE_Handle handle_;
@ -33,11 +35,16 @@ class scanner : public ISaneInvoker, virtual public refer
int dpi_; int dpi_;
unsigned int img_ind_; unsigned int img_ind_;
std::wstring tmp_path_; std::wstring tmp_path_;
std::string scan_msg_;
bool scan_err_;
twain_xfer xfer_; twain_xfer xfer_;
safe_img_queue images_; safe_img_queue images_;
volatile bool working_; volatile bool working_;
bool ui_quit_;
SANE_FinalImgFormat img_fmt_; SANE_FinalImgFormat img_fmt_;
std::unique_ptr<dlg_indicator> indicator_;
void on_ui_quit(bool cancel);
int open(void); int open(void);
int close(void); int close(void);
int init_options_id(void); int init_options_id(void);
@ -155,6 +162,7 @@ class scanner : public ISaneInvoker, virtual public refer
static int __stdcall to_int(SANE_Int v); static int __stdcall to_int(SANE_Int v);
static float __stdcall to_float(SANE_Fixed v); static float __stdcall to_float(SANE_Fixed v);
static void __stdcall ui_callback(bool cancel, void* param);
public: public:
scanner(SCANNERID id); scanner(SCANNERID id);

View File

@ -2471,7 +2471,7 @@ void huagao_ds::on_scan_event(int sane_event, void* data, unsigned int* len)
{ {
if (sane_event == SANE_EVENT_SCAN_FINISHED) if (sane_event == SANE_EVENT_SCAN_FINISHED)
{ {
notifyCloseOk(); notifyCloseCancel();
} }
} }
} }