增加用户自定义扫描区域设置界面

This commit is contained in:
gb 2022-06-23 14:01:28 +08:00
parent 64c671b6b7
commit 1e762283c6
15 changed files with 1152 additions and 53 deletions

732
sane/DlgArea.cpp Normal file
View File

@ -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\u7c73mm");
SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)L"\u82f1\u5bf8inch");
SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)L"\u50cf\u7d20px");
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_);
}

98
sane/DlgArea.h Normal file
View File

@ -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);
};

View File

@ -94,7 +94,7 @@ BOOL dlg_indicator::handle_message(UINT msg, WPARAM wp, LPARAM lp)
if (wp == 1) if (wp == 1)
{ {
KillTimer(hwnd_, wp); KillTimer(hwnd_, wp);
notify_over(); notify_over(false);
break; break;
} }
default: default:
@ -108,16 +108,16 @@ void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl)
{ {
if (id == IDCANCEL) if (id == IDCANCEL)
{ {
notify_over(); notify_over(true);
} }
} }
void dlg_indicator::notify_over(void) void dlg_indicator::notify_over(bool cancel)
{ {
if (notify_) 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_ = notify;
notify_param_ = param; 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)) if (!PostMessage(hwnd_, WM_SCAN_FINISHED, (WPARAM)mstr, (LPARAM)err))
{ {
delete mstr; delete mstr;
notify_over(); notify_over(false);
} }
} }
// CDlgIndicator 消息处理程序 // CDlgIndicator 消息处理程序

View File

@ -12,19 +12,19 @@ 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_)(bool, void*); void(__stdcall* notify_)(ui_event, void*);
void* notify_param_; 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);
void notify_over(void); void notify_over(bool cancel);
public: public:
dlg_indicator(HWND parent); dlg_indicator(HWND parent);
~dlg_indicator(); ~dlg_indicator();
public: 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 window(void);
HWND parent(void); HWND parent(void);
void show(void); void show(void);

View File

@ -4,6 +4,7 @@
#include "DlgPage.h" #include "DlgPage.h"
#include "resource.h" #include "resource.h"
#include "scanned_img.h" // for local_trans #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_STR_EQUAL(s1, s2) (wcscmp(s1, s2) == 0)
#define IS_EDIT(cls) IS_STR_EQUAL(cls, WC_EDITW) #define IS_EDIT(cls) IS_STR_EQUAL(cls, WC_EDITW)
#define IS_COMBOX(cls) IS_STR_EQUAL(cls, WC_COMBOBOXW) #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_TRACKBAR(cls) IS_STR_EQUAL(cls, TRACKBAR_CLASSW)
#define IS_UPDOWN_ARROW(cls) IS_STR_EQUAL(cls, UPDOWN_CLASSW) #define IS_UPDOWN_ARROW(cls) IS_STR_EQUAL(cls, UPDOWN_CLASSW)
static IMPLEMENT_OPTION_STRING_COMPARE(is_sane_opt);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// dlg_base 对话框 // dlg_base 对话框
extern HMODULE g_my_inst; extern HMODULE g_my_inst;
@ -157,6 +161,8 @@ dlg_page::dlg_page(HWND parent, const wchar_t* name
, LPSANEAPI api, SANE_Handle dev) , LPSANEAPI api, SANE_Handle dev)
: dlg_base(parent, IDD_PAGE), name_(name ? name : L""), ctrl_id_(0) : dlg_base(parent, IDD_PAGE), name_(name ? name : L""), ctrl_id_(0)
, sane_(*api), dev_(dev), done_(false) , 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; size_.cx = size_.cy = 0;
pos_.x = 12; pos_.x = 12;
@ -498,6 +504,42 @@ void dlg_page::handle_command(WORD code, WORD id, HANDLE ctrl)
{ {
return; 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); 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_; bool finish = done_;
wchar_t cls[128] = { 0 }; wchar_t cls[128] = { 0 };
int(__cdecl * cmpstr)(const wchar_t*, const wchar_t*) = wcscmp;
GetClassNameW(ctrl, cls, _countof(cls) - 1); GetClassNameW(ctrl, cls, _countof(cls) - 1);
done_ = false; done_ = false;
if (cmpstr(cls, WC_BUTTONW) == 0) if (IS_BUTTON(cls))
{ {
if (type == SANE_TYPE_BOOL) 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) if (type == SANE_TYPE_INT)
SendMessage(ctrl, TBM_SETPOS, 1, (LPARAM)*(SANE_Int*)val); 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)); 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 }; wchar_t buf[40] = { 0 };
std::wstring text(L""); 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 else
SendMessageW(ctrl, CB_SELECTSTRING, 0, (LPARAM)text.c_str()); 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) if (type == SANE_TYPE_INT)
{ {
@ -726,6 +775,16 @@ void dlg_page::control_action(HWND wnd)
done_ = false; done_ = false;
set_ctrl_value(wnd, type, val, false, !(after || statu)); set_ctrl_value(wnd, type, val, false, !(after || statu));
done_ = true; 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) if (after || statu)
PostMessage(parent_, WM_REFRESH_OPTION, id - dlg_page::dyn_id_base, 0); PostMessage(parent_, WM_REFRESH_OPTION, id - dlg_page::dyn_id_base, 0);
free_ctrl_value(val); 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_STRING, &dlg_page::create_control_string}
, {SANE_TYPE_BUTTON, &dlg_page::create_control_button} , {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)); if (creat[i].sane_type == desc->type)
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)
{ {
SetPropW(wnd, dlg_page::property_type.c_str(), (HANDLE)creat[i].sane_type); std::wstring title(local_trans::a2u(desc->title, CP_UTF8));
SetPropW(wnd, dlg_page::property_size.c_str(), (HANDLE)desc->size); HDC hdc = GetWindowDC(hwnd());
if (desc->cap & SANE_CAP_INACTIVE) 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) SetPropW(wnd, dlg_page::property_type.c_str(), (HANDLE)creat[i].sane_type);
EnableWindow(ctrls_[pos], FALSE); 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) break;
size_.cx = pos_.x + text.cx;
pos_.y += text.cy + dlg_page::gap_y;
} }
break;
} }
} }
size_.cy = pos_.y; size_.cy = pos_.y;
@ -847,6 +949,20 @@ bool dlg_page::refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val
break; break;
set_ctrl_value(ctrls_[ind], desc->type, cur_val, true); set_ctrl_value(ctrls_[ind], desc->type, cur_val, true);
EnableWindow(ctrls_[ind], (desc->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE); 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; done_ = true;
@ -856,3 +972,34 @@ const wchar_t* dlg_page::name(void)
{ {
return name_.c_str(); 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_;
}

View File

@ -10,6 +10,13 @@
// CDlgIndicator 对话框 // CDlgIndicator 对话框
#define WM_REFRESH_OPTION WM_USER + 111 // WPARAM: source option SN, LPARAM: unused now #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; extern HMODULE g_my_inst;
class dlg_base class dlg_base
@ -54,6 +61,18 @@ class dlg_page : public dlg_base
bool done_; bool done_;
std::vector<HWND> ctrls_; 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_type;
static std::wstring property_host; static std::wstring property_host;
static std::wstring property_size; static std::wstring property_size;
@ -100,3 +119,20 @@ public:
bool refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val); bool refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
const wchar_t* name(void); 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);
};

View File

@ -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); SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_restore_, SANE_ACTION_SET_VALUE, &after, &after);
refresh_controls(id_restore_); 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) void dlg_setting::notify_over(void)
{ {
if (notify_) if (notify_)
notify_(true, notify_param_); notify_(UI_EVENT_CLOSE_NORMAL, notify_param_);
} }
void dlg_setting::on_init_dialog(void) void dlg_setting::on_init_dialog(void)
{ {
@ -186,6 +192,9 @@ void dlg_setting::on_init_dialog(void)
screen_2_client(&r); screen_2_client(&r);
MoveWindow(get_item(IDOK), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE); 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); select_page(0);
UpdateWindow(hwnd()); 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_ = notify;
notify_param_ = param; notify_param_ = param;

View File

@ -31,7 +31,7 @@ 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_)(bool, void*); void(__stdcall* notify_)(ui_event, void*);
void* notify_param_; void* notify_param_;
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
@ -51,7 +51,7 @@ public:
~dlg_setting(); ~dlg_setting();
public: 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 window(void);
HWND parent(void); HWND parent(void);
void show(void); void show(void);

View File

@ -5,6 +5,7 @@
#define IDD_INDICATOR 101 #define IDD_INDICATOR 101
#define IDD_SETTING 103 #define IDD_SETTING 103
#define IDD_PAGE 105 #define IDD_PAGE 105
#define IDD_AREA 106
#define IDC_EDIT_PAPER 1001 #define IDC_EDIT_PAPER 1001
#define IDC_EDIT_IMAGE 1002 #define IDC_EDIT_IMAGE 1002
#define IDC_STATIC_PAPER 1003 #define IDC_STATIC_PAPER 1003
@ -12,16 +13,23 @@
#define IDC_STATIC_ERR 1005 #define IDC_STATIC_ERR 1005
#define IDC_BUTTON_SCAN 1007 #define IDC_BUTTON_SCAN 1007
#define IDC_BUTTON_RESTORE 1008 #define IDC_BUTTON_RESTORE 1008
#define IDC_BUTTON3 1009 #define IDC_UNIT 1008
#define IDC_BUTTON_HELP 1009 #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 // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #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_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1008 #define _APS_NEXT_CONTROL_VALUE 1017
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

View File

@ -80,6 +80,32 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
END 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 TOPMARGIN, 7
BOTTOMMARGIN, 126 BOTTOMMARGIN, 126
END END
IDD_AREA, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 222
TOPMARGIN, 7
BOTTOMMARGIN, 222
END
END END
#endif // APSTUDIO_INVOKED #endif // APSTUDIO_INVOKED
@ -136,6 +170,28 @@ BEGIN
0 0
END 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 #endif // 中文(简体,中国) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -197,6 +197,7 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$
<ClCompile Include="..\..\code_device\hgsane\main.c" /> <ClCompile Include="..\..\code_device\hgsane\main.c" />
<ClCompile Include="..\..\code_device\hgsane\sane_hg_mdw.cpp" /> <ClCompile Include="..\..\code_device\hgsane\sane_hg_mdw.cpp" />
<ClCompile Include="..\..\code_device\hgsane\sane_option.cpp" /> <ClCompile Include="..\..\code_device\hgsane\sane_option.cpp" />
<ClCompile Include="DlgArea.cpp" />
<ClCompile Include="DlgIndicator.cpp" /> <ClCompile Include="DlgIndicator.cpp" />
<ClCompile Include="DlgPage.cpp" /> <ClCompile Include="DlgPage.cpp" />
<ClCompile Include="DlgSetting.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\sanei_debug.h" />
<ClInclude Include="..\..\sdk\include\sane\sane_ex.h" /> <ClInclude Include="..\..\sdk\include\sane\sane_ex.h" />
<ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h" /> <ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h" />
<ClInclude Include="DlgArea.h" />
<ClInclude Include="DlgIndicator.h" /> <ClInclude Include="DlgIndicator.h" />
<ClInclude Include="DlgPage.h" /> <ClInclude Include="DlgPage.h" />
<ClInclude Include="DlgSetting.h" /> <ClInclude Include="DlgSetting.h" />

View File

@ -54,6 +54,9 @@
<ClCompile Include="DlgPage.cpp"> <ClCompile Include="DlgPage.cpp">
<Filter>sane2twain\UI</Filter> <Filter>sane2twain\UI</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="DlgArea.cpp">
<Filter>sane2twain\UI</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\code_device\hgsane\cJSON.h"> <ClInclude Include="..\..\code_device\hgsane\cJSON.h">
@ -116,6 +119,9 @@
<ClInclude Include="DlgPage.h"> <ClInclude Include="DlgPage.h">
<Filter>sane2twain\UI</Filter> <Filter>sane2twain\UI</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="DlgArea.h">
<Filter>sane2twain\UI</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="sane.def"> <None Include="sane.def">

View File

@ -115,6 +115,7 @@ scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BAS
tmp_path_ += L"imgs"; tmp_path_ += L"imgs";
CreateDirectoryW(tmp_path_.c_str(), NULL); CreateDirectoryW(tmp_path_.c_str(), NULL);
tmp_path_ += L"\\"; tmp_path_ += L"\\";
img_fmt_.img_format = SANE_IMAGE_TYPE_BMP;
err_ = open(); err_ = open();
} }
@ -181,9 +182,9 @@ float __stdcall scanner::to_float(SANE_Fixed v)
{ {
return SANE_UNFIX(v); return SANE_UNFIX(v);
} }
void __stdcall scanner::ui_callback(bool cancel, void* param) void __stdcall scanner::ui_callback(ui_event uev, void* param)
{ {
((scanner*)param)->on_ui_quit(cancel); ((scanner*)param)->on_ui_quit(uev);
} }
// IRef // IRef
@ -196,15 +197,15 @@ COM_API_IMPLEMENT(scanner, long, release(void))
return refer::release(); 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(); stop();
ui_quit_ = true; ui_quit_ = uev != UI_EVENT_BEGIN_SCANNING;
if (cb_invoker_) 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) int scanner::open(void)

View File

@ -21,7 +21,7 @@
#define EXTENSION_ID_BASE 0x300 #define EXTENSION_ID_BASE 0x300
#include "DlgPage.h"
class dlg_indicator; class dlg_indicator;
class dlg_setting; class dlg_setting;
@ -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(bool cancel); void on_ui_quit(ui_event uev);
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(bool cancel, void* param); static void __stdcall ui_callback(ui_event uev, void* param);
public: public:
scanner(SCANNERID id); scanner(SCANNERID id);

View File

@ -2473,6 +2473,10 @@ void huagao_ds::on_scan_event(int sane_event, void* data, unsigned int* len)
{ {
notifyCloseCancel(); notifyCloseCancel();
} }
else if (sane_event == SANE_EVENT_WORKING)
{
notifyXferReady();
}
} }
} }