// DlgIndicator.cpp: 实现文件 // #include "DlgSetting.h" #include "resource.h" #include "scanned_img.h" // for local_trans #include "DlgPage.h" #include "gb_json.h" // CDlgIndicator 对话框 #define WM_USB_PACKET_RECEIVED WM_USER + 1 #define WM_IMAGE_RECEIVED WM_USER + 2 #define WM_SCAN_FINISHED WM_USER + 3 // WPARAM: std::string* msg; LPARAM: boo err 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"") { create(); SetWindowTextW(hwnd(), (std::wstring(name) + L" \u8bbe\u7f6e").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**)lp) = cfg_; break; default: ret = FALSE; break; } return ret; } void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl) { 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_) { 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_NORMAL); } 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 (cmp_sane_opt(OPTION_TITLE_BZ, desc->title)) { ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_HELP), SW_SHOW); id_help_ = sn - 1; } else if (cmp_sane_opt(OPTION_TITLE_HFMRSZ, desc->title)) { 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); } GetWindowRect(hwnd(), &r); r.right += size.cx - (rme.right - rme.left); r.bottom += size.cy; MoveWindow(hwnd(), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE); for (int i = 0; page = get_page(i); ++i) { MoveWindow(page->hwnd(), 0, y, size.cx, size.cy - y, TRUE); } 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); 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* 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 消息处理程序