增加用户自定义扫描区域设置界面
This commit is contained in:
parent
64c671b6b7
commit
1e762283c6
|
@ -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<DRAGRECT>& 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<DRAGRECT> 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<DRAGRECT> 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_);
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
#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<DRAGRECT>& 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);
|
||||
};
|
|
@ -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 消息处理程序
|
||||
|
|
|
@ -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);
|
||||
|
|
157
sane/DlgPage.cpp
157
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)
|
||||
{
|
||||
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,6 +835,16 @@ 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}
|
||||
};
|
||||
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
|
||||
{
|
||||
for (int i = 0; i < _countof(creat); ++i)
|
||||
{
|
||||
if (creat[i].sane_type == desc->type)
|
||||
|
@ -799,6 +868,38 @@ bool dlg_page::add_control(int sn, const SANE_Option_Descriptor* desc, void* cur
|
|||
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;
|
||||
|
@ -806,6 +907,7 @@ bool dlg_page::add_control(int sn, const SANE_Option_Descriptor* desc, void* cur
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
size_.cy = pos_.y;
|
||||
|
||||
return ret;
|
||||
|
@ -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_;
|
||||
}
|
|
@ -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<HWND> 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);
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -31,7 +31,7 @@ class dlg_setting : public dlg_base
|
|||
#ifdef USE_SOLE_WIN_THREAD
|
||||
std::unique_ptr<std::thread> 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);
|
||||
|
|
|
@ -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
|
||||
|
|
56
sane/sane.rc
56
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
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -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\sane_hg_mdw.cpp" />
|
||||
<ClCompile Include="..\..\code_device\hgsane\sane_option.cpp" />
|
||||
<ClCompile Include="DlgArea.cpp" />
|
||||
<ClCompile Include="DlgIndicator.cpp" />
|
||||
<ClCompile Include="DlgPage.cpp" />
|
||||
<ClCompile Include="DlgSetting.cpp" />
|
||||
|
@ -217,6 +218,7 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$
|
|||
<ClInclude Include="..\..\sdk\include\sane\sanei_debug.h" />
|
||||
<ClInclude Include="..\..\sdk\include\sane\sane_ex.h" />
|
||||
<ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h" />
|
||||
<ClInclude Include="DlgArea.h" />
|
||||
<ClInclude Include="DlgIndicator.h" />
|
||||
<ClInclude Include="DlgPage.h" />
|
||||
<ClInclude Include="DlgSetting.h" />
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
<ClCompile Include="DlgPage.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DlgArea.cpp">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\code_device\hgsane\cJSON.h">
|
||||
|
@ -116,6 +119,9 @@
|
|||
<ClInclude Include="DlgPage.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DlgArea.h">
|
||||
<Filter>sane2twain\UI</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="sane.def">
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<dlg_indicator> indicator_;
|
||||
std::unique_ptr<dlg_setting> 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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue