code_twain/sane/DlgSetting.cpp

412 lines
10 KiB
C++

// DlgIndicator.cpp: 实现文件
//
#include "DlgSetting.h"
#include "resource.h"
#include "scanned_img.h" // for local_trans
#include "DlgPage.h"
#include "gb_json.h"
#include "../../sdk/include/lang/app_language.h"
// CDlgIndicator 对话框
static IMPLEMENT_OPTION_STRING_COMPARE(cmp_sane_opt);
dlg_setting::dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name) : dlg_base(parent, IDD_SETTING)
, sane_api_(*api), sane_dev_(dev), with_scan_(with_scan)
, papers_(0), images_(0), err_(false), tab_(NULL), cfg_(NULL), cfg_file_(L"")
{
std::wstring setting(local_trans::a2u(from_default_language("\350\256\276\347\275\256", nullptr), CP_UTF8));
create();
SetWindowTextW(hwnd(), (std::wstring(name) + L" " + setting).c_str());
}
dlg_setting::~dlg_setting()
{
if (IsWindow(tab_))
{
for (int i = 0; i < get_tab_count(); ++i)
{
TCITEMW item = { 0 };
item.mask = TCIF_PARAM;
TabCtrl_GetItem(tab_, i, &item);
if (item.lParam)
delete (dlg_page*)item.lParam;
}
DestroyWindow(tab_);
}
cfg_->end_setting(false);
}
BOOL dlg_setting::handle_message(UINT msg, WPARAM wp, LPARAM lp)
{
wchar_t text[40] = { 0 };
BOOL ret = TRUE;
switch (msg)
{
case WM_INITDIALOG:
on_init_dialog();
break;
case WM_COMMAND:
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
break;
case WM_NOTIFY:
ret = on_notify((int)wp, (LPNMHDR)lp);
break;
case WM_REFRESH_OPTION:
refresh_controls((int)wp);
break;
case WM_GET_CONFIG_OBJ:
*((gb::sane_config_schm**)lp) = cfg_;
break;
default:
ret = FALSE;
break;
}
return ret;
}
void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl)
{
if (id == IDOK)
{
if (cfg_)
cfg_->save_to(NULL);
notify_over();
}
else if (id == IDC_BUTTON_HELP)
{
SANE_Int after = 0;
SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_help_, SANE_ACTION_SET_VALUE, &after, &after);
}
else if (id == IDC_BUTTON_RESTORE)
{
SANE_Int after = 0;
SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_restore_, SANE_ACTION_SET_VALUE, &after, &after);
refresh_controls(id_restore_);
if (cfg_)
{
cfg_->begin_setting(true);
cfg_->end_setting(false);
cfg_->begin_setting();
}
}
else if (id == IDC_BUTTON_SCAN)
{
// enable(false);
notify_ui_event(SANE_EVENT_UI_SCAN_COMMAND);
}
}
void dlg_setting::notify_over(void)
{
notify_ui_event(SANE_EVENT_UI_CLOSE_SETTING);
}
void dlg_setting::on_init_dialog(void)
{
dlg_page* page = NULL;
SANE_Int sn = 1;
SIZE size = { 0 };
RECT r = { 0 }, rme = { 0 };
int y = 0;
const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
while (desc)
{
if (desc->type == SANE_TYPE_GROUP)
{
if (page)
{
dlg_base::get_max_size(size, page->desired_size());
page->add_control_done();
}
page = add_tab(desc->title);
}
else if (page)
{
char* buf = new char[desc->size + 4];
SANE_Int info = 0;
memset(buf, 0, desc->size + 4);
sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info);
page->add_control(sn - 1, desc, buf);
delete[] buf;
}
else if(desc->type == SANE_TYPE_BUTTON)
{
if (strcmp(SANE_STD_OPT_NAME_HELP, desc->name) == 0)
{
ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_HELP), SW_SHOW);
id_help_ = sn - 1;
}
else if (strcmp(SANE_STD_OPT_NAME_RESTORE, desc->name) == 0)
{
ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_RESTORE), SW_SHOW);
id_restore_ = sn - 1;
}
}
desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
}
if (page)
{
dlg_base::get_max_size(size, page->desired_size());
page->add_control_done();
}
if (size.cx || size.cy || IsWindow(tab_))
{
// resize ...
GetClientRect(hwnd(), &rme);
if (size.cx < rme.right - rme.left)
size.cx = rme.right - rme.left;
if (IsWindow(tab_))
{
GetWindowRect(tab_, &r);
y = r.bottom - r.top;
size.cy += y;
r.right = r.left + size.cx;
screen_2_client(&r);
MoveWindow(tab_, r.left, r.top, r.right - r.left, y, TRUE);
}
RECT desk = { 0 };
int diff = 0;
GetClientRect(GetDesktopWindow(), &desk);
GetWindowRect(hwnd(), &r);
r.right += size.cx - (rme.right - rme.left);
r.bottom += size.cy;
if (r.bottom - r.top > desk.bottom - desk.top)
{
diff = (r.bottom - r.top) - (desk.bottom - desk.top) + 100;
r.top = desk.top;
r.bottom = desk.bottom - 100;
}
MoveWindow(hwnd(), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
size.cy -= diff;
for (int i = 0; page = get_page(i); ++i)
{
MoveWindow(page->hwnd(), 0, y, size.cx, size.cy - y, TRUE);
page->set_view_size(size);
}
GetWindowRect(get_item(IDC_BUTTON_SCAN), &r);
OffsetRect(&r, 0, size.cy);
screen_2_client(&r);
MoveWindow(get_item(IDC_BUTTON_SCAN), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
GetWindowRect(get_item(IDC_BUTTON_HELP), &r);
OffsetRect(&r, size.cx - (rme.right - rme.left), size.cy);
screen_2_client(&r);
MoveWindow(get_item(IDC_BUTTON_HELP), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
GetWindowRect(get_item(IDC_BUTTON_RESTORE), &r);
OffsetRect(&r, size.cx - (rme.right - rme.left), size.cy);
screen_2_client(&r);
MoveWindow(get_item(IDC_BUTTON_RESTORE), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
GetWindowRect(get_item(IDOK), &r);
OffsetRect(&r, size.cx - (rme.right - rme.left), size.cy);
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);
if (!dlg_base::is_language_pack_default_code_page())
{
::SetDlgItemTextW(hwnd(), IDC_BUTTON_SCAN, dlg_base::language_from_hz936(L"\u626B\u63CF").c_str());
::SetDlgItemTextW(hwnd(), IDC_BUTTON_RESTORE, dlg_base::language_from_hz936(L"\u6062\u590D\u9ED8\u8BA4\u503C").c_str());
::SetDlgItemTextW(hwnd(), IDC_BUTTON_HELP, dlg_base::language_from_hz936(L"\u5E2E\u52A9").c_str());
::SetDlgItemTextW(hwnd(), IDOK, dlg_base::language_from_hz936(L"\u786E\u5B9A").c_str());
}
select_page(0);
UpdateWindow(hwnd());
}
BOOL dlg_setting::on_notify(int ctrl_id, LPNMHDR pnmh)
{
BOOL ret = TRUE;
if (pnmh->hwndFrom == tab_)
{
if (pnmh->code == TCN_SELCHANGING)
ret = FALSE;
else if (pnmh->code == TCN_SELCHANGE)
select_page(TabCtrl_GetCurSel(tab_));
}
return ret;
}
int dlg_setting::get_tab_count(void)
{
int count = 0;
if (IsWindow(tab_))
count = TabCtrl_GetItemCount(tab_);
return count;
}
dlg_page* dlg_setting::add_tab(const char* utf8_title)
{
std::wstring title(local_trans::a2u(utf8_title, CP_UTF8));
dlg_page *page = new dlg_page(hwnd(), title.c_str(), &sane_api_, sane_dev_);
HFONT font = (HFONT)SendMessage(get_item(IDOK), WM_GETFONT, 0, 0);
LOGFONTW lf = { 0 };
GetObjectW(font, sizeof(lf), &lf);
page->set_font(font);
if (!IsWindow(tab_))
{
HDC hdc = GetWindowDC(hwnd());
SIZE text = { 0 };
GetTextExtentPointW(hdc, title.c_str(), title.length(), &text);
ReleaseDC(hwnd(), hdc);
tab_ = CreateWindowW(L"SysTabControl32", L"pages", WS_CHILD | WS_VISIBLE, 0, 0, 100, text.cy + 6, hwnd(), NULL, g_my_inst, NULL);
SendMessage(tab_, WM_SETFONT, (WPARAM)SendMessage(get_item(IDOK), WM_GETFONT, 0, 0), 1);
SetWindowLong(tab_, GWL_ID, 1234);
ShowWindow(tab_, SW_SHOW);
}
TC_ITEMW item = { 0 };
item.mask = TCIF_PARAM | TCIF_TEXT;
item.lParam = (LPARAM)page;
item.pszText = &title[0];
TabCtrl_InsertItem(tab_, get_tab_count(), &item);
page->hide();
return page;
}
dlg_page* dlg_setting::get_page(int index)
{
dlg_page* page = NULL;
if (IsWindow(tab_) && index >= 0 && index < get_tab_count())
{
TCITEMW item = { 0 };
item.mask = TCIF_PARAM;
TabCtrl_GetItem(tab_, index, &item);
page = (dlg_page*)item.lParam;
}
return page;
}
dlg_page* dlg_setting::get_page(const char* utf8_title)
{
dlg_page* page = NULL;
std::wstring unic(local_trans::a2u(utf8_title, CP_UTF8));
for (int i = 0; i < get_tab_count(); ++i)
{
TCITEMW item = { 0 };
wchar_t buf[80] = { 0 };
item.mask = TCIF_TEXT | TCIF_PARAM;
item.pszText = buf;
item.cchTextMax = _countof(buf) - 1;
TabCtrl_GetItem(tab_, i, &item);
if (unic == buf)
{
page = (dlg_page*)item.lParam;
break;
}
}
return page;
}
dlg_page* dlg_setting::select_page(int index)
{
dlg_page* ret = NULL, *cur = NULL;
for (int i = 0; cur = get_page(i); ++i)
{
if (i == index)
{
ret = cur;
cur->show();
}
else
cur->hide();
}
return ret;
}
void dlg_setting::refresh_controls(int src_sn)
{
int sn = 1;
const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
while (desc)
{
char* buf = new char[desc->size + 8];
SANE_Int info = 0;
dlg_page* page = NULL;
memset(buf, 0, desc->size + 8);
sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info);
for (int i = 0; page = get_page(i); ++i)
{
if (page->refresh(sn - 1, desc, buf))
break;
}
delete[] buf;
desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
}
}
void dlg_setting::set_config(gb::sane_config_schm* cfg, const wchar_t* file)
{
cfg_ = cfg;
cfg_file_ = file;
}
HWND dlg_setting::window(void)
{
return hwnd_;
}
HWND dlg_setting::parent(void)
{
return parent_;
}
//void dlg_setting::show(void)
//{
// RECT rp, r, desk;
//
// if (IsWindow(parent_))
// GetWindowRect(parent_, &rp);
// else
// GetWindowRect(GetDesktopWindow(), &rp);
// GetWindowRect(hwnd_, &r);
// GetWindowRect(GetDesktopWindow(), &desk);
//
// rp.left += (rp.right - rp.left - (r.right - r.left)) / 2;
// rp.top += (rp.bottom - rp.top - (r.bottom - r.top)) / 2;
// if (rp.top > desk.bottom)
// rp.top = desk.bottom - (r.bottom - r.top);
// if (rp.top < desk.top)
// rp.top = desk.top;
// if (rp.left > desk.right)
// rp.left = desk.right - (rp.right - rp.left);
// if (rp.left < desk.left)
// rp.left = desk.left;
// SetWindowPos(hwnd_, HWND_TOPMOST, rp.left, rp.top, r.right - r.left, r.bottom - r.top, SWP_NOSIZE | SWP_SHOWWINDOW);
// UpdateWindow(hwnd_);
//}
void dlg_setting::hide(void)
{
ShowWindow(hwnd_, SW_HIDE);
}
void dlg_setting::notify_scan_over(void)
{
enable(true);
}
// CDlgIndicator 消息处理程序