完善设置界面扫描流程

This commit is contained in:
gb 2022-06-27 09:38:12 +08:00
parent c55d6189d1
commit 0e66d29b90
10 changed files with 169 additions and 48 deletions

View File

@ -95,6 +95,7 @@ namespace calc
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// dlg_gamma // dlg_gamma
dlg_gamma::dlg_gamma(HWND parent, bool color) : dlg_base(parent, IDD_GAMMA), exit_code_(0), is_color_(color), bkgnd_(NULL) dlg_gamma::dlg_gamma(HWND parent, bool color) : dlg_base(parent, IDD_GAMMA), exit_code_(0), is_color_(color), bkgnd_(NULL)
, show_all_(false)
{ {
create(); create();
} }
@ -312,10 +313,12 @@ BYTE dlg_gamma::calc_value(BYTE x)
y = 255.0f; y = 255.0f;
if (y < .0f) if (y < .0f)
y = .0f; y = .0f;
if (y < cur_->points[0].y)
y = cur_->points[0].y; bool upper = cur_->points[1].y > cur_->points[0].y;
if (y > cur_->points[1].y) if (y < cur_->points[!upper].y)
y = cur_->points[1].y; y = cur_->points[!upper].y;
if (y > cur_->points[upper].y)
y = cur_->points[upper].y;
return y + .5f; return y + .5f;
} }
@ -381,6 +384,15 @@ void dlg_gamma::draw_ellipse(HDC hdc, POINT center, int xl, int yl)
DeleteObject(brsh); DeleteObject(brsh);
DeleteObject(rgn); DeleteObject(rgn);
} }
void dlg_gamma::draw_current_curve(HDC hdc)
{
MoveToEx(hdc, paint_area_.left + cur_->points[0].x, paint_area_.bottom - cur_->points[0].y, NULL);
for (int i = 0; i < 256; ++i)
{
int y = calc_value(i);
LineTo(hdc, paint_area_.left + i, paint_area_.bottom - y);
}
}
void dlg_gamma::on_init_dlg(void) void dlg_gamma::on_init_dlg(void)
{ {
@ -433,13 +445,38 @@ void dlg_gamma::on_paint(HDC hdc)
SelectObject(cdc, ob); SelectObject(cdc, ob);
DeleteDC(cdc); DeleteDC(cdc);
MoveToEx(hdc, paint_area_.left, paint_area_.bottom, NULL); if (show_all_)
for (int i = 0; i < 256; ++i)
{ {
int y = calc_value(i); GAMMACURVE* prev = cur_;
LineTo(hdc, paint_area_.left + i, paint_area_.bottom - y); HPEN now = NULL;
cur_ = &red_;
now = CreatePen(PS_SOLID, 1, cur_->clr);
SelectObject(hdc, now);
draw_current_curve(hdc);
cur_ = &green_;
SelectObject(hdc, old);
DeleteObject(now);
now = CreatePen(PS_SOLID, 1, cur_->clr);
SelectObject(hdc, now);
draw_current_curve(hdc);
cur_ = &blue_;
SelectObject(hdc, old);
DeleteObject(now);
now = CreatePen(PS_SOLID, 1, cur_->clr);
SelectObject(hdc, now);
draw_current_curve(hdc);
SelectObject(hdc, pen);
DeleteObject(now);
cur_ = prev;
} }
else
draw_current_curve(hdc);
SelectObject(hdc, drag); SelectObject(hdc, drag);
for (int i = 0; i < cur_->points.size(); ++i) for (int i = 0; i < cur_->points.size(); ++i)
{ {
draw_ellipse(hdc, cur_->points[i], 3, 3); draw_ellipse(hdc, cur_->points[i], 3, 3);
@ -497,9 +534,62 @@ void dlg_gamma::on_lbutton_up(int x, int y)
} }
void dlg_gamma::on_combo_sel_changed(int id, int sel) void dlg_gamma::on_combo_sel_changed(int id, int sel)
{ {
show_all_ = false;
if (id == IDC_SCHEME) if (id == IDC_SCHEME)
{ {
if (sel == 1)
{
cur_ = &rgb_gray_;
init_curve(cur_);
cur_->points.clear();
cur_->points.push_back({ 0, 255 });
cur_->points.push_back({ 255, 0 });
cur_->coefs = calc::coefs_from_points(cur_->points);
}
else if (sel == 2)
{
show_all_ = true;
cur_ = &red_;
init_curve(cur_, cur_->clr);
cur_->points.clear();
cur_->points.push_back({ 33, 255 });
cur_->points.push_back({ 185, 0 });
cur_->points.push_back({ 119, 127 });
cur_->coefs = calc::coefs_from_points(cur_->points);
cur_ = &green_;
init_curve(cur_, cur_->clr);
cur_->points.clear();
cur_->points.push_back({ 28, 255 });
cur_->points.push_back({ 132, 0 });
cur_->points.push_back({ 77, 127 });
cur_->coefs = calc::coefs_from_points(cur_->points);
cur_ = &blue_;
init_curve(cur_, cur_->clr);
cur_->points.clear();
cur_->points.push_back({ 25, 255 });
cur_->points.push_back({ 108, 0 });
cur_->points.push_back({ 60, 127 });
cur_->coefs = calc::coefs_from_points(cur_->points);
cur_ = &red_;
}
else if (sel == 3)
{
cur_ = &rgb_gray_;
init_curve(cur_);
cur_->points.push_back({ 130, 101 });
cur_->coefs = calc::coefs_from_points(cur_->points);
}
else if (sel == 4)
{
cur_ = &rgb_gray_;
init_curve(cur_);
cur_->points.push_back({ 103, 125 });
cur_->coefs = calc::coefs_from_points(cur_->points);
}
InvalidateRect(hwnd(), NULL, FALSE);
} }
else if (id == IDC_CHANNEL) else if (id == IDC_CHANNEL)
{ {

View File

@ -11,6 +11,7 @@ class dlg_gamma: public dlg_base
{ {
int exit_code_; int exit_code_;
bool is_color_; bool is_color_;
bool show_all_;
RECT paint_area_; RECT paint_area_;
HBITMAP bkgnd_; HBITMAP bkgnd_;
@ -38,6 +39,7 @@ class dlg_gamma: public dlg_base
bool is_adjacent(POINT p1, POINT p2); bool is_adjacent(POINT p1, POINT p2);
bool hit_test(int* x, int* y); bool hit_test(int* x, int* y);
void draw_ellipse(HDC hdc, POINT center, int xl, int yl); void draw_ellipse(HDC hdc, POINT center, int xl, int yl);
void draw_current_curve(HDC hdc);
void on_init_dlg(void); void on_init_dlg(void);
void on_paint(HDC hdc); void on_paint(HDC hdc);

View File

@ -12,7 +12,7 @@
dlg_indicator::dlg_indicator(HWND parent) : dlg_base(parent, IDD_INDICATOR) dlg_indicator::dlg_indicator(HWND parent) : dlg_base(parent, IDD_INDICATOR)
, papers_(0), images_(0), notify_(NULL), notify_param_(NULL), err_(false) , papers_(0), images_(0), err_(false)
{ {
create(); create();
SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW); SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW);
@ -113,15 +113,9 @@ void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl)
} }
void dlg_indicator::notify_over(bool cancel) void dlg_indicator::notify_over(bool cancel)
{ {
if (notify_) notify_ui_event(cancel ? UI_EVENT_CLOSE_CANCEL : UI_EVENT_CLOSE_NORMAL);
notify_(cancel ? UI_EVENT_CLOSE_CANCEL : UI_EVENT_CLOSE_NORMAL, notify_param_);
} }
void dlg_indicator::set_quit_notify(void(__stdcall* notify)(ui_event, void*), void* param)
{
notify_ = notify;
notify_param_ = param;
}
HWND dlg_indicator::window(void) HWND dlg_indicator::window(void)
{ {
return hwnd_; return hwnd_;

View File

@ -12,8 +12,6 @@ class dlg_indicator : public dlg_base
unsigned int papers_; unsigned int papers_;
unsigned int images_; unsigned int images_;
bool err_; bool err_;
void(__stdcall* notify_)(ui_event, void*);
void* notify_param_;
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
void handle_command(WORD code, WORD id, HANDLE ctrl); void handle_command(WORD code, WORD id, HANDLE ctrl);
@ -24,7 +22,6 @@ public:
~dlg_indicator(); ~dlg_indicator();
public: public:
void set_quit_notify(void(__stdcall* notify)(ui_event uev, void*), void* param);
HWND window(void); HWND window(void);
HWND parent(void); HWND parent(void);
void show(void); void show(void);

View File

@ -25,7 +25,7 @@ extern HMODULE g_my_inst;
std::wstring dlg_base::prop_name = L"dlg_base_object_prop_name"; std::wstring dlg_base::prop_name = L"dlg_base_object_prop_name";
dlg_base::dlg_base(HWND parent, UINT idd) : parent_(parent), hwnd_(NULL), idd_(idd) dlg_base::dlg_base(HWND parent, UINT idd) : parent_(parent), hwnd_(NULL), idd_(idd), ui_event_notify_(NULL), ui_notify_param_(NULL)
{ {
} }
dlg_base::~dlg_base() dlg_base::~dlg_base()
@ -100,11 +100,25 @@ void dlg_base::create(void)
{ {
hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, &dlg_base::dlg_proc, (LPARAM)this); hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, &dlg_base::dlg_proc, (LPARAM)this);
} }
void dlg_base::notify_ui_event(ui_event ev)
{
if (ui_event_notify_)
ui_event_notify_(ev, this, ui_notify_param_);
}
void dlg_base::set_ui_event_notify(void(__stdcall* notify)(ui_event, void*, void*), void* param)
{
ui_event_notify_ = notify;
ui_notify_param_ = param;
}
HWND dlg_base::hwnd(void) HWND dlg_base::hwnd(void)
{ {
return hwnd_; return hwnd_;
} }
void dlg_base::enable(bool enable)
{
EnableWindow(hwnd_, enable);
}
void dlg_base::screen_2_client(LPRECT r) void dlg_base::screen_2_client(LPRECT r)
{ {
POINT pt = { r->left, r->top }; POINT pt = { r->left, r->top };

View File

@ -25,13 +25,15 @@ protected:
HWND hwnd_; HWND hwnd_;
HWND parent_; HWND parent_;
UINT idd_; UINT idd_;
void(__stdcall* ui_event_notify_)(ui_event uev, void* sender, void* param);
void* ui_notify_param_;
static std::wstring prop_name; static std::wstring prop_name;
static BOOL CALLBACK dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); static BOOL CALLBACK dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
virtual BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp); virtual BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp);
virtual void on_font_changed(void); virtual void on_font_changed(void);
void create(void); void create(void);
void notify_ui_event(ui_event ev);
public: public:
dlg_base(HWND parent, UINT idd); dlg_base(HWND parent, UINT idd);
@ -41,7 +43,9 @@ public:
static bool get_max_size(SIZE& dst, int cx, int cy); // return whether changed dst static bool get_max_size(SIZE& dst, int cx, int cy); // return whether changed dst
public: public:
void set_ui_event_notify(void(__stdcall* notify)(ui_event, void*, void*), void* param);
HWND hwnd(void); HWND hwnd(void);
void enable(bool enable);
void screen_2_client(LPRECT r); void screen_2_client(LPRECT r);
void client_2_screen(LPRECT r); void client_2_screen(LPRECT r);
HWND get_item(UINT id); HWND get_item(UINT id);

View File

@ -17,7 +17,7 @@ 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) : dlg_base(parent, IDD_SETTING)
, sane_api_(*api), sane_dev_(dev), with_scan_(with_scan) , sane_api_(*api), sane_dev_(dev), with_scan_(with_scan)
, papers_(0), images_(0), notify_(NULL), notify_param_(NULL), err_(false), tab_(NULL) , papers_(0), images_(0), err_(false), tab_(NULL)
{ {
create(); create();
SetWindowTextW(hwnd(), (std::wstring(name) + L" \u8bbe\u7f6e").c_str()); SetWindowTextW(hwnd(), (std::wstring(name) + L" \u8bbe\u7f6e").c_str());
@ -84,15 +84,13 @@ void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl)
} }
else if (id == IDC_BUTTON_SCAN) else if (id == IDC_BUTTON_SCAN)
{ {
if (sane_api_.sane_start_api(sane_dev_) == SANE_STATUS_GOOD && enable(false);
notify_) notify_ui_event(UI_EVENT_BEGIN_SCANNING);
notify_(UI_EVENT_BEGIN_SCANNING, notify_param_);
} }
} }
void dlg_setting::notify_over(void) void dlg_setting::notify_over(void)
{ {
if (notify_) notify_ui_event(UI_EVENT_CLOSE_NORMAL);
notify_(UI_EVENT_CLOSE_NORMAL, notify_param_);
} }
void dlg_setting::on_init_dialog(void) void dlg_setting::on_init_dialog(void)
{ {
@ -330,11 +328,6 @@ void dlg_setting::refresh_controls(int src_sn)
} }
} }
void dlg_setting::set_quit_notify(void(__stdcall* notify)(ui_event, void*), void* param)
{
notify_ = notify;
notify_param_ = param;
}
HWND dlg_setting::window(void) HWND dlg_setting::window(void)
{ {
return hwnd_; return hwnd_;

View File

@ -31,8 +31,6 @@ class dlg_setting : public dlg_base
#ifdef USE_SOLE_WIN_THREAD #ifdef USE_SOLE_WIN_THREAD
std::unique_ptr<std::thread> thread_; std::unique_ptr<std::thread> thread_;
#endif #endif
void(__stdcall* notify_)(ui_event, void*);
void* notify_param_;
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
void handle_command(WORD code, WORD id, HANDLE ctrl); void handle_command(WORD code, WORD id, HANDLE ctrl);
@ -51,7 +49,6 @@ public:
~dlg_setting(); ~dlg_setting();
public: public:
void set_quit_notify(void(__stdcall* notify)(ui_event uev, void*), void* param);
HWND window(void); HWND window(void);
HWND parent(void); HWND parent(void);
void show(void); void show(void);

View File

@ -182,9 +182,9 @@ float __stdcall scanner::to_float(SANE_Fixed v)
{ {
return SANE_UNFIX(v); return SANE_UNFIX(v);
} }
void __stdcall scanner::ui_callback(ui_event uev, void* param) void __stdcall scanner::ui_callback(ui_event uev, void* sender, void* param)
{ {
((scanner*)param)->on_ui_quit(uev); ((scanner*)param)->on_ui_quit(uev, sender);
} }
// IRef // IRef
@ -197,16 +197,39 @@ COM_API_IMPLEMENT(scanner, long, release(void))
return refer::release(); return refer::release();
} }
void scanner::on_ui_quit(ui_event uev) void scanner::on_ui_quit(ui_event uev, void* sender)
{ {
if (uev == UI_EVENT_CLOSE_CANCEL) switch (uev)
stop();
ui_quit_ = uev != UI_EVENT_BEGIN_SCANNING;
if (cb_invoker_)
{ {
cb_invoker_(ui_quit_ ? SANE_EVENT_SCAN_FINISHED : SANE_EVENT_WORKING, NULL, NULL, cb_param_); 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();
}
else
setting_->enable(true);
break;
default:
break;
} }
if (cb_invoker_)
cb_invoker_(ui_quit_ ? SANE_EVENT_SCAN_FINISHED : SANE_EVENT_WORKING, NULL, NULL, cb_param_);
} }
int scanner::open(void) int scanner::open(void)
{ {
@ -1860,7 +1883,14 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan))
api.sane_strstatus_api = inner_sane_strstatus; api.sane_strstatus_api = inner_sane_strstatus;
setting_.reset(new dlg_setting(parent, &api, handle_, with_scan, scanner_name_.c_str())); setting_.reset(new dlg_setting(parent, &api, handle_, with_scan, scanner_name_.c_str()));
setting_->set_quit_notify(&scanner::ui_callback, this); setting_->set_ui_event_notify(&scanner::ui_callback, this);
if (with_scan)
{
indicator_.reset(new dlg_indicator(parent));
indicator_->set_ui_event_notify(&scanner::ui_callback, this);
}
else
indicator_.reset();
setting_->show(); setting_->show();
ui_quit_ = false; ui_quit_ = false;
@ -1869,7 +1899,7 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan))
COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent)) COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
{ {
indicator_.reset(new dlg_indicator(parent)); indicator_.reset(new dlg_indicator(parent));
indicator_->set_quit_notify(&scanner::ui_callback, this); indicator_->set_ui_event_notify(&scanner::ui_callback, this);
indicator_->show(); indicator_->show();
ui_quit_ = false; ui_quit_ = false;

View File

@ -48,7 +48,7 @@ class scanner : public ISaneInvoker, virtual public refer
std::unique_ptr<dlg_indicator> indicator_; std::unique_ptr<dlg_indicator> indicator_;
std::unique_ptr<dlg_setting> setting_; std::unique_ptr<dlg_setting> setting_;
void on_ui_quit(ui_event uev); void on_ui_quit(ui_event uev, void* sender);
int open(void); int open(void);
int close(void); int close(void);
int init_options_id(void); int init_options_id(void);
@ -166,7 +166,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(ui_event uev, void* param); static void __stdcall ui_callback(ui_event uev, void* sender, void* param);
public: public:
scanner(SCANNERID id); scanner(SCANNERID id);