// 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 对话框 #include "DlgCfgMgr.h" #include "DlgInput.h" #define MENU_CMD_0 ((unsigned short)0x8888) 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::lang_trans_between_hz936(CONST_STRING_SETTING)); create(); SetWindowTextW(hwnd(), (std::wstring(name) + L" " + setting).c_str()); cfg_menu_ = CreatePopupMenu(); InsertMenuW(cfg_menu_, 0, MF_BYPOSITION, MENU_CMD_0, local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_CUR_CFG_AS).c_str()); InsertMenuA(cfg_menu_, 1, MF_BYPOSITION | MF_SEPARATOR, MENU_CMD_0 + 1, ""); } 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_); } gb::sane_config_schm* schm = cfg_->get_scheme(); if (schm) { schm->end_setting(false); schm->release(); } cfg_->save(local_trans::u2a(cfg_file_.c_str()).c_str()); DestroyMenu(cfg_menu_); } 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* schm = cfg_->get_scheme(); if (wp) { if (!schm && *(bool*)wp) { schm = cfg_->create_empty_scheme(true); } else *(bool*)wp = false; } *((gb::sane_config_schm**)lp) = schm; } break; default: ret = FALSE; break; } return ret; } void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl) { if (ctrl == NULL) { // menu command ... if (id == MENU_CMD_0) { // save current scheme as ... gb::sane_config_schm* s = cfg_->get_scheme(); if (!s) s = cfg_->copy_scheme(nullptr); if (s) { std::vector all; std::vector allw; std::wstring cur(local_trans::a2u(s->get_scheme_name().c_str(), CP_UTF8)); dlg_input dlg(hwnd(), cur.c_str()); cfg_->get_all_schemes(all); for (auto& v : all) allw.push_back(local_trans::a2u(v.c_str(), CP_UTF8)); dlg.set_no_repeats(allw); if (dlg.do_modal(hwnd()) == IDOK) { std::string name(local_trans::u2a(dlg.get_value().c_str(), CP_UTF8)); gb::sane_config_schm* n = s->copy(); if (cfg_->add_scheme(n, name.c_str())) { cfg_->select_scheme(name.c_str()); } n->release(); } s->end_setting(true); s->release(); } } else if(id > MENU_CMD_0 + 1) { // config scheme changed ... std::string schm(local_trans::u2a(dlg_base::get_menu_text(cfg_menu_, id - MENU_CMD_0).c_str(), CP_UTF8)); if (cfg_->get_current_scheme_name() != schm) { gb::sane_config_schm* s = cfg_->get_scheme(); if (s) { s->end_setting(false); s->release(); } if (cfg_->select_scheme(schm.c_str())) { s = cfg_->get_scheme(); apply_scheme_(s, apply_param_); if (s) { s->release(); } refresh_controls(-1); // cfg_->save(); } } } } else if (id == IDOK) { 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_) { gb::sane_config_schm* schm = cfg_->get_scheme(); if (schm) { schm->end_setting(false); schm->release(); } cfg_->select_scheme(nullptr); } } else if (id == IDC_BUTTON_SCAN) { // enable(false); notify_ui_event(SANE_EVENT_UI_SCAN_COMMAND); } else if (id == IDC_BUTTON_CONFIG_MGR) { dlg_cfg_mgr dlg(cfg_, hwnd()); dlg.do_modal(hwnd()); if (dlg.is_scheme_changed()) { gb::sane_config_schm* schm = cfg_->get_scheme(); apply_scheme_(schm, apply_param_); if (schm) schm->release(); refresh_controls(-1); } } else if (id == IDC_BUTTON_CONFIG_MENU) { HMENU sub = cfg_menu_; // GetSubMenu(cfg_menu_, 0); int ind = 2; std::vector schemes; while (DeleteMenu(sub, 2, MF_BYPOSITION)); cfg_->get_all_schemes(schemes); for (auto& v : schemes) { UINT flag = MF_BYPOSITION; if (v == cfg_->get_current_scheme_name()) flag |= MF_CHECKED; InsertMenuW(sub, ind, flag, MENU_CMD_0 + ind, local_trans::a2u(v.c_str(), CP_UTF8).c_str()); ind++; } RECT r = { 0 }; GetWindowRect(get_item(IDC_BUTTON_CONFIG_MENU), &r); TrackPopupMenu(cfg_menu_, TPM_LEFTALIGN | TPM_BOTTOMALIGN, r.left, r.top, 0, hwnd(), NULL); } } 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); } offset_item(IDC_BUTTON_SCAN, 0, size.cy); offset_item(IDC_BUTTON_CONFIG_MGR, size.cx - RECT_W(rme), size.cy); offset_item(IDC_BUTTON_CONFIG_MENU, size.cx - RECT_W(rme), size.cy); offset_item(IDC_BUTTON_HELP, size.cx - RECT_W(rme), size.cy); offset_item(IDC_BUTTON_RESTORE, size.cx - RECT_W(rme), size.cy); offset_item(IDOK, size.cx - RECT_W(rme), size.cy); ShowWindow(get_item(IDC_BUTTON_CONFIG_MGR), SW_SHOW); ShowWindow(get_item(IDC_BUTTON_CONFIG_MENU), SW_SHOW); } if (with_scan_) ShowWindow(get_item(IDC_BUTTON_SCAN), SW_SHOW); if (!dlg_base::is_language_pack_default_code_page()) { std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CFG_MANAGER)); ::SetDlgItemTextW(hwnd(), IDC_BUTTON_CONFIG_MGR, title.c_str()); y = set_item_fit_to_text(IDC_BUTTON_CONFIG_MGR); if (y) offset_item(IDC_BUTTON_CONFIG_MGR, -y, 0); ::SetDlgItemTextW(hwnd(), IDC_BUTTON_SCAN, local_trans::lang_trans_between_hz936(CONST_STRING_SCAN).c_str()); ::SetDlgItemTextW(hwnd(), IDC_BUTTON_RESTORE, local_trans::lang_trans_between_hz936(CONST_STRING_RESTORE).c_str()); ::SetDlgItemTextW(hwnd(), IDC_BUTTON_HELP, local_trans::lang_trans_between_hz936(CONST_STRING_HELP).c_str()); ::SetDlgItemTextW(hwnd(), IDOK, local_trans::lang_trans_between_hz936(CONST_STRING_OK).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::scanner_cfg* cfg, const wchar_t* file, void(__stdcall* apply)(gb::sane_config_schm*, void*), void* param) { cfg_ = cfg; cfg_file_ = file; apply_scheme_ = apply; apply_param_ = param; } 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 消息处理程序