// DlgCondition.cpp: 实现文件 // #include "stdafx.h" #include "hgjson.h" #include "DlgCondition.h" #include "afxdialogex.h" #include "resource.h" #include "../../../../code_device/sdk/sane_opt_json/simple_logic.h" #include "opt_ui/DlgPage.h" // for u2a // CDlgCondition 对话框 IMPLEMENT_DYNAMIC(CDlgCondition, CDialogEx) CDlgCondition::CDlgCondition(const wchar_t* name, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_CONDITION, pParent) , name_(name ? name : L"") { } CDlgCondition::~CDlgCondition() { } std::wstring CDlgCondition::get_item_text(UINT id) { int l = GetDlgItem(id)->GetWindowTextLengthW(); wchar_t* buf = new wchar_t[l + 4]; l = GetDlgItem(id)->GetWindowTextW(buf, l + 2); buf[l] = 0; std::wstring ret(buf); delete[] buf; return std::move(ret); } std::wstring CDlgCondition::get_value(int range, bool first) { if (range == SANE_CONSTRAINT_STRING_LIST || range == SANE_CONSTRAINT_WORD_LIST) { return get_item_text(first ? IDC_COMBO_VALUE : IDC_COMBO_VALUE2); } else { return get_item_text(first ? IDC_EDIT_VALUE : IDC_EDIT_VALUE2); } } void CDlgCondition::enable_value_controls(bool enable, int range, bool second) { int cmd = enable ? SW_SHOW : SW_HIDE; if (second) { GetDlgItem(IDC_STATIC_AND)->ShowWindow(cmd); if (range == SANE_CONSTRAINT_STRING_LIST || range == SANE_CONSTRAINT_WORD_LIST) { GetDlgItem(IDC_EDIT_VALUE2)->ShowWindow(SW_HIDE); value2_.ShowWindow(cmd); } else { GetDlgItem(IDC_EDIT_VALUE2)->ShowWindow(cmd); value2_.ShowWindow(SW_HIDE); } } else { if (range == SANE_CONSTRAINT_STRING_LIST || range == SANE_CONSTRAINT_WORD_LIST) { GetDlgItem(IDC_EDIT_VALUE)->ShowWindow(SW_HIDE); value_.ShowWindow(cmd); } else { GetDlgItem(IDC_EDIT_VALUE)->ShowWindow(cmd); value_.ShowWindow(SW_HIDE); } } } void CDlgCondition::clear_items(void) { for (int i = 0; i < items_.GetCount(); ++i) { LPOPTITEM opt = (LPOPTITEM)items_.GetItemData(i); if (opt) delete opt; } items_.ResetContent(); } void CDlgCondition::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_COMBO_ITEM, items_); DDX_Control(pDX, IDC_COMBO_LOGIC, oper_); DDX_Control(pDX, IDC_COMBO_VALUE, value_); DDX_Control(pDX, IDC_COMBO_VALUE2, value2_); } BOOL CDlgCondition::OnInitDialog() { CDialogEx::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog enable_value_controls(false, 0); LPOPTITEM data = new OPTITEM; int index = 0; clear_items(); while (!(data->title = item_all_(index++, &data->type, &data->range, &data->name)).empty()) { if (data->type != SANE_TYPE_GROUP) { int ind = items_.AddString(data->title.c_str()); items_.SetItemData(ind, (DWORD_PTR)data); data = new OPTITEM; } } delete data; value_.ResetContent(); SetDlgItemText(IDC_EDIT_CONDITION, condition_.c_str()); return TRUE; // return TRUE unless you set the focus to a control } BEGIN_MESSAGE_MAP(CDlgCondition, CDialogEx) ON_BN_CLICKED(IDOK, &CDlgCondition::OnBnClickedOk) ON_BN_CLICKED(IDC_BUTTON1, &CDlgCondition::OnBnClickedButton1) ON_BN_CLICKED(IDCANCEL, &CDlgCondition::OnBnClickedCancel) ON_CBN_SELCHANGE(IDC_COMBO_ITEM, &CDlgCondition::OnCbnSelchangeComboItem) ON_CBN_SELCHANGE(IDC_COMBO_LOGIC, &CDlgCondition::OnCbnSelchangeComboLogic) END_MESSAGE_MAP() // CDlgCondition 消息处理程序 void CDlgCondition::init_data(std::function item, std::function < std::wstring(const wchar_t*/*name*/, int/*index*/)> value, const wchar_t* data0) { item_all_ = item; item_val_ = value; condition_ = data0 ? data0 : L""; } std::wstring CDlgCondition::get_condition(void) { return condition_; } void CDlgCondition::OnCbnSelchangeComboItem() { // TODO: 在此添加控件通知处理程序代码 LPOPTITEM opt = (LPOPTITEM)items_.GetItemData(items_.GetCurSel()); if (opt->name == name_) { MessageBox(TEXT("Condition can't contains self!")); if (items_.GetCurSel() == 0) items_.SetCurSel(1); else items_.SetCurSel(items_.GetCurSel() - 1); GotoDlgCtrl(&items_); return; } if (opt->range == SANE_CONSTRAINT_STRING_LIST || opt->range == SANE_CONSTRAINT_WORD_LIST || opt->range == SANE_CONSTRAINT_RANGE) { std::wstring val(L""); int ind = 0; value_.ResetContent(); value2_.ResetContent(); while (!(val = item_val_(opt->name.c_str(), ind++)).empty()) { value_.AddString(val.c_str()); value2_.AddString(val.c_str()); } } std::wstring lg(get_item_text(IDC_COMBO_LOGIC)); enable_value_controls(lg != L"enabled" && lg != L"!enabled", opt->range, false); } void CDlgCondition::OnCbnSelchangeComboLogic() { // TODO: 在此添加控件通知处理程序代码 std::wstring oper(get_item_text(IDC_COMBO_LOGIC)); LPOPTITEM opt = (LPOPTITEM)items_.GetItemData(items_.GetCurSel()); if (oper == L"enabled" || oper == L"!enabled") { enable_value_controls(false, opt->range, false); enable_value_controls(false, opt->range); } else { enable_value_controls(true, opt->range, false); if (oper == L"between" || oper == L"out of") enable_value_controls(true, opt->range); } } void CDlgCondition::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 std::wstring name(get_item_text(IDC_COMBO_ITEM)), logic(get_item_text(IDC_COMBO_LOGIC)), val(L""), val2(L""); LPOPTITEM opt = (LPOPTITEM)items_.GetItemData(items_.GetCurSel()); if (logic == L"enabled" || logic == L"!enabled") { name = opt->name + L"." + logic; } else { val = get_value(opt->range, true); if (logic == L"between" || logic == L"out of") { val2 = get_value(opt->range, false); name = opt->name; if (logic == L"between") name += L"==["; else name += L"!=["; name += val + L"," + val2 + L"]"; } else { name = opt->name + logic + val; } if (opt->range == SANE_CONSTRAINT_RANGE) { wchar_t buf[128] = { 0 }; value_.GetLBText(0, buf); if (val < buf) { logic = buf; swprintf_s(buf, _countof(buf) - 1, L"value must not less than '%s'", logic.c_str()); MessageBox(buf); return; } value_.GetLBText(1, buf); if (val2 > buf) { logic = buf; swprintf_s(buf, _countof(buf) - 1, L"value must not greate than '%s'", logic.c_str()); MessageBox(buf); return; } } } val = get_item_text(IDC_EDIT_CONDITION); if (!val.empty()) name.insert(0, val + L" || "); SetDlgItemText(IDC_EDIT_CONDITION, name.c_str()); } void CDlgCondition::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 std::string utf8(""); simple_logic logic; int pos = 0; condition_ = get_item_text(IDC_EDIT_CONDITION); utf8 = local_trans::u2a(condition_.c_str(), CP_UTF8); if (!logic.parse(utf8.c_str(), &pos)) { wchar_t info[128] = { 0 }; swprintf_s(info, _countof(info) - 1, L"Failed at pos %d ('%c')!", pos, utf8[pos]); MessageBox(info, L"Invalid expression", MB_OK); utf8.erase(pos); std::wstring pre(local_trans::a2u(utf8.c_str(), CP_UTF8)); ::SendMessage(GetDlgItem(IDC_EDIT_CONDITION)->m_hWnd, EM_SETSEL, (WPARAM)pre.length(), (LPARAM)pre.length() + 1); condition_ = L""; return; } clear_items(); CDialogEx::OnOK(); } void CDlgCondition::OnBnClickedCancel() { // TODO: 在此添加控件通知处理程序代码 clear_items(); CDialogEx::OnCancel(); }