diff --git a/sane/DlgArea.cpp b/sane/DlgArea.cpp new file mode 100644 index 0000000..5ac8f01 --- /dev/null +++ b/sane/DlgArea.cpp @@ -0,0 +1,732 @@ +// DlgIndicator.cpp: 实现文件 +// + +#include "DlgArea.h" +#include "resource.h" +#include "scanned_img.h" // for local_trans + +// CDlgIndicator 对话框 +#define MM_PER_INCH 25.4f + +int dlg_area::area_min_pixel = 50; + +dlg_area::dlg_area(HWND parent) : dlg_base(parent, IDD_AREA) + , unit_(PAPER_UNIT_MM), paper_w_(210), paper_h_(297), dpi_(200) + , x_(0), y_(0), w_(paper_w_), h_(paper_h_) + , exit_code_(0), paper_(L"A4") + , paper_w_0_(paper_w_), paper_h_0_(paper_h_), cursor_(NULL), drag_(DRAG_POS_NONE) + , in_set_func_(false) +{ + create(); + SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)L"\u6beb\u7c73(mm)"); + SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)L"\u82f1\u5bf8(inch)"); + SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)L"\u50cf\u7d20(px)"); + SendMessage(get_item(IDC_UNIT), CB_SETCURSEL, 0, 0); +} +dlg_area::~dlg_area() +{ +} + +float dlg_area::mm_2_pixel(float mm, float dpi) +{ + return inches_2_pixel(mm_2_inches(mm), dpi); +} +float dlg_area::mm_2_inches(float mm) +{ + return mm / MM_PER_INCH; +} +float dlg_area::inches_2_pixel(float inch, float dpi) +{ + return inch * dpi; +} +float dlg_area::inches_2_mm(float inch) +{ + return inch * MM_PER_INCH; +} +float dlg_area::pixel_2_mm(float px, float dpi) +{ + return inches_2_mm(pixel_2_inches(px, dpi)); +} +float dlg_area::pixel_2_inches(float px, float dpi) +{ + return px / dpi; +} + +BOOL dlg_area::handle_message(UINT msg, WPARAM wp, LPARAM lp) +{ + wchar_t text[40] = { 0 }; + BOOL ret = TRUE; + + switch (msg) + { + case WM_INITDIALOG: + UpdateWindow(hwnd()); + break; + case WM_COMMAND: + handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); + break; + case WM_PAINT: + { + PAINTSTRUCT ps = { 0 }; + HDC hdc = BeginPaint(hwnd(), &ps); + { + compatible_dc dc(hdc); + on_paint(dc.get_dc()); + } + EndPaint(hwnd(), &ps); + } + break; + case WM_MOUSEMOVE: + on_mouse_move(wp, LOWORD(lp), HIWORD(lp)); + break; + case WM_LBUTTONDOWN: + on_lbutton_down(LOWORD(lp), HIWORD(lp)); + break; + case WM_LBUTTONUP: + on_lbutton_up(LOWORD(lp), HIWORD(lp)); + break; + default: + ret = FALSE; + } + return ret; +} +void dlg_area::handle_command(WORD code, WORD id, HANDLE ctrl) +{ + if (id == IDC_UNIT) + { + if (code == CBN_SELCHANGE) + { + on_unit_changed((HWND)ctrl); + } + } + else if (id == IDCANCEL) + { + exit_code_ = id; + } + else if (id == IDOK) + { + exit_code_ = id; + } + else if (id == IDC_BUTTON_RESET) + { + clear_area(); + } + else if (id == IDC_EDIT_x || + id == IDC_EDIT_y || + id == IDC_EDIT_W || + id == IDC_EDIT_H) + { + if (code == EN_CHANGE && !in_set_func_) + { + wchar_t val[80] = { 0 }; + float num = .0f; + + GetWindowTextW((HWND)ctrl, val, _countof(val) - 1); + num = _wtof(val); + if (id == IDC_EDIT_x) + { + if (num < .0f) + num = .0f; + if (num > paper_w_ - dlg_area::area_min_pixel) + num = paper_w_ - dlg_area::area_min_pixel; + x_ = num; + user_sel_.left = whole_.left + x_ / ratio_; + if (x_ + w_ > paper_w_) + w_ = paper_w_ - x_; + user_sel_.right = user_sel_.left + w_ / ratio_; + refresh_paper_info(); + InvalidateRect(hwnd(), &whole_, FALSE); + } + else if (id == IDC_EDIT_y) + { + if (num < .0f) + num = .0f; + if (num > paper_h_ - dlg_area::area_min_pixel) + num = paper_h_ - dlg_area::area_min_pixel; + y_ = num; + user_sel_.top = whole_.top + y_ / ratio_; + if (y_ + h_ > paper_h_) + h_ = paper_h_ - y_; + user_sel_.bottom = user_sel_.top + h_ / ratio_; + refresh_paper_info(); + InvalidateRect(hwnd(), &whole_, FALSE); + } + else if (id == IDC_EDIT_W) + { + if (num < dlg_area::area_min_pixel) + num = dlg_area::area_min_pixel; + if (num > paper_w_) + num = paper_w_; + w_ = num; + user_sel_.right = user_sel_.left + w_ / ratio_; + if (user_sel_.right > whole_.right) + { + OffsetRect(&user_sel_, whole_.right - user_sel_.right, 0); + if (user_sel_.left < whole_.left) + { + user_sel_.left = whole_.left; + x_ = 0; + } + } + refresh_paper_info(); + InvalidateRect(hwnd(), &whole_, FALSE); + } + else if (id == IDC_EDIT_H) + { + if (num < dlg_area::area_min_pixel) + num = dlg_area::area_min_pixel; + if (num > paper_h_) + num = paper_h_; + h_ = num; + user_sel_.bottom = user_sel_.top + h_ / ratio_; + if (user_sel_.bottom > whole_.bottom) + { + OffsetRect(&user_sel_, 0, whole_.bottom - user_sel_.bottom); + if (user_sel_.top < whole_.top) + { + user_sel_.top = whole_.top; + y_ = 0; + } + } + refresh_paper_info(); + InvalidateRect(hwnd(), &whole_, FALSE); + } + } + } +} + +float dlg_area::as_mm(float v) +{ + if (unit_ == PAPER_UNIT_INCH) + return dlg_area::inches_2_mm(v); + else if (unit_ == PAPER_UNIT_PIXEL) + return dlg_area::pixel_2_mm(v, dpi_); + else + return v; +} +float dlg_area::as_inches(float v) +{ + if (unit_ == PAPER_UNIT_MM) + return dlg_area::mm_2_inches(v); + else if (unit_ == PAPER_UNIT_PIXEL) + return dlg_area::pixel_2_inches(v, dpi_); + else + return v; +} +float dlg_area::as_pixels(float v) +{ + if (unit_ == PAPER_UNIT_MM) + return dlg_area::mm_2_pixel(v, dpi_); + else if (unit_ == PAPER_UNIT_INCH) + return dlg_area::inches_2_pixel(v, dpi_); + else + return v; +} +std::wstring dlg_area::format_number(float v) +{ + wchar_t str[40] = { 0 }; + + if (unit_ == PAPER_UNIT_PIXEL) + swprintf_s(str, _countof(str) - 1, L"%d", (int)(v + .5f)); + else + swprintf_s(str, _countof(str) - 1, L"%.2f", v); + + return str; +} +void dlg_area::refresh_paper_info(void) +{ + SetWindowTextW(get_item(IDC_EDIT_PAPER), (paper_ + L"(" + format_number(paper_w_) + L"\u00d7" + format_number(paper_h_) + L")").c_str()); + SetDlgItemInt(hwnd(), IDC_EDIT_DPI, UINT(dpi_), FALSE); + + in_set_func_ = true; + SetWindowTextW(get_item(IDC_EDIT_x), format_number(x_).c_str()); + SetWindowTextW(get_item(IDC_EDIT_y), format_number(y_).c_str()); + SetWindowTextW(get_item(IDC_EDIT_W), format_number(w_).c_str()); + SetWindowTextW(get_item(IDC_EDIT_H), format_number(h_).c_str()); + in_set_func_ = false; + + InvalidateRect(hwnd(), &whole_, FALSE); +} +void dlg_area::to_unit(paper_unit unit) +{ + float(dlg_area:: * conv)(float) = NULL; + + if (unit == PAPER_UNIT_INCH) + { + conv = &dlg_area::as_inches; + paper_w_ = dlg_area::mm_2_inches(paper_w_0_); + paper_h_ = dlg_area::mm_2_inches(paper_h_0_); + } + else if (unit == PAPER_UNIT_PIXEL) + { + conv = &dlg_area::as_pixels; + paper_w_ = dlg_area::mm_2_pixel(paper_w_0_, dpi_); + paper_h_ = dlg_area::mm_2_pixel(paper_h_0_, dpi_); + } + else // if (unit == PAPER_UNIT_MM) + { + conv = &dlg_area::as_mm; + paper_w_ = paper_w_0_; + paper_h_ = paper_h_0_; + } + +#define CONV_UNIT(v) \ + v = (this->*conv)(v); + + CONV_UNIT(x_); + CONV_UNIT(y_); + CONV_UNIT(w_); + CONV_UNIT(h_); + unit_ = unit; + refresh_paper_info(); +} +void dlg_area::clear_area(void) +{ + x_ = y_ = 0; + w_ = paper_w_; + h_ = paper_h_; + user_sel_ = whole_; + + refresh_paper_info(); +} +void dlg_area::drag_blocks(std::vector& blocks) +{ + int l = 5; + DRAGRECT r = { user_sel_.left, user_sel_.top, user_sel_.left + l, user_sel_.top + l, DRAG_POS_LT }; + + blocks.clear(); + blocks.push_back(r); + OffsetRect(&r, (user_sel_.right - user_sel_.left) / 2 - l / 2, 0); r.pos = DRAG_POS_MT; + blocks.push_back(r); + OffsetRect(&r, (user_sel_.right - r.right), 0); r.pos = DRAG_POS_RT; + blocks.push_back(r); + OffsetRect(&r, 0, (user_sel_.bottom - user_sel_.top) / 2 - l / 2); r.pos = DRAG_POS_RM; + blocks.push_back(r); + OffsetRect(&r, 0, (user_sel_.bottom - r.bottom)); r.pos = DRAG_POS_RB; + blocks.push_back(r); + OffsetRect(&r, -((user_sel_.right - user_sel_.left) / 2 - l / 2), 0); r.pos = DRAG_POS_MB; + blocks.push_back(r); + OffsetRect(&r, user_sel_.left - r.left, 0); r.pos = DRAG_POS_LB; + blocks.push_back(r); + OffsetRect(&r, 0, -((user_sel_.bottom - user_sel_.top) / 2 - l / 2)); r.pos = DRAG_POS_LM; + blocks.push_back(r); +} +float dlg_area::pos_2_area(int val, bool x) +{ + float r = x ? val - whole_.left : val - whole_.top; + + r *= ratio_; + if (unit_ == PAPER_UNIT_INCH) + r = dlg_area::mm_2_inches(r); + else if (unit_ == PAPER_UNIT_PIXEL) + r = dlg_area::mm_2_pixel(r, dpi_); + + return r; +} +void dlg_area::valid_x(int& x, bool left) +{ + if (left) + { + if (x < whole_.left) + x = whole_.left; + if (x > user_sel_.right - dlg_area::area_min_pixel) + x = user_sel_.right - dlg_area::area_min_pixel; + } + else + { + if (x > whole_.right) + x = whole_.right; + if (x < user_sel_.left + dlg_area::area_min_pixel) + x = user_sel_.left + dlg_area::area_min_pixel; + } +} +void dlg_area::valid_y(int& y, bool top) +{ + if (top) + { + if (y < whole_.top) + y = whole_.top; + if (y > user_sel_.bottom - dlg_area::area_min_pixel) + y = user_sel_.bottom - dlg_area::area_min_pixel; + } + else + { + if (y > whole_.bottom) + y = whole_.bottom; + if (y < user_sel_.top + dlg_area::area_min_pixel) + y = user_sel_.top + dlg_area::area_min_pixel; + } +} + +void dlg_area::on_unit_changed(HWND wnd) +{ + wchar_t text[80] = { 0 }; + + GetWindowTextW(wnd, text, _countof(text) - 1); + if (wcsstr(text, L"mm")) + { + if (unit_ != PAPER_UNIT_MM) + { + to_unit(PAPER_UNIT_MM); + } + } + else if (wcsstr(text, L"inch")) + { + if (unit_ != PAPER_UNIT_INCH) + { + to_unit(PAPER_UNIT_INCH); + } + } + else + { + if (unit_ != PAPER_UNIT_PIXEL) + { + to_unit(PAPER_UNIT_PIXEL); + } + } +} +void dlg_area::on_paint(HDC hdc) +{ + HBRUSH brsh_all = CreateSolidBrush(RGB(192, 192, 192)), + brsh_drag = CreateSolidBrush(RGB(255, 0, 0)), + brsh_sel = CreateSolidBrush(RGB(255, 255, 255)); + HPEN pen_border = CreatePen(PS_SOLID, 1, RGB(0, 255, 0)), + pen_ruler = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)), + pen_old = (HPEN)SelectObject(hdc, pen_border); + int step = 3, minor = 3, major = 5, count = 1, len = 0; + + FillRect(hdc, &whole_, brsh_all); + FillRect(hdc, &user_sel_, brsh_sel); + Rectangle(hdc, user_sel_.left, user_sel_.top, user_sel_.right, user_sel_.bottom); + SelectObject(hdc, pen_ruler); + for (int i = whole_.left + step; i < whole_.right; i += step) + { + ++count; + len = (count % 5) == 0 ? major : minor; + MoveToEx(hdc, i, whole_.top, NULL); + LineTo(hdc, i, whole_.top + len); + MoveToEx(hdc, i, whole_.bottom, NULL); + LineTo(hdc, i, whole_.bottom - len); + } + count = 1; + for (int i = whole_.top + step; i < whole_.bottom; i += step) + { + ++count; + len = (count % 5) == 0 ? major : minor; + MoveToEx(hdc, whole_.left, i, NULL); + LineTo(hdc, whole_.left + len, i); + MoveToEx(hdc, whole_.right, i, NULL); + LineTo(hdc, whole_.right - len, i); + } + + std::vector r; + drag_blocks(r); + for(size_t i = 0; i < r.size(); ++i) + FillRect(hdc, &r[i], brsh_drag); + + SelectObject(hdc, pen_old); + DeleteObject(pen_border); + DeleteObject(pen_ruler); + DeleteObject(brsh_all); + DeleteObject(brsh_sel); + DeleteObject(brsh_drag); +} +void dlg_area::on_mouse_move(DWORD key, int x, int y) +{ + if (key == MK_LBUTTON) + { + if (drag_ == DRAG_POS_NONE) + return; + + float dif = .0f; + + SetCursor(LoadCursorW(NULL, cursor_)); + if (drag_ == DRAG_POS_LT) + { + valid_x(x, true); + valid_y(y, true); + user_sel_.left = x; + user_sel_.top = y; + dif = x_; + x_ = pos_2_area(x, true); + w_ -= x_ - dif; + dif = y_; + y_ = pos_2_area(y, false); + h_ -= y_ - dif; + } + else if (drag_ == DRAG_POS_MT) + { + valid_y(y, true); + user_sel_.top = y; + dif = y_; + y_ = pos_2_area(y, false); + h_ -= y_ - dif; + } + else if(drag_ == DRAG_POS_RT) + { + valid_x(x, false); + valid_y(y, true); + user_sel_.right = x; + user_sel_.top = y; + w_ = pos_2_area(x, true) - x_; + if (x_ + w_ > paper_w_) + w_ = paper_w_ - x_; + dif = y_; + y_ = pos_2_area(y, false); + h_ -= y_ - dif; + } + else if (drag_ == DRAG_POS_LM) + { + valid_x(x, true); + user_sel_.left = x; + dif = x_; + x_ = pos_2_area(x, true); + w_ -= x_ - dif; + } + else if (drag_ == DRAG_POS_RM) + { + valid_x(x, false); + user_sel_.right = x; + w_ = pos_2_area(x, true) - x_; + if (x_ + w_ > paper_w_) + w_ = paper_w_ - x_; + } + else if (drag_ == DRAG_POS_LB) + { + valid_x(x, true); + valid_y(y, false); + user_sel_.left = x; + user_sel_.bottom = y; + dif = x_; + x_ = pos_2_area(x, true); + w_ -= x_ - dif; + h_ = pos_2_area(y, false) - y_; + } + else if (drag_ == DRAG_POS_MB) + { + valid_y(y, false); + user_sel_.bottom = y; + h_ = pos_2_area(y, false) - y_; + if (y_ + h_ > paper_h_) + h_ = paper_h_ - y_; + } + else if (drag_ == DRAG_POS_RB) + { + valid_x(x, false); + valid_y(y, false); + user_sel_.right = x; + user_sel_.bottom = y; + w_ = pos_2_area(x, true) - x_; + if (x_ + w_ > paper_w_) + w_ = paper_w_ - x_; + h_ = pos_2_area(y, false) - y_; + if (y_ + h_ > paper_h_) + h_ = paper_h_ - y_; + } + else if (drag_ == DRAG_POS_MOVE) + { + x += move_.x; + y += move_.y; + OffsetRect(&user_sel_, x - user_sel_.left, y - user_sel_.top); + if (user_sel_.left < whole_.left) + OffsetRect(&user_sel_, whole_.left - user_sel_.left, 0); + if (user_sel_.right > whole_.right) + OffsetRect(&user_sel_, whole_.right - user_sel_.right, 0); + if (user_sel_.top < whole_.top) + OffsetRect(&user_sel_, 0, whole_.top - user_sel_.top); + if (user_sel_.bottom > whole_.bottom) + OffsetRect(&user_sel_, 0, whole_.bottom - user_sel_.bottom); + x_ = pos_2_area(user_sel_.left, true); + if (x_ + w_ > paper_w_) + x_ = paper_w_ - w_; + y_ = pos_2_area(user_sel_.top, false); + if (y_ + h_ > paper_h_) + y_ = paper_h_ - h_; + } + + refresh_paper_info(); + InvalidateRect(hwnd(), &whole_, FALSE); + return; + } + + POINT pt = { x, y }; + std::vector r; + bool handled = false; + + drag_blocks(r); + for (size_t i = 0; i < r.size(); ++i) + { + if (PtInRect(&r[i], pt)) + { + handled = true; + if (r[i].pos == DRAG_POS_LT || r[i].pos == DRAG_POS_RB) + cursor_ = IDC_SIZENWSE; + else if(r[i].pos == DRAG_POS_RT || r[i].pos == DRAG_POS_LB) + cursor_ = IDC_SIZENESW; + else if(r[i].pos == DRAG_POS_MT || r[i].pos == DRAG_POS_MB) + cursor_ = IDC_SIZENS; + else + cursor_ = IDC_SIZEWE; + + drag_ = r[i].pos; + SetCursor(LoadCursor(NULL, cursor_)); + break; + } + } + if (!handled) + { + if (PtInRect(&user_sel_, pt)) + { + drag_ = DRAG_POS_MOVE; + cursor_ = IDC_SIZEALL; + SetCursor(LoadCursor(NULL, cursor_)); + } + else + { + drag_ = DRAG_POS_NONE; + cursor_ = NULL; + } + } +} +void dlg_area::on_lbutton_down(int x, int y) +{ + move_.x = user_sel_.left - x; + move_.y = user_sel_.top - y; + if (cursor_) + SetCursor(LoadCursorW(NULL, cursor_)); + SetCapture(hwnd()); +} +void dlg_area::on_lbutton_up(int x, int y) +{ + drag_ = DRAG_POS_NONE; + cursor_ = NULL; + ReleaseCapture(); +} + + +void dlg_area::set_paper(const wchar_t* name, float width_mm, float height_mm, float dpi) +{ + wchar_t paper[40] = { 0 }; + + dpi_ = dpi; + paper_ = name; + + paper_w_0_ = width_mm; + paper_h_0_ = height_mm; + + if (unit_ == PAPER_UNIT_INCH) + { + paper_w_ = dlg_area::mm_2_inches(width_mm); + paper_h_ = dlg_area::mm_2_inches(height_mm); + } + else if (unit_ == PAPER_UNIT_PIXEL) + { + paper_w_ = dlg_area::mm_2_pixel(width_mm, dpi_); + paper_h_ = dlg_area::mm_2_pixel(height_mm, dpi_); + } + else + { + paper_w_ = width_mm; + paper_h_ = height_mm; + } + + RECT r = { 0 }; + float xr = 1.0f, + yr = 1.0f; + + GetWindowRect(get_item(IDC_STATIC_PAINT), &r); + screen_2_client(&r); + xr = paper_w_0_ / (r.right - r.left); + yr = paper_h_0_ / (r.bottom - r.top); + ratio_ = xr >= yr ? xr : yr; + + xr = paper_w_0_ / ratio_; + xr = (r.right - r.left - xr) / 2; + yr = paper_h_0_ / ratio_; + yr = (r.bottom - r.top - yr) / 2; + whole_.left = r.left + xr; whole_.right = r.right - xr; + whole_.top = r.top + yr; whole_.bottom = r.bottom - yr; + + clear_area(); +} +void dlg_area::set_area(int x, int y, int w, int h) +{ + x_ = x; + y_ = y; + w_ = w; + h_ = h; + + if (x_ > paper_w_) + { + if (w_ < paper_w_) + x_ = paper_w_ - w_; + else + x_ = 0; + } + if (w_ + x_ > paper_w_) + w_ = paper_w_ - x_; + if (y_ > paper_h_) + { + if (h_ < paper_h_) + y_ = paper_h_ - h_; + else + y_ = 0; + } + if (h_ + y_ > paper_h_) + h_ = paper_h_ - y_; + + refresh_paper_info(); +} +int dlg_area::do_modal(HWND parent) +{ + BOOL enable_parent = FALSE, + got = TRUE; + MSG msg = { 0 }; + + if (IsWindow(parent) && parent != GetDesktopWindow()) + { + EnableWindow(parent, FALSE); + enable_parent = TRUE; + } + + ShowWindow(hwnd(), SW_SHOW); + while ((got = GetMessage(&msg, NULL, 0, 0))) + { + if ((DWORD)got == -1) + break; + + //if (enable_parent && msg.hwnd == parent && + // msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST && + // msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) + // continue; + + TranslateMessage(&msg); + DispatchMessage(&msg); + if (exit_code_ == IDOK || exit_code_ == IDCANCEL) + break; + } + ShowWindow(hwnd(), SW_HIDE); + + if (enable_parent) + { + EnableWindow(parent, TRUE); + } + + return exit_code_; +} +int dlg_area::x_in_mm(void) +{ + return as_mm(x_); +} +int dlg_area::y_in_mm(void) +{ + return as_mm(y_); +} +int dlg_area::w_in_mm(void) +{ + return as_mm(w_); +} +int dlg_area::h_in_mm(void) +{ + return as_mm(h_); +} diff --git a/sane/DlgArea.h b/sane/DlgArea.h new file mode 100644 index 0000000..048d6be --- /dev/null +++ b/sane/DlgArea.h @@ -0,0 +1,98 @@ +#pragma once + +#include +#include + +#include "DlgPage.h" + +// CDlgIndicator 对话框 + +class dlg_area: public dlg_base +{ + enum paper_unit + { + PAPER_UNIT_MM = 0, + PAPER_UNIT_INCH, + PAPER_UNIT_PIXEL, + }; + enum drag_pos + { + DRAG_POS_NONE = 0, + DRAG_POS_LT, + DRAG_POS_MT, + DRAG_POS_RT, + DRAG_POS_LM, + DRAG_POS_RM, + DRAG_POS_LB, + DRAG_POS_MB, + DRAG_POS_RB, + DRAG_POS_MOVE, + }; + typedef struct _drag_block : RECT + { + drag_pos pos; + }DRAGRECT; + std::wstring paper_; + paper_unit unit_; + float paper_w_0_; + float paper_h_0_; + float paper_w_; + float paper_h_; + float dpi_; + float x_; + float y_; + float w_; + float h_; + int exit_code_; + + RECT whole_; + RECT user_sel_; + float ratio_; // mm / pixel + drag_pos drag_; + POINT move_; + bool in_set_func_; + const wchar_t* cursor_; + + static int area_min_pixel; + + BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; + void handle_command(WORD code, WORD id, HANDLE ctrl); + + float as_mm(float v); + float as_inches(float v); + float as_pixels(float v); + std::wstring format_number(float v); + void refresh_paper_info(void); + void to_unit(paper_unit unit); + void clear_area(void); + void drag_blocks(std::vector& blocks); + float pos_2_area(int val, bool x); + void valid_x(int& x, bool left); + void valid_y(int& y, bool top); + + void on_unit_changed(HWND wnd); + void on_paint(HDC hdc); + void on_mouse_move(DWORD key, int x, int y); + void on_lbutton_down(int x, int y); + void on_lbutton_up(int x, int y); + +public: + dlg_area(HWND parent); + ~dlg_area(); + + static float mm_2_pixel(float mm, float dpi); + static float mm_2_inches(float mm); + static float inches_2_pixel(float inch, float dpi); + static float inches_2_mm(float inch); + static float pixel_2_mm(float px, float dpi); + static float pixel_2_inches(float px, float dpi); + +public: + void set_paper(const wchar_t* name, float width_mm, float height_mm, float dpi); + void set_area(int x, int y, int w, int h); + int do_modal(HWND parent); // return IDOK or IDCANCEL + int x_in_mm(void); + int y_in_mm(void); + int w_in_mm(void); + int h_in_mm(void); +}; diff --git a/sane/DlgIndicator.cpp b/sane/DlgIndicator.cpp index 10eb7d1..19926e8 100644 --- a/sane/DlgIndicator.cpp +++ b/sane/DlgIndicator.cpp @@ -94,7 +94,7 @@ BOOL dlg_indicator::handle_message(UINT msg, WPARAM wp, LPARAM lp) if (wp == 1) { KillTimer(hwnd_, wp); - notify_over(); + notify_over(false); break; } default: @@ -108,16 +108,16 @@ void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl) { if (id == IDCANCEL) { - notify_over(); + notify_over(true); } } -void dlg_indicator::notify_over(void) +void dlg_indicator::notify_over(bool cancel) { if (notify_) - notify_(true, notify_param_); + notify_(cancel ? UI_EVENT_CLOSE_CANCEL : UI_EVENT_CLOSE_NORMAL, notify_param_); } -void dlg_indicator::set_quit_notify(void(__stdcall* notify)(bool, void*), void* param) +void dlg_indicator::set_quit_notify(void(__stdcall* notify)(ui_event, void*), void* param) { notify_ = notify; notify_param_ = param; @@ -161,7 +161,7 @@ void dlg_indicator::notify_scan_over(const char* msg, bool err) if (!PostMessage(hwnd_, WM_SCAN_FINISHED, (WPARAM)mstr, (LPARAM)err)) { delete mstr; - notify_over(); + notify_over(false); } } // CDlgIndicator 消息处理程序 diff --git a/sane/DlgIndicator.h b/sane/DlgIndicator.h index c42c3e7..2dfaea1 100644 --- a/sane/DlgIndicator.h +++ b/sane/DlgIndicator.h @@ -12,19 +12,19 @@ class dlg_indicator : public dlg_base unsigned int papers_; unsigned int images_; bool err_; - void(__stdcall* notify_)(bool, void*); + void(__stdcall* notify_)(ui_event, void*); void* notify_param_; BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; void handle_command(WORD code, WORD id, HANDLE ctrl); - void notify_over(void); + void notify_over(bool cancel); public: dlg_indicator(HWND parent); ~dlg_indicator(); public: - void set_quit_notify(void(__stdcall* notify)(bool cancel, void*), void* param); + void set_quit_notify(void(__stdcall* notify)(ui_event uev, void*), void* param); HWND window(void); HWND parent(void); void show(void); diff --git a/sane/DlgPage.cpp b/sane/DlgPage.cpp index de53806..87108d0 100644 --- a/sane/DlgPage.cpp +++ b/sane/DlgPage.cpp @@ -4,6 +4,7 @@ #include "DlgPage.h" #include "resource.h" #include "scanned_img.h" // for local_trans +#include "DlgArea.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -11,9 +12,12 @@ #define IS_STR_EQUAL(s1, s2) (wcscmp(s1, s2) == 0) #define IS_EDIT(cls) IS_STR_EQUAL(cls, WC_EDITW) #define IS_COMBOX(cls) IS_STR_EQUAL(cls, WC_COMBOBOXW) +#define IS_BUTTON(cls) IS_STR_EQUAL(cls, WC_BUTTONW) #define IS_TRACKBAR(cls) IS_STR_EQUAL(cls, TRACKBAR_CLASSW) #define IS_UPDOWN_ARROW(cls) IS_STR_EQUAL(cls, UPDOWN_CLASSW) +static IMPLEMENT_OPTION_STRING_COMPARE(is_sane_opt); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // dlg_base 对话框 extern HMODULE g_my_inst; @@ -157,6 +161,8 @@ dlg_page::dlg_page(HWND parent, const wchar_t* name , LPSANEAPI api, SANE_Handle dev) : dlg_base(parent, IDD_PAGE), name_(name ? name : L""), ctrl_id_(0) , sane_(*api), dev_(dev), done_(false) + , id_custom_area_(-1), id_custom_left_(-1), id_custom_right_(-1), id_custom_top_(-1), id_custom_bottom_(-1) + , id_custom_gamma_(-1), id_paper_(-1), paper_(L"A4"), id_dpi_(-1), dpi_(200) { size_.cx = size_.cy = 0; pos_.x = 12; @@ -498,6 +504,42 @@ void dlg_page::handle_command(WORD code, WORD id, HANDLE ctrl) { return; } + if (IS_BUTTON(cls)) + { + HWND host = (HWND)GetPropW((HWND)ctrl, dlg_page::property_host.c_str()); + if (IsWindow(host)) + { + if (id == dlg_page::dyn_id_base + id_custom_area_) + { + unsigned int size = 0; + std::string utf8(local_trans::u2a(paper_.c_str(), CP_UTF8)); + dlg_area dlg(hwnd()); + + sane_.sane_io_control_api(dev_, IO_CTRL_CODE_GET_PAPER_SIZE, &utf8[0], &size); + dlg.set_paper(paper_.c_str(), (float)(size & 0x0ffff), float(size >> 16), dpi_); + if (dlg.do_modal(hwnd()) == IDOK) + { + SANE_Fixed val = SANE_FIX(dlg.x_in_mm()); + SANE_Int after = 0; + sane_.sane_control_option_api(dev_, id_custom_left_, SANE_ACTION_SET_VALUE, &val, &after); + + val = SANE_FIX(dlg.y_in_mm()); + sane_.sane_control_option_api(dev_, id_custom_top_, SANE_ACTION_SET_VALUE, &val, &after); + + val = SANE_FIX(dlg.x_in_mm() + dlg.w_in_mm()); + sane_.sane_control_option_api(dev_, id_custom_right_, SANE_ACTION_SET_VALUE, &val, &after); + + val = SANE_FIX(dlg.y_in_mm() + dlg.h_in_mm()); + sane_.sane_control_option_api(dev_, id_custom_bottom_, SANE_ACTION_SET_VALUE, &val, &after); + } + return; + } + else if (id == dlg_page::dyn_id_base + id_custom_gamma_) + { + return; + } + } + } control_action((HWND)ctrl); } @@ -613,16 +655,23 @@ void dlg_page::set_ctrl_value(HWND ctrl, SANE_Value_Type type, void* val, bool o { bool finish = done_; wchar_t cls[128] = { 0 }; - int(__cdecl * cmpstr)(const wchar_t*, const wchar_t*) = wcscmp; GetClassNameW(ctrl, cls, _countof(cls) - 1); done_ = false; - if (cmpstr(cls, WC_BUTTONW) == 0) + if (IS_BUTTON(cls)) { if (type == SANE_TYPE_BOOL) - SendMessage(ctrl, BM_SETCHECK, *(SANE_Bool*)val == SANE_TRUE ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); + { + DWORD id = GetWindowLong(ctrl, GWL_ID); + HWND host = (HWND)GetPropW(ctrl, dlg_page::property_host.c_str()); + + if (IsWindow(host) && (id == id_custom_area_ || id == id_custom_gamma_)) + EnableWindow(ctrl, *(SANE_Bool*)val == SANE_TRUE); + else + SendMessage(ctrl, BM_SETCHECK, *(SANE_Bool*)val == SANE_TRUE ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); + } } - else if (cmpstr(cls, TRACKBAR_CLASSW) == 0) + else if (IS_TRACKBAR(cls)) { if (type == SANE_TYPE_INT) SendMessage(ctrl, TBM_SETPOS, 1, (LPARAM)*(SANE_Int*)val); @@ -632,7 +681,7 @@ void dlg_page::set_ctrl_value(HWND ctrl, SANE_Value_Type type, void* val, bool o SendMessage(ctrl, TBM_SETPOS, TRUE, (LPARAM)int(pos * 100.0f + .5f)); } } - else if (cmpstr(cls, WC_EDITW) == 0 || cmpstr(cls, WC_COMBOBOXW) == 0) + else if (IS_EDIT(cls) || IS_COMBOX(cls)) { wchar_t buf[40] = { 0 }; std::wstring text(L""); @@ -655,7 +704,7 @@ void dlg_page::set_ctrl_value(HWND ctrl, SANE_Value_Type type, void* val, bool o else SendMessageW(ctrl, CB_SELECTSTRING, 0, (LPARAM)text.c_str()); } - else if (cmpstr(cls, UPDOWN_CLASSW) == 0) + else if (IS_UPDOWN_ARROW(cls)) { if (type == SANE_TYPE_INT) { @@ -726,6 +775,16 @@ void dlg_page::control_action(HWND wnd) done_ = false; set_ctrl_value(wnd, type, val, false, !(after || statu)); done_ = true; + if (id == dlg_page::dyn_id_base + id_dpi_) + { + if (type == SANE_TYPE_FIXED) + dpi_ = SANE_UNFIX(*(SANE_Fixed*)val); + else + dpi_ = (float)(int)*(SANE_Int*)val; + } + else if (id == dlg_page::dyn_id_base + id_paper_) + paper_ = local_trans::a2u((char*)val, CP_UTF8); + if (after || statu) PostMessage(parent_, WM_REFRESH_OPTION, id - dlg_page::dyn_id_base, 0); free_ctrl_value(val); @@ -776,34 +835,77 @@ bool dlg_page::add_control(int sn, const SANE_Option_Descriptor* desc, void* cur , {SANE_TYPE_STRING, &dlg_page::create_control_string} , {SANE_TYPE_BUTTON, &dlg_page::create_control_button} }; - for (int i = 0; i < _countof(creat); ++i) + if (is_sane_opt(OPTION_TITLE_SMQYZCmm, desc->title)) + id_custom_left_ = sn; + else if (is_sane_opt(OPTION_TITLE_SMQYSCmm, desc->title)) + id_custom_top_ = sn; + else if (is_sane_opt(OPTION_TITLE_SMQYXCmm, desc->title)) + id_custom_bottom_ = sn; + else if (is_sane_opt(OPTION_TITLE_SMQYYCmm, desc->title)) + id_custom_right_ = sn; + else { - if (creat[i].sane_type == desc->type) + for (int i = 0; i < _countof(creat); ++i) { - std::wstring title(local_trans::a2u(desc->title, CP_UTF8)); - HDC hdc = GetWindowDC(hwnd()); - SIZE text = { 0 }; - HWND wnd = NULL; - int pos = ctrls_.size(); - - GetTextExtentPointW(hdc, title.c_str(), title.length(), &text); - ReleaseDC(hwnd(), hdc); - wnd = (this->*creat[i].func)(sn, desc, cur_val, title.c_str(), &text); - ret = IsWindow(wnd); - if (ret) + if (creat[i].sane_type == desc->type) { - SetPropW(wnd, dlg_page::property_type.c_str(), (HANDLE)creat[i].sane_type); - SetPropW(wnd, dlg_page::property_size.c_str(), (HANDLE)desc->size); - if (desc->cap & SANE_CAP_INACTIVE) + std::wstring title(local_trans::a2u(desc->title, CP_UTF8)); + HDC hdc = GetWindowDC(hwnd()); + SIZE text = { 0 }; + HWND wnd = NULL; + int pos = ctrls_.size(); + + GetTextExtentPointW(hdc, title.c_str(), title.length(), &text); + ReleaseDC(hwnd(), hdc); + wnd = (this->*creat[i].func)(sn, desc, cur_val, title.c_str(), &text); + ret = IsWindow(wnd); + if (ret) { - for (; pos < ctrls_.size(); ++pos) - EnableWindow(ctrls_[pos], FALSE); + SetPropW(wnd, dlg_page::property_type.c_str(), (HANDLE)creat[i].sane_type); + SetPropW(wnd, dlg_page::property_size.c_str(), (HANDLE)desc->size); + if (desc->cap & SANE_CAP_INACTIVE) + { + for (; pos < ctrls_.size(); ++pos) + EnableWindow(ctrls_[pos], FALSE); + } + if (is_sane_opt(OPTION_TITLE_ZDYSMQY, desc->title)) + { + // custom area ... + int w = 69; + HWND host = wnd; + + id_custom_area_ = sn; + wnd = CreateWindowW(WC_BUTTONW, L"\u8bbe\u7f6e\u533a\u57df", WS_CHILD | WS_VISIBLE, pos_.x + text.cx, pos_.y - 1, w, text.cy + 3, hwnd(), NULL, g_my_inst, NULL); + text.cx += w + dlg_page::gap_x; + EnableWindow(wnd, (desc->cap & SANE_CAP_INACTIVE) == 0 && *(SANE_Bool*)cur_val == SANE_TRUE); + SetWindowLong(wnd, GWL_ID, dlg_page::dyn_id_base + sn); + SendMessage(wnd, WM_SETFONT, (WPARAM)get_font(), 1); + SetPropW(wnd, dlg_page::property_host.c_str(), host); + ctrls_.push_back(wnd); + } + else if (is_sane_opt(OPTION_TITLE_ZZCC, desc->title)) + { + paper_ = local_trans::a2u((char*)cur_val, CP_UTF8); + id_paper_ = sn; + } + else if (is_sane_opt(OPTION_TITLE_FBL, desc->title)) + { + if (desc->type == SANE_TYPE_FIXED) + dpi_ = SANE_UNFIX(*(SANE_Fixed*)cur_val); + else + dpi_ = (float)(int)*(SANE_Int*)cur_val; + id_dpi_ = sn; + } + else if (is_sane_opt(OPTION_TITLE_QYSDQX, desc->title)) + { + // custom gamma control ... + } + if (size_.cx < pos_.x + text.cx) + size_.cx = pos_.x + text.cx; + pos_.y += text.cy + dlg_page::gap_y; } - if (size_.cx < pos_.x + text.cx) - size_.cx = pos_.x + text.cx; - pos_.y += text.cy + dlg_page::gap_y; + break; } - break; } } size_.cy = pos_.y; @@ -847,6 +949,20 @@ bool dlg_page::refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val break; set_ctrl_value(ctrls_[ind], desc->type, cur_val, true); EnableWindow(ctrls_[ind], (desc->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE); + HWND host = (HWND)GetPropW(ctrls_[ind], dlg_page::property_host.c_str()); + if (IsWindow(host)) + { + BOOL checked = SendMessage(host, BM_GETCHECK, 0, 0) == BST_CHECKED; + checked &= (desc->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE; + if (sn - dlg_page::dyn_id_base == id_custom_area_) + { + EnableWindow(ctrls_[ind], checked); + } + else if (sn - dlg_page::dyn_id_base == id_custom_gamma_) + { + EnableWindow(ctrls_[ind], checked); + } + } } done_ = true; @@ -856,3 +972,34 @@ const wchar_t* dlg_page::name(void) { return name_.c_str(); } + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// compatible_dc +compatible_dc::compatible_dc(HDC src) : src_(src), old_(NULL) +{ + HWND hwnd = WindowFromDC(src); + RECT r = { 0 }; + + if (!IsWindow(hwnd)) + hwnd = GetDesktopWindow(); + GetWindowRect(hwnd, &r); + size_.cx = r.right - r.left; + size_.cy = r.bottom - r.top; + bmp_ = CreateCompatibleBitmap(src, size_.cx, size_.cy); + hdc_ = CreateCompatibleDC(src); + old_ = (HBITMAP)SelectObject(hdc_, bmp_); + BitBlt(hdc_, 0, 0, size_.cx, size_.cy, src, 0, 0, SRCCOPY); +} +compatible_dc::~compatible_dc() +{ + BitBlt(src_, 0, 0, size_.cx, size_.cy, hdc_, 0, 0, SRCCOPY); + SelectObject(hdc_, old_); + DeleteObject(bmp_); + DeleteDC(hdc_); +} + +HDC compatible_dc::get_dc() +{ + return hdc_; +} \ No newline at end of file diff --git a/sane/DlgPage.h b/sane/DlgPage.h index 2482a71..41d3fb1 100644 --- a/sane/DlgPage.h +++ b/sane/DlgPage.h @@ -10,6 +10,13 @@ // CDlgIndicator 对话框 #define WM_REFRESH_OPTION WM_USER + 111 // WPARAM: source option SN, LPARAM: unused now +enum ui_event +{ + UI_EVENT_CLOSE_NORMAL = 0, + UI_EVENT_CLOSE_CANCEL, + UI_EVENT_BEGIN_SCANNING, +}; + extern HMODULE g_my_inst; class dlg_base @@ -54,6 +61,18 @@ class dlg_page : public dlg_base bool done_; std::vector ctrls_; + int id_dpi_; + float dpi_; + int id_paper_; + std::wstring paper_; + + int id_custom_area_; + int id_custom_left_; + int id_custom_right_; + int id_custom_top_; + int id_custom_bottom_; + int id_custom_gamma_; + static std::wstring property_type; static std::wstring property_host; static std::wstring property_size; @@ -100,3 +119,20 @@ public: bool refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val); const wchar_t* name(void); }; + + +class compatible_dc +{ + HBITMAP bmp_; + HBITMAP old_; + HDC hdc_; + HDC src_; + SIZE size_; + +public: + compatible_dc(HDC src); + ~compatible_dc(); + +public: + HDC get_dc(void); +}; \ No newline at end of file diff --git a/sane/DlgSetting.cpp b/sane/DlgSetting.cpp index bc7911d..9e94820 100644 --- a/sane/DlgSetting.cpp +++ b/sane/DlgSetting.cpp @@ -82,11 +82,17 @@ void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl) SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_restore_, SANE_ACTION_SET_VALUE, &after, &after); refresh_controls(id_restore_); } + else if (id == IDC_BUTTON_SCAN) + { + if (sane_api_.sane_start_api(sane_dev_) == SANE_STATUS_GOOD && + notify_) + notify_(UI_EVENT_BEGIN_SCANNING, notify_param_); + } } void dlg_setting::notify_over(void) { if (notify_) - notify_(true, notify_param_); + notify_(UI_EVENT_CLOSE_NORMAL, notify_param_); } void dlg_setting::on_init_dialog(void) { @@ -186,6 +192,9 @@ void dlg_setting::on_init_dialog(void) screen_2_client(&r); MoveWindow(get_item(IDOK), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE); } + if (with_scan_) + ShowWindow(get_item(IDC_BUTTON_SCAN), SW_SHOW); + select_page(0); UpdateWindow(hwnd()); } @@ -321,7 +330,7 @@ void dlg_setting::refresh_controls(int src_sn) } } -void dlg_setting::set_quit_notify(void(__stdcall* notify)(bool, void*), void* param) +void dlg_setting::set_quit_notify(void(__stdcall* notify)(ui_event, void*), void* param) { notify_ = notify; notify_param_ = param; diff --git a/sane/DlgSetting.h b/sane/DlgSetting.h index 2aa2db9..bb9c3ff 100644 --- a/sane/DlgSetting.h +++ b/sane/DlgSetting.h @@ -31,7 +31,7 @@ class dlg_setting : public dlg_base #ifdef USE_SOLE_WIN_THREAD std::unique_ptr thread_; #endif - void(__stdcall* notify_)(bool, void*); + void(__stdcall* notify_)(ui_event, void*); void* notify_param_; BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; @@ -51,7 +51,7 @@ public: ~dlg_setting(); public: - void set_quit_notify(void(__stdcall* notify)(bool cancel, void*), void* param); + void set_quit_notify(void(__stdcall* notify)(ui_event uev, void*), void* param); HWND window(void); HWND parent(void); void show(void); diff --git a/sane/resource.h b/sane/resource.h index 9ce941c..d7cf6cf 100644 --- a/sane/resource.h +++ b/sane/resource.h @@ -5,6 +5,7 @@ #define IDD_INDICATOR 101 #define IDD_SETTING 103 #define IDD_PAGE 105 +#define IDD_AREA 106 #define IDC_EDIT_PAPER 1001 #define IDC_EDIT_IMAGE 1002 #define IDC_STATIC_PAPER 1003 @@ -12,16 +13,23 @@ #define IDC_STATIC_ERR 1005 #define IDC_BUTTON_SCAN 1007 #define IDC_BUTTON_RESTORE 1008 -#define IDC_BUTTON3 1009 +#define IDC_UNIT 1008 #define IDC_BUTTON_HELP 1009 +#define IDC_EDIT_DPI 1010 +#define IDC_BUTTON_RESET 1011 +#define IDC_EDIT_x 1012 +#define IDC_EDIT_y 1013 +#define IDC_EDIT_W 1014 +#define IDC_EDIT_H 1015 +#define IDC_STATIC_PAINT 1016 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_RESOURCE_VALUE 108 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1008 +#define _APS_NEXT_CONTROL_VALUE 1017 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/sane/sane.rc b/sane/sane.rc index 169396a..8e4fa82 100644 --- a/sane/sane.rc +++ b/sane/sane.rc @@ -80,6 +80,32 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN END +IDD_AREA DIALOGEX 0, 0, 229, 229 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION +CAPTION "Զɨ" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + COMBOBOX IDC_UNIT,37,25,69,103,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_EDIT_x,191,64,30,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_y,191,85,30,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_W,191,106,30,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_H,191,127,30,12,ES_AUTOHSCROLL + PUSHBUTTON "ָ",IDC_BUTTON_RESET,172,156,50,14 + DEFPUSHBUTTON "ȷ",IDOK,189,209,33,13 + DEFPUSHBUTTON "ȡ",IDCANCEL,134,209,33,13 + LTEXT "ֽųߴ磺",IDC_STATIC,7,7,41,8 + LTEXT "DPI/Ӣ磩",IDC_STATIC,118,28,70,8 + LTEXT "λ",IDC_STATIC,7,28,25,8 + EDITTEXT IDC_EDIT_PAPER,45,5,177,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EDIT_DPI,187,26,34,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "",IDC_STATIC,173,66,17,8 + LTEXT "ϣ",IDC_STATIC,173,87,17,8 + LTEXT "",IDC_STATIC,173,108,17,8 + LTEXT "ߣ",IDC_STATIC,173,129,17,8 + GROUPBOX "",IDC_STATIC,7,47,215,160 + LTEXT "Static",IDC_STATIC_PAINT,9,60,159,144,NOT WS_VISIBLE | WS_BORDER +END + ///////////////////////////////////////////////////////////////////////////// // @@ -112,6 +138,14 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 126 END + + IDD_AREA, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 222 + TOPMARGIN, 7 + BOTTOMMARGIN, 222 + END END #endif // APSTUDIO_INVOKED @@ -136,6 +170,28 @@ BEGIN 0 END +IDD_AREA AFX_DIALOG_LAYOUT +BEGIN + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_AREA DLGINIT +BEGIN + IDC_UNIT, 0x403, 11, 0 +0xc1ba, 0xd7c3, 0xa8a3, 0x6d6d, 0xa9a3, "\000" + IDC_UNIT, 0x403, 13, 0 +0xa2d3, 0xe7b4, 0xa8a3, 0x6e69, 0x6863, 0xa9a3, "\000" + IDC_UNIT, 0x403, 11, 0 +0xf1cf, 0xd8cb, 0xa8a3, 0x7870, 0xa9a3, "\000" + 0 +END + #endif // (壬й) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/sane/sane.vcxproj b/sane/sane.vcxproj index 72b577b..5308910 100644 --- a/sane/sane.vcxproj +++ b/sane/sane.vcxproj @@ -197,6 +197,7 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$ + @@ -217,6 +218,7 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$ + diff --git a/sane/sane.vcxproj.filters b/sane/sane.vcxproj.filters index bcd0e34..ca66e29 100644 --- a/sane/sane.vcxproj.filters +++ b/sane/sane.vcxproj.filters @@ -54,6 +54,9 @@ sane2twain\UI + + sane2twain\UI + @@ -116,6 +119,9 @@ sane2twain\UI + + sane2twain\UI + diff --git a/sane/scanner.cpp b/sane/scanner.cpp index 8782faa..246e185 100644 --- a/sane/scanner.cpp +++ b/sane/scanner.cpp @@ -115,6 +115,7 @@ scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BAS tmp_path_ += L"imgs"; CreateDirectoryW(tmp_path_.c_str(), NULL); tmp_path_ += L"\\"; + img_fmt_.img_format = SANE_IMAGE_TYPE_BMP; err_ = open(); } @@ -181,9 +182,9 @@ float __stdcall scanner::to_float(SANE_Fixed v) { return SANE_UNFIX(v); } -void __stdcall scanner::ui_callback(bool cancel, void* param) +void __stdcall scanner::ui_callback(ui_event uev, void* param) { - ((scanner*)param)->on_ui_quit(cancel); + ((scanner*)param)->on_ui_quit(uev); } // IRef @@ -196,15 +197,15 @@ COM_API_IMPLEMENT(scanner, long, release(void)) return refer::release(); } -void scanner::on_ui_quit(bool cancel) +void scanner::on_ui_quit(ui_event uev) { - if (cancel) + if (uev == UI_EVENT_CLOSE_CANCEL) stop(); - ui_quit_ = true; + ui_quit_ = uev != UI_EVENT_BEGIN_SCANNING; if (cb_invoker_) { - cb_invoker_(SANE_EVENT_SCAN_FINISHED, NULL, NULL, cb_param_); + cb_invoker_(ui_quit_ ? SANE_EVENT_SCAN_FINISHED : SANE_EVENT_WORKING, NULL, NULL, cb_param_); } } int scanner::open(void) diff --git a/sane/scanner.h b/sane/scanner.h index 0306c86..e2be44d 100644 --- a/sane/scanner.h +++ b/sane/scanner.h @@ -21,7 +21,7 @@ #define EXTENSION_ID_BASE 0x300 - +#include "DlgPage.h" class dlg_indicator; class dlg_setting; @@ -48,7 +48,7 @@ class scanner : public ISaneInvoker, virtual public refer std::unique_ptr indicator_; std::unique_ptr setting_; - void on_ui_quit(bool cancel); + void on_ui_quit(ui_event uev); int open(void); int close(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 float __stdcall to_float(SANE_Fixed v); - static void __stdcall ui_callback(bool cancel, void* param); + static void __stdcall ui_callback(ui_event uev, void* param); public: scanner(SCANNERID id); diff --git a/twain/twain/huagaods.cpp b/twain/twain/huagaods.cpp index ba00ed3..2ceec87 100644 --- a/twain/twain/huagaods.cpp +++ b/twain/twain/huagaods.cpp @@ -2473,6 +2473,10 @@ void huagao_ds::on_scan_event(int sane_event, void* data, unsigned int* len) { notifyCloseCancel(); } + else if (sane_event == SANE_EVENT_WORKING) + { + notifyXferReady(); + } } }