diff --git a/pc/code_twain/sln/hgjson/CDlgLang.cpp b/pc/code_twain/sln/hgjson/CDlgLang.cpp new file mode 100644 index 0000000..5994538 --- /dev/null +++ b/pc/code_twain/sln/hgjson/CDlgLang.cpp @@ -0,0 +1,1094 @@ +// CDlgLang.cpp: 实现文件 +// + +#include "stdafx.h" +#include "hgjson.h" +#include "afxdialogex.h" +#include "CDlgLang.h" +#include "DlgInput.h" +#include "DlgAddWords.h" + +#include +#include +#include +#include + +#define RESERVED_STR 600 + +namespace sdk_util +{ + INTER_MODULE_CALLBACK(got_str) + { + *((std::string*)param) += std::string(data, len); + + return inter_module_data::SET_RESULT_CONTINUE; + } + INTER_MODULE_CALLBACK(got_wstr) + { + *((std::wstring*)param) += std::wstring((const wchar_t*)data, len / 2); + + return inter_module_data::SET_RESULT_CONTINUE; + } + + uint32_t make_string_id(const wchar_t* str, bool(*is_repeat)(uint32_t, void*), void* param) + { + uint32_t crc = coding_util::crc_32(str, lstrlenW(str) * 2); + + crc &= 0x0ffff; + if (crc <= RESERVED_STR) + crc = RESERVED_STR + 1; + while (is_repeat(crc, param)) + crc++; + + return crc; + } + + void trim_left(std::wstring& str) + { + int i = 0; + + while (str[i] == L' ' || str[i] == L'\t') + i++; + + str.erase(0, i); + } + void trim_right(std::wstring& str) + { + int i = str.length() - 1; + while (i >= 0) + { + if (str[i] == L' ' || str[i] == L'\t') + i--; + else + break; + } + + str.erase(i + 1); + } + unsigned pick_number(const wchar_t* str, const wchar_t** end, int type) + { + int off = 0; + unsigned val = 0; + + if (type == coding_util::NUM_FMT_HEX) + { + for (; off < 4; ++off) + { + val <<= 4; + if (str[off] >= L'0' && str[off] <= L'9') + { + val += str[off] - L'0'; + } + else if (str[off] >= L'a' && str[off] <= L'f') + { + val += str[off] - L'a' + 10; + } + else if (str[off] >= L'A' && str[off] <= L'A') + { + val += str[off] - L'A' + 10; + } + else + { + val >>= 4; + break; + } + } + } + else if (type == coding_util::NUM_FMT_OCT) + { + for (; off < 3; ++off) + { + val <<= 3; + if (str[off] >= L'0' && str[off] <= L'7') + { + val += str[off] - L'0'; + } + else + { + val >>= 3; + break; + } + } + } + + if (end) + *end = str + off; + + return val; + } + void convert_unicode(std::wstring& str) + { + std::wstring conv(L""); + + for (int i = 0; i < str.length(); ++i) + { + if (str[i] == L'\\') + { + const wchar_t* end = NULL; + if (str[i + 1] == L'u') + { + unsigned val = (unsigned)sdk_util::pick_number(str.c_str() + i + 2, &end, coding_util::NUM_FMT_HEX); + if (end - str.c_str() == i + 6) + { + conv.append(1, val); + i += 5; + continue; + } + } + else if (iswdigit(str[i + 1])) + { + char val[4] = { 0 }; + val[0] = (char)sdk_util::pick_number(str.c_str() + i + 1, &end, coding_util::NUM_FMT_OCT); + if (end - str.c_str() == i + 4 && *end == L'\\' && iswdigit(end[1])) + { + val[1] = (char)sdk_util::pick_number(str.c_str() + i + 5, &end, coding_util::NUM_FMT_OCT); + if (end - str.c_str() == i + 8) + { + int off = 8; + if ((val[0] & 0x20) && *end == L'\\' && iswdigit(end[1])) + { + val[2] = (char)sdk_util::pick_number(str.c_str() + i + 9, &end, coding_util::NUM_FMT_OCT); + off += 4; + } + if (end - str.c_str() == i + off) + { + std::wstring oct(L""); + coding_util::utf8_2_unicode(val, got_wstr, &oct); + conv += oct; + i += off - 1; + continue; + } + } + } + } + } + + conv.append(1, str[i]); + } + + str = std::move(conv); + } + + static LANGID g_reserve[] = { {1, 936, "\344\270\255\346\226\207\357\274\210\347\256\200\344\275\223\357\274\211"} // 中文(简体) + , {2, 950, "\344\270\255\346\226\207\357\274\210\347\271\201\344\275\223\357\274\211"} // 中文(繁体) + , {10, 20127, "\350\213\261\350\257\255"} // 英语 + , {20, 855, "\344\277\204\350\257\255"} // 俄语 + , {30, 863, "\346\263\225\350\257\255"} // 法语 + , {40, 1141, "\345\276\267\350\257\255"} // 德语 + , {50, 1144, "\346\204\217\345\244\247\345\210\251\350\257\255"} // 意大利语 + , {60, 932, "\346\227\245\350\257\255"} // 日语 + , {70, 949, "\351\237\251\346\226\207"} // 韩文 + }; + LANGID* lang_info_from_cp(int cp) + { + for (auto& v : g_reserve) + { + if (v.cp == cp) + return &v; + } + + return NULL; + } + LANGID* lang_info_from_ID(int id) + { + for (auto& v : g_reserve) + { + if (v.id == id) + return &v; + } + + return NULL; + } + LANGID* lang_info_from_name(const char* utf8) + { + for (auto& v : g_reserve) + { + if (v.utf8 == utf8) + return &v; + } + + return NULL; + } + int save_2_lang_pak(HWND owner, std::vector& items, int cp, std::string* raw_data, bool to_file) + { + uint32_t len = 0, + crc = 0, + ver = MAKELPARAM(0, 1), + cps[] = { cp, -1}, + self_id = g_reserve[0].id, + off = sizeof(len) + sizeof(crc) + sizeof(ver) + sizeof(cps) + sizeof(self_id), + *ptr = NULL, + repeat = 0, + tmp = 0; + LANGID *info = lang_info_from_cp(cp); + std::string cont(""), str(""); + std::vector known; + + if (!info) + return ERROR_NOT_SUPPORTED; + + self_id = info->id; + +#define APPEND_INT(str, n) \ + str += std::string((char*)&n, sizeof(n)) +#define APPEND_ARRAY(str, n) \ + str += std::string((char*)n, sizeof(n)) + + APPEND_INT(cont, len); + APPEND_INT(cont, crc); + APPEND_INT(cont, ver); + APPEND_ARRAY(cont, cps); + APPEND_INT(cont, self_id); + cont += std::string(info->utf8.c_str(), info->utf8.length() + 1); + if (cont.length() % 16) + cont.append(16 - (cont.length() % 16), '\0'); // ENDING address align 16 before + + len = cont.length(); + off = (items.size() + _countof(g_reserve) + 1) * sizeof(len) * 2; + for (const auto& v : g_reserve) + { + APPEND_INT(cont, v.id); + APPEND_INT(cont, off); + + std::vector::iterator it = std::find(items.begin(), items.end(), v.id); + if (it == items.end()) + { + str += std::string(v.utf8.c_str(), v.utf8.length() + 1); + off += v.utf8.length() + 1; + } + else + { + str += std::string(it->utf8.c_str(), it->utf8.length() + 1); + off += it->utf8.length() + 1; + } + known.push_back(v.id); + } + for (const auto& v : items) + { + if (std::find(known.begin(), known.end(), v.id) == known.end()) + { + APPEND_INT(cont, v.id); + APPEND_INT(cont, off); + str += std::string(v.utf8.c_str(), v.utf8.length() + 1); + off += v.utf8.length() + 1; + } + else + repeat++; + } + + len = -1; + APPEND_INT(cont, len); + APPEND_INT(cont, len); + for (int i = 0; i < repeat; ++i) + { + APPEND_INT(cont, len); + APPEND_INT(cont, len); + } + + cont += std::string(str.c_str(), str.length()); + ptr = (uint32_t*)&cont[0]; + *ptr++ = cont.length(); + *ptr = coding_util::crc_32((const void*)(ptr + 1), cont.length() - 8); + + file_util::PATHFILE file = { 0 }; + tmp = 0; + if (to_file && file_util::browser_file(owner, &file, L"Language pack(*.pak)\0\0", false)) + { + tmp = file_util::save_2_file(cont.c_str(), cont.length(), file.path); + } + + if (raw_data) + *raw_data = std::move(cont); + + return tmp; + } + + bool parse_pak_digest(uint8_t* data, int* id) + { + uint32_t ver = *(uint32_t*)data, + val = 0, + name_id = 0, + * cps = (uint32_t*)(data + sizeof(uint32_t) * 3); + std::vector code_pages; + std::wstring name(L""); + + if (id) + *id = *cps; + while (*cps != -1) + { + code_pages.push_back(*cps++); + } + if (code_pages.empty()) + return false; + + cps++; + name_id = *cps++; + val = (uint8_t*)cps - data; + coding_util::utf8_2_unicode((char*)data + val, got_wstr, &name); + + return name.length() ? true : false; + } + bool parse_pak(uint8_t* data, std::vector& items) + { + uint32_t ver = *(uint32_t*)data, + val = 0, + * cps = (uint32_t*)(data + sizeof(uint32_t) * 3); + + while (*cps++ != -1); + cps++; + val = (uint8_t*)cps - data; + val += strlen((char*)data + val) + 1; + val += 15; + val /= 16; + val *= 16; + + struct + { + uint32_t id; + uint32_t off; + }*go = nullptr; + *((void**)&go) = (void*)(data + val); + while (go->id != -1) + { + LANGIDW l; + l.id = go->id; + coding_util::utf8_2_unicode((char*)data + go->off + val, got_wstr, &l.unic); + items.push_back(l); + go++; + } + + return true; + } + bool load_lang_pak(const wchar_t* file, std::vector& items, int* id) + { + std::string cont(""), name(""); + bool ret = false; + FILE* src = _wfopen(file, L"rb"); + + if (src) + { + int len = 0; + uint8_t* buf = nullptr; + + fseek(src, 0, SEEK_END); + len = ftell(src); + fseek(src, 0, SEEK_SET); + if (len) + { + buf = new uint8_t[len + 4]; + if (buf) + { + memset(buf, 0, len + 4); + len = fread(buf, 1, len, src); + if (len == *(uint32_t*)buf && coding_util::crc_32(buf + sizeof(uint32_t) * 2, len - sizeof(uint32_t) * 2) == ((uint32_t*)buf)[1]) + { + cont = std::string((char*)buf, len); + } + delete[] buf; + } + } + fclose(src); + } + if (cont.length()) + { + parse_pak_digest((uint8_t*)&cont[0], id); + ret = parse_pak((uint8_t*)&cont[0], items); + } + + return ret; + } + + std::wstring get_wnd_text(HWND wnd) + { + int l = GetWindowTextLengthW(wnd); + wchar_t* buf = new wchar_t[l + 4]; + std::wstring ret(L""); + + l = GetWindowTextW(wnd, buf, l + 1); + buf[l] = 0; + ret = buf; + delete[] buf; + + return std::move(ret); + } + std::wstring get_wnd_text(HWND dlg, UINT id) + { + return get_wnd_text(GetDlgItem(dlg, id)); + } + std::wstring load_file(const wchar_t* file, int* bom) + { + std::string raw(""); + std::wstring unic(L""); + + file_util::load_file(file, got_str, &raw); + if (bom) + { + if (coding_util::bom::is_unicode(raw.c_str(), NULL)) + *bom = BOM_UNICODE; + else if (coding_util::bom::is_utf8(raw.c_str())) + *bom = BOM_UTF8; + else + *bom = BOM_ANSI; + } + coding_util::bom::to_unicode(raw.c_str(), raw.length(), got_wstr, &unic); + + return std::move(unic); + } + int save_file(const wchar_t* file, std::wstring& cont, int bom) + { + if (bom == BOM_UTF8) + { + std::string raw(""), bomd(""); + + coding_util::unicode_2_utf8(cont.c_str(), got_str, &raw); + coding_util::bom::from_utf8(raw.c_str(), raw.length(), got_str, &bomd); + + return file_util::save_2_file(bomd.c_str(), bomd.length(), file); + } + else if (bom == BOM_UNICODE) + { + std::string raw(""); + + coding_util::bom::from_unicode(cont.c_str(), cont.length() * 2, got_str, &raw); + + return file_util::save_2_file(raw.c_str(), raw.length(), file); + } + else + { + std::string raw(""); + + coding_util::unicode_2_ansi(cont.c_str(), got_str, &raw); + + return file_util::save_2_file(raw.c_str(), raw.length(), file); + } + } +} + +// CDlgLang 对话框 + +IMPLEMENT_DYNAMIC(CDlgLang, CDialogEx) + +CDlgLang::CDlgLang(CWnd* pParent /*=nullptr*/) + : CDialogEx(IDD_LANGUAGE, pParent) + , cur_cp_(936) +{ + std::vector langs; + + //sdk_util::load_lang_pak(L"D:\\boxroom\\Dingding\\chinese.pak", langs); + langs.clear(); +} + +CDlgLang::~CDlgLang() +{ +} + +void CDlgLang::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO1, lang_); + DDX_Control(pDX, IDC_LIST1, list_); +} +BOOL CDlgLang::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + int ind = 0; + list_.InsertColumn(ind++, TEXT("No."), 0, 48); + list_.InsertColumn(ind++, TEXT("ID"), 0, 60); + list_.InsertColumn(ind++, TEXT("Text"), 0, 350); + list_.SetExtendedStyle(list_.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP); + list_.ModifyStyle(0, LVS_SINGLESEL); + + for (const auto& v : sdk_util::g_reserve) + { + std::wstring unic(L""); + coding_util::utf8_2_unicode(v.utf8.c_str(), sdk_util::got_wstr, &unic); + ind = lang_.AddString(unic.c_str()); + lang_.SetItemData(ind, (DWORD_PTR)v.cp); + } + select_code_page(936); + + return TRUE; // return TRUE unless you set the focus to a control +} +bool CDlgLang::select_code_page(int cp) +{ + bool found = false; + + for (int i = 0; i < lang_.GetCount(); ++i) + { + if ((int)lang_.GetItemData(i) == cp) + { + lang_.SetCurSel(i); + found = true; + break; + } + } + + return found; +} +void CDlgLang::add_2_list(void* lang_list, int id, bool unic) +{ + if (unic) + { + std::vector* data = (std::vector*)lang_list; + + for (const auto& v : *data) + { + std::wstring text(L""); + int ind = find_list_item_by_ID(v.id); + + if (ind == -1) + { + ind = list_.InsertItem(list_.GetItemCount(), std::to_wstring(list_.GetItemCount() + 1).c_str()); + list_.SetItemText(ind, 1, std::to_wstring(v.id).c_str()); + } + list_.SetItemText(ind, 2, v.unic.c_str()); + } + } + else + { + std::vector* data = (std::vector*)lang_list; + + for (const auto& v : *data) + { + std::wstring text(L""); + int ind = find_list_item_by_ID(v.id); + + if (ind == -1) + { + ind = list_.InsertItem(list_.GetItemCount(), std::to_wstring(list_.GetItemCount() + 1).c_str()); + list_.SetItemText(ind, 1, std::to_wstring(v.id).c_str()); + } + coding_util::utf8_2_unicode(v.utf8.c_str(), sdk_util::got_wstr, &text); + list_.SetItemText(ind, 2, text.c_str()); + } + } +} +int CDlgLang::insert_item_2_list(const wchar_t* str, uint32_t id) +{ + int item = 0; + bool ok = false; + wchar_t buf[40] = { 0 }; + + for (; item < list_.GetItemCount(); ++item) + { + list_.GetItemText(item, 1, buf, _countof(buf) - 1); + if (_wtoi(buf) > id) + { + item = list_.InsertItem(item, std::to_wstring(item + 1).c_str()); + ok = true; + break; + } + } + if (ok) + { + for (int i = item + 1; i < list_.GetItemCount(); ++i) + list_.SetItemText(i, 0, std::to_wstring(i + 1).c_str()); + } + else + item = list_.InsertItem(list_.GetItemCount(), std::to_wstring(list_.GetItemCount() + 1).c_str()); + + list_.SetItemText(item, 1, std::to_wstring(id).c_str()); + list_.SetItemText(item, 2, str); + list_.EnsureVisible(item, FALSE); + list_.SetItemState(item, LVNI_FOCUSED | LVIS_SELECTED, LVNI_FOCUSED | LVIS_SELECTED); + GotoDlgCtrl(&list_); + + return item; +} +int CDlgLang::find_hz_ID(const wchar_t* hz) +{ + for (const auto& v : hz_) + { + if (v.hz == hz) + return v.id; + } + + return -1; +} +int CDlgLang::find_list_item_by_ID(int id) +{ + for (int i = 0; i < list_.GetItemCount(); ++i) + { + TCHAR val[40] = { 0 }; + list_.GetItemText(i, 1, val, _countof(val) - 1); + if (_ttoi(val) == id) + return i; + } + + return -1; +} +void CDlgLang::on_hz_pak_initialized(bool success) +{ + lang_.EnableWindow(success); + list_.EnableWindow(success); + GetDlgItem(IDC_BUTTON_SAVE)->EnableWindow(success); + GetDlgItem(IDC_BUTTON_SAVE_EXPORT)->EnableWindow(success); + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(cur_cp_ == 936); + GetDlgItem(IDC_BUTTON_ADD_FILE)->EnableWindow(cur_cp_ == 936); +} +bool CDlgLang::find_repeat_in_vector(uint32_t val, void* param) +{ + std::vector* vec = (std::vector*)param; + + return std::find(vec->begin(), vec->end(), val) != vec->end(); +} +bool CDlgLang::find_repeat_in_list(uint32_t val, void* param) +{ + CListCtrl* lst = (CListCtrl*)param; + wchar_t buf[40] = { 0 }; + + for (int i = 0; i < lst->GetItemCount(); ++i) + { + lst->GetItemText(i, 1, buf, _countof(buf) - 1); + if (_wtoi(buf) == val) + return true; + } + + return false; +} + +BEGIN_MESSAGE_MAP(CDlgLang, CDialogEx) + ON_BN_CLICKED(IDC_BUTTON_INIT_ID, &CDlgLang::OnBnClickedButtonInitId) + ON_CBN_SELCHANGE(IDC_COMBO1, &CDlgLang::OnCbnSelchangeLanguage) + ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CDlgLang::OnNMDblclkList1) + ON_BN_CLICKED(IDC_BUTTON_SAVE, &CDlgLang::OnBnClickedButtonSave) + ON_BN_CLICKED(IDC_BUTTON_ADD, &CDlgLang::OnBnClickedButtonAdd) + ON_BN_CLICKED(IDC_BUTTON_ADD_FILE, &CDlgLang::OnBnClickedButtonAddFile) + ON_BN_CLICKED(IDC_BUTTON_SAVE_EXPORT, &CDlgLang::OnBnClickedButtonSaveExport) + ON_BN_CLICKED(IDC_BUTTON_BATCH_ADD, &CDlgLang::OnBnClickedButtonBatchAdd) +END_MESSAGE_MAP() + + +// CDlgLang 消息处理程序 + + +void CDlgLang::OnBnClickedButtonInitId() +{ + // TODO: 在此添加控件通知处理程序代码 + file_util::PATHFILE file = { 0 }; + std::vector items; + + if (file_util::browser_file(m_hWnd, &file, L"Language Pack (*.pak)\0All Files (*.*)\0\0")) + { + hz_.clear(); + { + file_util::PATHFILE ext = { 0 }; + file_util::file_extension(file.path, &ext); + if (wcsicmp(ext.path, L"pak") == 0) + { + std::vector lans; + int id = 0; + + sdk_util::load_lang_pak(file.path, lans, &id); + if (id != 936) + { + ::MessageBoxW(m_hWnd, L"\u8BF7\u9009\u62E9\u201C\u4E2D\u6587\uFF08\u7B80\u4F53\uFF09\u201D\u7684\u8BED\u8A00\u5305\u4F5C\u4E3A\u521D\u59CB\u5316\u8BED\u8A00\u5305\uFF01", L"\u91CD\u65B0\u9009\u62E9", MB_OK | MB_ICONINFORMATION); + return; + } + cur_cp_ = id; + for (auto& v : lans) + { + HZMAP hm; + hm.id = v.id; + hm.hz = v.unic; + hz_.push_back(hm); + } + list_.DeleteAllItems(); + add_2_list(&lans, cur_cp_, true); + select_code_page(cur_cp_); + on_hz_pak_initialized(true); + return; + } + } + + std::string bom(""), utf8(""); + std::wstring cont(L""), line(L""), save(L""); + size_t pos = -1; + int cur = 0, next = 0; + std::vector ids; + + file_util::load_file(file.path, sdk_util::got_str, &bom); + coding_util::bom::to_unicode(bom.c_str(), bom.length(), sdk_util::got_wstr, &cont); + bom.clear(); + coding_util::pick_line(cont.c_str(), sdk_util::got_wstr, &line, &next); + while (next || !line.empty()) + { + std::wstring cpy(line + L"\r\n"); + + if (!line.empty()) + { + sdk_util::trim_left(line); + pos = line.find(L"//"); + if (pos) + { + pos = line.find(L"#define"); + if (pos == 0) + { + line.erase(0, 7); + sdk_util::trim_left(line); + pos = line.find(L" "); + if(pos == std::wstring::npos) + pos = line.find(L"\t"); + if (pos != std::wstring::npos) + { + std::wstring name = line.substr(0, pos); + line.erase(0, pos + 1); + sdk_util::trim_left(line); + if (line[0] == L'\"') + { + int bgn = 0, end = 0; + if (coding_util::pick_value(line.c_str(), L"\"", L"\"", &bgn, &end)) + { + line.erase(end + 1); + line.erase(0, bgn); + cpy.insert(0, L"// "); + sdk_util::convert_unicode(line); + bgn = sdk_util::make_string_id(line.c_str(), &CDlgLang::find_repeat_in_vector, &ids); + ids.push_back(bgn); + cpy += L"#define ID_" + name + L" " + std::to_wstring(bgn) + L"\r\n\r\n"; + + sdk_util::LANGID li; + li.id = bgn; + coding_util::unicode_2_utf8(line.c_str(), sdk_util::got_str, &li.utf8); + items.push_back(li); + + HZMAP hm; + hm.id = li.id; + hm.hz = line; + hz_.push_back(hm); + } + } + } + } + } + } + save += cpy; + cur += next; + line.clear(); + coding_util::pick_line(cont.c_str() + cur, sdk_util::got_wstr, &line, &next); + } + + coding_util::unicode_2_utf8(save.c_str(), sdk_util::got_str, &utf8); + save.clear(); + coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), sdk_util::got_str, &bom); + utf8.clear(); + file_util::save_2_file(bom.c_str(), bom.length(), file.path); + + std::sort(items.begin(), items.end()); + list_.DeleteAllItems(); + cur_cp_ = 936; + add_2_list(&items, cur_cp_, false); + select_code_page(cur_cp_); + on_hz_pak_initialized(true); + //sdk_util::save_2_lang_pak(m_hWnd, items); + } +} +void CDlgLang::OnCbnSelchangeLanguage() +{ + file_util::PATHFILE file = { 0 }; + int lang_cp = (int)lang_.GetItemData(lang_.GetCurSel()); + + if (file_util::browser_file(m_hWnd, &file)) + { + { + file_util::PATHFILE ext = { 0 }; + file_util::file_extension(file.path, &ext); + if (wcsicmp(ext.path, L"pak") == 0) + { + std::vector lans; + int cp = 0; + + sdk_util::load_lang_pak(file.path, lans, &cp); + if (cp != lang_cp) + { + sdk_util::LANGID* inf = sdk_util::lang_info_from_cp(lang_cp); + std::wstring unic(L""); + + coding_util::utf8_2_unicode(inf->utf8.c_str(), sdk_util::got_wstr, &unic); + unic.insert(0, L"\u8BF7\u9009\u62E9\u201C"); + unic += L"\u201D\u8BED\u8A00\u5305\uFF01"; + ::MessageBoxW(m_hWnd, unic.c_str(), L"Error", MB_OK | MB_ICONSTOP); + select_code_page(cur_cp_); + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(cur_cp_ == 936); + GetDlgItem(IDC_BUTTON_ADD_FILE)->EnableWindow(cur_cp_ == 936); + return; + } + // list_.DeleteAllItems(); + cur_cp_ = cp; + add_2_list(&lans, cur_cp_, true); + select_code_page(cur_cp_); + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(cur_cp_ == 936); + GetDlgItem(IDC_BUTTON_ADD_FILE)->EnableWindow(cur_cp_ == 936); + return; + } + } + + ::MessageBoxW(m_hWnd, L"\u7EAF\u6587\u672C\u7FFB\u8BD1\u5BF9\u7167\uFF0C\u8BF7\u4EE5\u4E2D\u6587\uFF08\u7B80\u4F53\uFF09\u8BED\u8A00\u5728\u7B2C\u4E00\u5217\uFF08\u5982\u6709\u7A7A\u683C\u8BF7\u52A0\u82F1\u6587\u53CC\u5F15\u53F7\uFF09\uFF0C\u5176\u5B83\u8BED\u8A00\u4E3A\u7A7A\u683C\u4EE5\u540E\u7684\u7B2C\u4E8C\u5217\u3002", L"\u63D0\u793A", MB_OK | MB_ICONINFORMATION); + + std::string bom(""); + std::wstring cont(L""), line(L""), hz(L""), lan(L""); + size_t pos = -1; + int cur = 1, next = -1; + std::vector ids; + std::map lost; + + cur_cp_ = lang_cp; + file_util::load_file(file.path, sdk_util::got_str, &bom); + coding_util::bom::to_unicode(bom.c_str(), bom.length(), sdk_util::got_wstr, &cont); + bom.clear(); + while (next || !line.empty()) + { + cur += next; + line.clear(); + coding_util::pick_line(cont.c_str() + cur, sdk_util::got_wstr, &line, &next); + if (line.empty()) + continue; + + sdk_util::trim_left(line); + if (line.empty()) + continue; + + if (line[0] == L'\"') + { + int bgn = 0, end = 0; + coding_util::pick_value(line.c_str(), L"\"", L"\"", &bgn, &end); + if (end <= bgn) + continue; + + hz = line.substr(bgn, end - bgn + 1); + line.erase(0, end + 2); + } + else + { + pos = line.find(L" "); + if (pos > line.find(L"\t")) + pos = line.find(L"\t"); + if (pos == std::wstring::npos) + continue; + hz = line.substr(0, pos); + line.erase(0, pos + 1); + } + sdk_util::trim_left(line); + if (line.empty()) + continue; + + lan = line; + + int id = find_hz_ID(hz.c_str()), + item = id == -1 ? -1 : find_list_item_by_ID(id); + if (item == -1) + lost[hz] = lan; + else + list_.SetItemText(item, 2, lan.c_str()); + } + + cont.clear(); + if (lost.size()) + { + for (auto& v : lost) + cont += L" " + v.first + L" <---> " + v.second + L"\r\n"; + file_util::set_clipboard(cont.c_str(), cont.length() * 2, CF_UNICODETEXT); + cont.insert(0, L"下列语言条目,没有找到中文原版,请在中文(简体)语言包中补充完整(内容已经拷贝到剪贴板):\r\n"); + ::MessageBoxW(m_hWnd, cont.c_str(), L"Lost", MB_OK | MB_ICONERROR); + } + } + else if (lang_cp == 936) + { + cur_cp_ = lang_cp; + list_.DeleteAllItems(); + lang_cp = 1; + for (const auto& v : hz_) + { + int item = list_.InsertItem(list_.GetItemCount(), std::to_wstring(lang_cp++).c_str()); + list_.SetItemText(item, 1, std::to_wstring(v.id).c_str()); + list_.SetItemText(item, 2, v.hz.c_str()); + } + } + else + { + select_code_page(cur_cp_); + } + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(cur_cp_ == 936); + GetDlgItem(IDC_BUTTON_ADD_FILE)->EnableWindow(cur_cp_ == 936); +} +void CDlgLang::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); + *pResult = 0; + + // TODO: 在此添加控件通知处理程序代码 + POINT pos = { 0 }; + int item = -1; + + GetCursorPos(&pos); + list_.ScreenToClient(&pos); + item = list_.HitTest(pos); + if (item != -1) + { + int size = 4 * 1024; + wchar_t* buf = new wchar_t[size]; + CDlgInput dlg; + + memset(buf, 0, size * sizeof(buf[0])); + list_.GetItemText(item, 2, buf, size - 1); + dlg.value_ = buf; + dlg.type_ = CDlgInput::INPUT_FOR_STRING; + delete[] buf; + if (dlg.DoModal() == IDOK) + { + list_.SetItemText(item, 2, dlg.value_); + } + } +} + + +void CDlgLang::OnBnClickedButtonSave() +{ + // TODO: 在此添加控件通知处理程序代码 + std::vector items; + int cp = (int)lang_.GetItemData(lang_.GetCurSel()), size = 1024; + wchar_t* buf = new wchar_t[size]; + + memset(buf, 0, size * sizeof(buf[0])); + for (int i = 0; i < list_.GetItemCount(); ++i) + { + sdk_util::LANGID lan; + + list_.GetItemText(i, 1, buf, size - 1); + lan.id = _wtoi(buf); + list_.GetItemText(i, 2, buf, size - 1); + coding_util::unicode_2_utf8(buf, sdk_util::got_str, &lan.utf8); + lan.cp = cp; + items.push_back(std::move(lan)); + } + delete[] buf; + + if (items.empty()) + { + MessageBox(TEXT("No items need save")); + return; + } + + if (sdk_util::save_2_lang_pak(m_hWnd, items, cp)) + ::MessageBoxW(m_hWnd, L"\u8BF7\u68C0\u67E5\u8DEF\u5F84\u53CA\u6743\u9650\u662F\u5426\u6B63\u5E38?", L"\u4FDD\u5B58\u5931\u8D25", MB_OK); +} + + +void CDlgLang::OnBnClickedButtonAdd() +{ + // TODO: 在此添加控件通知处理程序代码 + CDlgInput dlg; + + dlg.type_ = CDlgInput::INPUT_FOR_STRING; + if (dlg.DoModal() == IDOK) + { + HZMAP h; + + h.hz = dlg.value_.GetBuffer(); + dlg.value_.ReleaseBuffer(); + + h.id = find_hz_ID(h.hz.c_str()); + if (h.id == -1) + { + h.id = sdk_util::make_string_id(h.hz.c_str(), &CDlgLang::find_repeat_in_list, &list_); + + insert_item_2_list(h.hz.c_str(), h.id); + hz_.push_back(h); + } + else + { + MessageBox(TEXT("Existing already.")); + h.id = find_list_item_by_ID(h.id); + list_.EnsureVisible(h.id, FALSE); + list_.SetItemState(h.id, LVNI_FOCUSED | LVIS_SELECTED, LVNI_FOCUSED | LVIS_SELECTED); + GotoDlgCtrl(&list_); + } + } +} + + +void CDlgLang::OnBnClickedButtonAddFile() +{ + // TODO: 在此添加控件通知处理程序代码 + file_util::PATHFILE file = { 0 }; + + if (file_util::browser_file(m_hWnd, &file, L"Text File(*.txt)\0\0")) + { + std::string bom(""); + std::wstring unic(L""), line(L""); + int id = 0, next = 0, same = 0, added = 0, off = 0; + + file_util::load_file(file.path, sdk_util::got_str, &bom); + coding_util::bom::to_unicode(bom.c_str(), bom.length(), sdk_util::got_wstr, &unic); + bom.clear(); + + coding_util::pick_line(unic.c_str(), sdk_util::got_wstr, &line, &next); + while (next) + { + if (!line.empty()) + { + id = find_hz_ID(line.c_str()); + if (id == -1) + { + HZMAP h; + + h.hz = std::move(line); + h.id = sdk_util::make_string_id(h.hz.c_str(), &CDlgLang::find_repeat_in_list, &list_); + insert_item_2_list(h.hz.c_str(), h.id); + hz_.push_back(h); + added++; + } + else + { + same++; + } + } + off += next; + line = L""; + coding_util::pick_line(unic.c_str() + off, sdk_util::got_wstr, &line, &next); + } + + ::MessageBoxW(m_hWnd, (std::wstring(L"新增加 ") + std::to_wstring(added) + L" 个词条,有" + std::to_wstring(same) + L" 个词条重复。").c_str(), L"OK", MB_OK); + } +} + + +void CDlgLang::OnBnClickedButtonSaveExport() +{ + // TODO: 在此添加控件通知处理程序代码 + if (list_.GetItemCount()) + { + std::wstring text(L""); + + for (int i = 0; i < list_.GetItemCount(); ++i) + { + TCHAR buf[512] = { 0 }; + std::wstring l(L""); + + list_.GetItemText(i, 1, buf, _countof(buf) - 1); + l = buf; + if (l.length() < 5) + l.insert(0, 5 - l.length(), L' '); + l += L"\t\t"; + text += l; + + list_.GetItemText(i, 2, buf, _countof(buf) - 1); + text += buf; + text += L"\r\n"; + } + + file_util::set_clipboard(text.c_str(), text.length() * 2, CF_UNICODETEXT); + ::MessageBoxW(m_hWnd, L"文本内容已经拷贝到剪贴板", L"Ok", MB_OK); + } +} + + +void CDlgLang::OnBnClickedButtonBatchAdd() +{ + // TODO: 在此添加控件通知处理程序代码 + CDlgAddWords dlg; + dlg.DoModal(); +} diff --git a/pc/code_twain/sln/hgjson/CDlgLang.h b/pc/code_twain/sln/hgjson/CDlgLang.h new file mode 100644 index 0000000..7fedc3f --- /dev/null +++ b/pc/code_twain/sln/hgjson/CDlgLang.h @@ -0,0 +1,62 @@ +#pragma once +#include "afxdialogex.h" +#include +#include + +// CDlgLang 对话框 + +class CDlgLang : public CDialogEx +{ + DECLARE_DYNAMIC(CDlgLang) + +public: + CDlgLang(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CDlgLang(); + +// 对话框数据 + enum { IDD = IDD_LANGUAGE }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual BOOL OnInitDialog(); + + bool select_code_page(int cp); + void add_2_list(void* lang_list, int id, bool unic); + int insert_item_2_list(const wchar_t* str, uint32_t id); + int find_hz_ID(const wchar_t* hz); + int find_list_item_by_ID(int id); + void on_hz_pak_initialized(bool success); + + static bool find_repeat_in_vector(uint32_t val, void* param); + static bool find_repeat_in_list(uint32_t val, void* param); + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedButtonInitId(); + afx_msg void OnCbnSelchangeLanguage(); + afx_msg void OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult); + CComboBox lang_; + CListCtrl list_; + int cur_cp_; + + typedef struct _base_map + { + int id; + std::wstring hz; + + bool operator==(int i) + { + return id == i; + } + bool operator==(const wchar_t* t) + { + return hz == t; + } + }HZMAP; + std::vector hz_; + afx_msg void OnBnClickedButtonSave(); + afx_msg void OnBnClickedButtonAdd(); + afx_msg void OnBnClickedButtonAddFile(); + afx_msg void OnBnClickedButtonSaveExport(); + afx_msg void OnBnClickedButtonBatchAdd(); +}; diff --git a/pc/code_twain/sln/hgjson/CDlgMain.cpp b/pc/code_twain/sln/hgjson/CDlgMain.cpp new file mode 100644 index 0000000..8d1620f --- /dev/null +++ b/pc/code_twain/sln/hgjson/CDlgMain.cpp @@ -0,0 +1,114 @@ +// CDlgMain.cpp: 实现文件 +// + +#include "stdafx.h" +#include "hgjson.h" +#include "afxdialogex.h" +#include "CDlgMain.h" +#include "resource.h" + +#include "hgjsonDlg.h" +#include "CDlgLang.h" +#include "DlgTwain.h" +#include "DlgOptJson.h" + +// CDlgMain 对话框 + +IMPLEMENT_DYNAMIC(CDlgMain, CDialogEx) + +CDlgMain::CDlgMain(CWnd* pParent /*=nullptr*/) + : CDialogEx(IDD_MAIN, pParent) +{ +#ifndef _WIN32_WCE + EnableActiveAccessibility(); +#endif + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + +} + +CDlgMain::~CDlgMain() +{ +} + +void CDlgMain::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_TAB1, tab_); +} +BOOL CDlgMain::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + LRESULT lret = 0; + CDialogEx* page = new ChgjsonDlg(this); + page->Create(ChgjsonDlg::IDD, this); + insert_page(page, L"\u626B\u63CF\u4EEA\u914D\u7F6E"); + + page = new CDlgLang(this); + page->Create(CDlgLang::IDD, this); + insert_page(page, L"\u8BED\u8A00\u5305\u5236\u4F5C"); + + page = new CDlgTwain(this); + page->Create(CDlgTwain::IDD, this); + insert_page(page, L"TWAIN"); + + page = new CDlgOptJson(this); + page->Create(CDlgOptJson::IDD, this); + insert_page(page, L"Opt-JSON"); + + tab_.SetCurSel(0); + OnTcnSelchangeTab1(NULL, &lret); + + return TRUE; // return TRUE unless you set the focus to a control +} +void CDlgMain::insert_page(CDialogEx* page, const wchar_t* title) +{ + RECT r = { 0 }; + int ind = 0; + TCITEM item = { 0 }; + + GetDlgItem(IDC_STATIC_CHILD)->GetWindowRect(&r); + ScreenToClient(&r); + page->MoveWindow(&r); + page->ShowWindow(SW_HIDE); + + ind = tab_.InsertItem(tab_.GetItemCount(), title); + item.lParam = (LPARAM)page; + item.mask = TCIF_PARAM; + tab_.SetItem(ind, &item); +} + +BEGIN_MESSAGE_MAP(CDlgMain, CDialogEx) + ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CDlgMain::OnTcnSelchangeTab1) + ON_NOTIFY(TCN_SELCHANGING, IDC_TAB1, &CDlgMain::OnTcnSelchangingTab1) +END_MESSAGE_MAP() + + +// CDlgMain 消息处理程序 +void CDlgMain::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) +{ + // TODO: 在此添加控件通知处理程序代码 + *pResult = 0; + TCITEM item = { 0 }; + + item.mask = TCIF_PARAM; + tab_.GetItem(tab_.GetCurSel(), &item); + ((CWnd*)item.lParam)->ShowWindow(SW_SHOW); +} + +void CDlgMain::OnTcnSelchangingTab1(NMHDR* pNMHDR, LRESULT* pResult) +{ + // TODO: 在此添加控件通知处理程序代码 + *pResult = 0; + + TCITEM item = { 0 }; + + item.mask = TCIF_PARAM; + tab_.GetItem(tab_.GetCurSel(), &item); + ((CWnd*)item.lParam)->ShowWindow(SW_HIDE); +} diff --git a/pc/code_twain/sln/hgjson/CDlgMain.h b/pc/code_twain/sln/hgjson/CDlgMain.h new file mode 100644 index 0000000..861290e --- /dev/null +++ b/pc/code_twain/sln/hgjson/CDlgMain.h @@ -0,0 +1,30 @@ +#pragma once +#include "afxdialogex.h" + + +// CDlgMain 对话框 + +class CDlgMain : public CDialogEx +{ + DECLARE_DYNAMIC(CDlgMain) + +public: + CDlgMain(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CDlgMain(); + +// 对话框数据 + enum { IDD = IDD_MAIN }; + +protected: + HICON m_hIcon; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual BOOL OnInitDialog(); + + void insert_page(CDialogEx* page, const wchar_t* title); + + DECLARE_MESSAGE_MAP() +public: + CTabCtrl tab_; + afx_msg void OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnTcnSelchangingTab1(NMHDR* pNMHDR, LRESULT* pResult); +}; diff --git a/pc/code_twain/sln/hgjson/DlgAddWords.cpp b/pc/code_twain/sln/hgjson/DlgAddWords.cpp new file mode 100644 index 0000000..d3bcf83 --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgAddWords.cpp @@ -0,0 +1,441 @@ +// DlgAddWords.cpp: 实现文件 +// + +#include "stdafx.h" +#include "hgjson.h" +#include "afxdialogex.h" +#include "DlgAddWords.h" + + + +// CDlgAddWords 对话框 + +static bool is_id_existing(uint32_t id, void* param) +{ + std::vector* lang = (std::vector*)param; + + return std::find(lang->begin(), lang->end(), (int)id) != lang->end(); +} + +IMPLEMENT_DYNAMIC(CDlgAddWords, CDialogEx) + +CDlgAddWords::CDlgAddWords(CWnd* pParent /*=nullptr*/) + : CDialogEx(IDD_BATCH_ADD_LANG, pParent) +{ + +} + +CDlgAddWords::~CDlgAddWords() +{ +} + +void CDlgAddWords::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST1, words_); +} +BOOL CDlgAddWords::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + int ind = 0; + words_.InsertColumn(ind++, TEXT("No."), 0, 48); + words_.InsertColumn(ind++, TEXT("中文简体"), 0, 168); + words_.InsertColumn(ind++, TEXT("中文繁体"), 0, 168); + words_.InsertColumn(ind++, TEXT("英语"), 0, 250); + words_.SetExtendedStyle(words_.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP); + words_.ModifyStyle(0, LVS_SINGLESEL); + + + return TRUE; // return TRUE unless you set the focus to a control +} +void CDlgAddWords::open_pak(int lan_id) +{ + file_util::PATHFILE file = { 0 }; + + if (file_util::browser_file(m_hWnd, &file, L"PAK file(*.pak)\0All Files(*.*)\0\0")) + { + set_lang_pak_file(file.path, lan_id); + } +} +void CDlgAddWords::set_lang_pak_file(const wchar_t* file, int lan_id) +{ + std::vector lans; + int id = 0; + bool ok = false; + + if (sdk_util::load_lang_pak(file, lans, &id)) + { + if (id == lan_id || lan_id == 0) + { + ok = true; + if (id == 936) + { + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_HZ_PAK, file); + lan_hz_ = std::move(lans); + } + else if (id == 950) + { + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_HZT, file); + lan_hzt_ = std::move(lans); + } + else if (id == 20127) + { + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_ENGLISH, file); + lan_eng_ = std::move(lans); + } + else + ok = false; + } + } + if (!ok && lan_id) + ::MessageBoxW(m_hWnd, file, L"不是指定的语言包", MB_OK | MB_ICONERROR); +} +void CDlgAddWords::set_code_file(const wchar_t* file, bool tip) +{ + std::wstring unic(sdk_util::load_file(file)); + + if (unic.find(L"unsigned char g_chinese[] = {") == std::wstring::npos) + { + if(tip) + ::MessageBoxW(m_hWnd, file, L"不是指定的简体中文语言头文件", MB_OK | MB_ICONERROR); + } + else + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_CODE, file); +} +bool CDlgAddWords::add_words(const wchar_t* pak_file, std::vector& ids, std::string& cont, int lan_id, int src_col, bool init_id) +{ + std::vector prev; + int id = 0; + + if (sdk_util::load_lang_pak(pak_file, prev, &id)) + { + if (id == lan_id) + { + std::vector now; + + for (auto& v : prev) + { + sdk_util::LANGID item; + item.cp = id; + item.id = v.id; + coding_util::unicode_2_utf8(v.unic.c_str(), sdk_util::got_str, &item.utf8); + now.push_back(std::move(item)); + } + + for (int i = 0; i < words_.GetItemCount(); ++i) + { + wchar_t text[256] = { 0 }; + sdk_util::LANGID item; + + words_.GetItemText(i, src_col, text, _countof(text) - 1); + if (init_id) + { + ids.push_back(sdk_util::make_string_id(text, &is_id_existing, &now)); + } + item.cp = lan_id; + item.id = ids[i]; + coding_util::unicode_2_utf8(text, sdk_util::got_str, &item.utf8); + now.push_back(std::move(item)); + } + + cont = ""; + sdk_util::save_2_lang_pak(m_hWnd, now, lan_id, &cont, false); + + return true; + } + ::MessageBoxW(m_hWnd, L"语言包不匹配", L"错误", MB_OK | MB_ICONSTOP); + } + else + ::MessageBoxW(m_hWnd, pak_file, L"文件加载失败", MB_OK | MB_ICONSTOP); + + return false; +} +bool CDlgAddWords::update_head_file(const wchar_t* file, const std::string& cont) +{ + int bom = sdk_util::BOM_ANSI; + std::wstring code(sdk_util::load_file(file, &bom)), ar(L"unsigned char g_chinese[] = {"); + size_t pos = code.find(L"unsigned char g_chinese[] = {"), end = 0; + + + if (pos == std::wstring::npos) + return false; + + for (int i = 0; i < cont.length(); ++i) + { + unsigned char ch = cont[i]; + wchar_t buf[20] = { 0 }; + + swprintf_s(buf, _countof(buf) - 1, L"0x%02X", ch); + if ((i % 16) == 0) + { + if (i) + ar += L","; + ar += L"\r\n"; + } + else if ((i % 8) == 0) + { + if (i) + ar += L","; + ar += L" "; + } + else if (i) + ar += L", "; + ar += buf; + } + ar += L"\r\n};\r\n"; + + end = code.find(L";", pos); + if (end == std::wstring::npos) + code.erase(pos); + else + code.erase(pos, end - pos + 1); + code.insert(pos, ar); + + ar = file; + file_util::force_move_file(file, (ar + L".bak").c_str()); + bom = sdk_util::save_file(file, code, bom); + if(bom) + file_util::force_move_file((ar + L".bak").c_str(), file); + + return bom == 0; +} + +BEGIN_MESSAGE_MAP(CDlgAddWords, CDialogEx) + ON_BN_CLICKED(IDC_BUTTON_BROWSE_HZ, &CDlgAddWords::OnBnClickedButtonBrowseHz) + ON_BN_CLICKED(IDC_BUTTON_BROWSE_HZT, &CDlgAddWords::OnBnClickedButtonBrowseHzt) + ON_BN_CLICKED(IDC_BUTTON_BROWSE_ENG, &CDlgAddWords::OnBnClickedButtonBrowseEng) + ON_BN_CLICKED(IDC_BUTTON_BROWSE_CODE, &CDlgAddWords::OnBnClickedButtonBrowseCode) + ON_BN_CLICKED(IDC_BUTTON_ADD, &CDlgAddWords::OnBnClickedButtonAdd) + ON_BN_CLICKED(IDC_BUTTON_DEL, &CDlgAddWords::OnBnClickedButtonDel) + ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CDlgAddWords::OnBnClickedButtonClear) + ON_BN_CLICKED(IDC_BUTTON_UPDATE, &CDlgAddWords::OnBnClickedButtonUpdate) + ON_WM_DROPFILES() + ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CDlgAddWords::OnNMDblclkList1) +END_MESSAGE_MAP() + + +// CDlgAddWords 消息处理程序 + +void CDlgAddWords::OnDropFiles(HDROP hDropInfo) +{ + // TODO: 在此添加消息处理程序代码和/或调用默认值 + wchar_t path[MAX_PATH] = { 0 }; + int cnt = DragQueryFileW(hDropInfo, -1, path, _countof(path) - 1); + + for (int i = 0; i < cnt; ++i) + { + int len = DragQueryFileW(hDropInfo, i, path, _countof(path) - 1); + std::wstring file(path, len), ext(file); + + STR_FILE_EXTENSION(ext); + if (wcsicmp(ext.c_str(), L"pak") == 0) + { + set_lang_pak_file(file.c_str()); + } + else if (wcsicmp(ext.c_str(), L"h") == 0) + { + set_code_file(file.c_str(), false); + } + } + + CDialogEx::OnDropFiles(hDropInfo); +} + +void CDlgAddWords::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); + // TODO: 在此添加控件通知处理程序代码 + *pResult = 0; + + wchar_t text[256] = { 0 }; + + words_.GetItemText(pNMItemActivate->iItem, 1, text, _countof(text) - 1); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_HZ_WORD, text); + words_.GetItemText(pNMItemActivate->iItem, 2, text, _countof(text) - 1); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_HZT_WORD, text); + words_.GetItemText(pNMItemActivate->iItem, 3, text, _countof(text) - 1); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_ENG_WORD, text); +} + + +void CDlgAddWords::OnBnClickedButtonBrowseHz() +{ + // TODO: 在此添加控件通知处理程序代码 + open_pak(936); +} + + +void CDlgAddWords::OnBnClickedButtonBrowseHzt() +{ + // TODO: 在此添加控件通知处理程序代码 + open_pak(950); +} + + +void CDlgAddWords::OnBnClickedButtonBrowseEng() +{ + // TODO: 在此添加控件通知处理程序代码 + open_pak(20127); +} + + +void CDlgAddWords::OnBnClickedButtonBrowseCode() +{ + // TODO: 在此添加控件通知处理程序代码 + file_util::PATHFILE file = { 0 }; + + if (file_util::browser_file(m_hWnd, &file, L"Header file(*.h)\0\0")) + { + set_code_file(file.path); + } +} + + +void CDlgAddWords::OnBnClickedButtonAdd() +{ + // TODO: 在此添加控件通知处理程序代码 + std::wstring hz(sdk_util::get_wnd_text(m_hWnd, IDC_EDIT_HZ_WORD)), + hzt(sdk_util::get_wnd_text(m_hWnd, IDC_EDIT_HZT_WORD)), + eng(sdk_util::get_wnd_text(m_hWnd, IDC_EDIT_ENG_WORD)); + wchar_t text[256] = { 0 }; + int item = 0; + + for (int i = 0; i < words_.GetItemCount(); ++i) + { + words_.GetItemText(i, 1, text, _countof(text) - 1); + if (hz == text) + { + ::MessageBoxW(m_hWnd, text, L"词条已经存在", MB_OK | MB_ICONSTOP); + return; + } + } + + item = words_.InsertItem(words_.GetItemCount(), std::to_wstring(words_.GetItemCount() + 1).c_str()); + words_.SetItemText(item, 1, hz.c_str()); + words_.SetItemText(item, 2, hzt.c_str()); + words_.SetItemText(item, 3, eng.c_str()); +} + + +void CDlgAddWords::OnBnClickedButtonDel() +{ + // TODO: 在此添加控件通知处理程序代码 + for (int i = 0; i < words_.GetItemCount(); ++i) + { + if (words_.GetItemState(i, LVIF_STATE) & LVIS_SELECTED) + { + words_.DeleteItem(i--); + } + } + + for (int i = 0; i < words_.GetItemCount(); ++i) + words_.SetItemText(i, 0, std::to_wstring(i + 1).c_str()); +} + + +void CDlgAddWords::OnBnClickedButtonClear() +{ + // TODO: 在此添加控件通知处理程序代码 + words_.DeleteAllItems(); +} + + +void CDlgAddWords::OnBnClickedButtonUpdate() +{ + // TODO: 在此添加控件通知处理程序代码 + if (words_.GetItemCount() == 0) + { + ::MessageBoxW(m_hWnd, L"No words should be added into language packet!", L"None", MB_OK); + return; + } + + std::wstring hzf(sdk_util::get_wnd_text(m_hWnd, IDC_EDIT_HZ_PAK)), + hztf(sdk_util::get_wnd_text(m_hWnd, IDC_EDIT_HZT)), + engf(sdk_util::get_wnd_text(m_hWnd, IDC_EDIT_ENGLISH)), + hf(sdk_util::get_wnd_text(m_hWnd, IDC_EDIT_CODE)); + bool hzb(file_util::is_file_existing(hzf.c_str())), + hztb(file_util::is_file_existing(hztf.c_str())), + engb(file_util::is_file_existing(engf.c_str())), + hb(file_util::is_file_existing(hf.c_str())); + + if (!hzb) + { + ::MessageBoxW(m_hWnd, hzf.c_str(), L"File Not Found", MB_OK | MB_ICONSTOP); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_HZ_PAK)); + return; + } + if (!hztb) + { + ::MessageBoxW(m_hWnd, hztf.c_str(), L"File Not Found", MB_OK | MB_ICONSTOP); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_HZT)); + return; + } + if (!engb) + { + ::MessageBoxW(m_hWnd, hzf.c_str(), L"File Not Found", MB_OK | MB_ICONSTOP); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_ENGLISH)); + return; + } + if (!hb) + { + ::MessageBoxW(m_hWnd, hzf.c_str(), L"File Not Found", MB_OK | MB_ICONSTOP); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_CODE)); + return; + } + + // + std::vector ids; + std::string cont(""); + int err = 0; + + while (add_words(hzf.c_str(), ids, cont, 936, 1, true)) + { + file_util::force_move_file(hzf.c_str(), (hzf + L".bak").c_str()); + err = file_util::save_2_file(cont.c_str(), cont.length(), hzf.c_str()); + if (err) + { + ::MessageBoxW(m_hWnd, hzf.c_str(), L"Write file failed", MB_OK | MB_ICONERROR); + break; + } + + // change head file ... + if (update_head_file(hf.c_str(), cont)) + { + if (add_words(hztf.c_str(), ids, cont, 950, 2)) + { + file_util::force_move_file(hztf.c_str(), (hztf + L".bak").c_str()); + err = file_util::save_2_file(cont.c_str(), cont.length(), hztf.c_str()); + if (err) + { + ::MessageBoxW(m_hWnd, hztf.c_str(), L"Write file failed", MB_OK | MB_ICONERROR); + break; + } + + if (add_words(engf.c_str(), ids, cont, 20127, 3)) + { + file_util::force_move_file(engf.c_str(), (engf + L".bak").c_str()); + err = file_util::save_2_file(cont.c_str(), cont.length(), engf.c_str()); + } + } + else + err = -2; + } + else + { + err = -1; + } + break; + } + + if (err == 0) + ::MessageBoxW(m_hWnd, L"All languages have updated!", L"Congratulation", MB_OK | MB_ICONINFORMATION); + else + { + + } +} + + diff --git a/pc/code_twain/sln/hgjson/DlgAddWords.h b/pc/code_twain/sln/hgjson/DlgAddWords.h new file mode 100644 index 0000000..05df2b9 --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgAddWords.h @@ -0,0 +1,115 @@ +#pragma once +#include "afxdialogex.h" + + +// CDlgAddWords 对话框 + +#include +#include +#include +#include + +namespace sdk_util +{ + typedef struct _lang_id + { + int id; + int cp; + std::string utf8; + + bool operator==(int i) + { + return id == i; + } + bool operator<(struct _lang_id& r) + { + return id < r.id; + } + }LANGID; + typedef struct _lang_id_w + { + int id; + std::wstring unic; + + bool operator==(int i) + { + return id == i; + } + bool operator==(const wchar_t* text) + { + return unic == text; + } + bool operator<(struct _lang_id& r) + { + return id < r.id; + } + }LANGIDW; + + INTER_MODULE_CALLBACK(got_str); + INTER_MODULE_CALLBACK(got_wstr); + uint32_t make_string_id(const wchar_t* str, bool(*is_repeat)(uint32_t, void*), void* param); + void trim_left(std::wstring& str); + void trim_right(std::wstring& str); + unsigned pick_number(const wchar_t* str, const wchar_t** end, int type); + void convert_unicode(std::wstring& str); + LANGID* lang_info_from_cp(int cp); + LANGID* lang_info_from_ID(int id); + LANGID* lang_info_from_name(const char* utf8); + int save_2_lang_pak(HWND owner, std::vector& items, int cp = 936, std::string* raw_data = NULL, bool to_file = true); + bool parse_pak_digest(uint8_t* data, int* id); + bool parse_pak(uint8_t* data, std::vector& items); + bool load_lang_pak(const wchar_t* file, std::vector& items, int* id = NULL); + + std::wstring get_wnd_text(HWND wnd); + std::wstring get_wnd_text(HWND dlg, UINT id); + enum + { + BOM_ANSI = 0, + BOM_UTF8, + BOM_UNICODE, + }; + std::wstring load_file(const wchar_t* file, int* bom = NULL); + int save_file(const wchar_t* file, std::wstring& cont, int bom = BOM_UNICODE); +} + +class CDlgAddWords : public CDialogEx +{ + DECLARE_DYNAMIC(CDlgAddWords) + +public: + CDlgAddWords(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CDlgAddWords(); + +// 对话框数据 +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_BATCH_ADD_LANG }; +#endif + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual BOOL OnInitDialog(); + void open_pak(int lan_id); + void set_lang_pak_file(const wchar_t* file, int lan_id = 0); + void set_code_file(const wchar_t* file, bool tip = true); + bool add_words(const wchar_t* pak_file, std::vector& ids, std::string& cont, int lan_id, int src_col, bool init_id = false); + bool update_head_file(const wchar_t* file, const std::string& cont); + + DECLARE_MESSAGE_MAP() + + std::vector lan_hz_; + std::vector lan_hzt_; + std::vector lan_eng_; + +public: + afx_msg void OnBnClickedButtonBrowseHz(); + afx_msg void OnBnClickedButtonBrowseHzt(); + afx_msg void OnBnClickedButtonBrowseEng(); + afx_msg void OnBnClickedButtonBrowseCode(); + afx_msg void OnBnClickedButtonAdd(); + afx_msg void OnBnClickedButtonDel(); + afx_msg void OnBnClickedButtonClear(); + afx_msg void OnBnClickedButtonUpdate(); + CListCtrl words_; + afx_msg void OnDropFiles(HDROP hDropInfo); + afx_msg void OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult); +}; diff --git a/pc/code_twain/sln/hgjson/DlgInput.cpp b/pc/code_twain/sln/hgjson/DlgInput.cpp new file mode 100644 index 0000000..0a9c387 --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgInput.cpp @@ -0,0 +1,78 @@ +// DlgInput.cpp : implementation file +// + +#include "stdafx.h" +#include "hgjson.h" +#include "DlgInput.h" +#include "afxdialogex.h" + + +// CDlgInput dialog + +IMPLEMENT_DYNAMIC(CDlgInput, CDialogEx) + +CDlgInput::CDlgInput(CWnd* pParent /*=NULL*/) + : CDialogEx(CDlgInput::IDD, pParent) + , value_(_T("")), type_(INPUT_FOR_NAME) +{ + +} + +CDlgInput::~CDlgInput() +{ +} + +void CDlgInput::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Text(pDX, IDC_EDIT1, value_); +} +BOOL CDlgInput::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + + return TRUE; // return TRUE unless you set the focus to a control +} + + +BEGIN_MESSAGE_MAP(CDlgInput, CDialogEx) + ON_BN_CLICKED(IDOK, &CDlgInput::OnBnClickedOk) +END_MESSAGE_MAP() + + +// CDlgInput message handlers + + + +void CDlgInput::OnBnClickedOk() +{ + // TODO: Add your control notification handler code here + UpdateData(); + if (value_.IsEmpty()) + { + ::MessageBoxW(m_hWnd, L"", L"Error", MB_OK | MB_ICONSTOP); + GotoDlgCtrl(GetDlgItem(IDC_EDIT1)); + return; + } + + if (type_ == INPUT_FOR_NAME) + { + wchar_t text[128] = { 0 }; + + ::GetDlgItemTextW(m_hWnd, IDC_EDIT1, text, _countof(text) - 1); + for (size_t i = 0; i < used_names_.size(); ++i) + { + if (used_names_[i] == text) + { + std::wstring t(used_names_[i] + L" is already used, choose another name, plz."); + ::MessageBoxW(m_hWnd, t.c_str(), L"Sorry", MB_OK); + return; + } + } + } + + CDialogEx::OnOK(); +} diff --git a/pc/code_twain/sln/hgjson/DlgInput.h b/pc/code_twain/sln/hgjson/DlgInput.h new file mode 100644 index 0000000..7277479 --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgInput.h @@ -0,0 +1,31 @@ +#pragma once + + +// CDlgInput dialog +#include +#include + +class CDlgInput : public CDialogEx +{ + DECLARE_DYNAMIC(CDlgInput) + +public: + CDlgInput(CWnd* pParent = NULL); // standard constructor + virtual ~CDlgInput(); + +// Dialog Data + enum { IDD = IDD_DIALOG1 }; + + std::vector used_names_; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + + DECLARE_MESSAGE_MAP() +public: + CString value_; + enum { INPUT_FOR_NAME, INPUT_FOR_STRING, }; + int type_; + afx_msg void OnBnClickedOk(); +}; diff --git a/pc/code_twain/sln/hgjson/DlgOptJson.cpp b/pc/code_twain/sln/hgjson/DlgOptJson.cpp new file mode 100644 index 0000000..76a603b --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgOptJson.cpp @@ -0,0 +1,1452 @@ +// DlgInput.cpp : implementation file +// + +#include "stdafx.h" +#include "hgjson.h" +#include "DlgOptJson.h" +#include "afxdialogex.h" +#include "DlgRange.h" + +#include + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// known name ... +namespace known_name +{ + struct + { + std::wstring name; + std::wstring title; + } + g_group[] = { {L"base", L"\u57FA\u672C\u8BBE\u7F6E"}, {L"imgp", L"\u56FE\u50CF\u5904\u7406"}, {L"feeder", L"\u9001\u7EB8\u65B9\u5F0F"}, {L"adv", L"\u9AD8\u7EA7\u8BBE\u7F6E"}}, + g_cats[] = { {L"imgp", L"\u56FE\u50CF\u5904\u7406"}}; + + static std::wstring group_name(const wchar_t* grp_title) + { + for (auto& v : g_group) + { + if (v.title == grp_title) + return v.name; + } + + return grp_title; + } + static std::wstring group_title(const wchar_t* grp_name) + { + if (wcscmp(grp_name, L"imgproc") == 0) + grp_name = L"imgp"; + + for (auto& v : g_group) + { + if (v.name == grp_name) + return v.title; + } + + return grp_name; + } + + static std::wstring category_name(const wchar_t* cat_title) + { + for (auto& v : g_cats) + { + if (v.title == cat_title) + return v.name; + } + + return cat_title; + } + static std::wstring category_title(const wchar_t* cat_name) + { + if (wcscmp(cat_name, L"imgproc") == 0) + cat_name = L"imgp"; + + for (auto& v : g_cats) + { + if (v.name == cat_name) + return v.title; + } + + return cat_name; + } +}; + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CDlgOptJson dialog + +IMPLEMENT_DYNAMIC(CDlgOptJson, CDialogEx) + +CDlgOptJson::CDlgOptJson(CWnd* pParent /*=NULL*/) + : CDialogEx(CDlgOptJson::IDD, pParent) +{ + +} + +CDlgOptJson::~CDlgOptJson() +{ +} + +known_file_util::IJsonW* CDlgOptJson::SANEOPT::to_json(void) +{ + known_file_util::IJsonW* jsn = known_file_util::create_jsonW(), *dep = NULL; + int nv = 0; + + jsn->set_key(name.c_str()); + jsn->set_value(L"cat", known_name::category_name(category.c_str()).c_str()); + jsn->set_value(L"group", known_name::group_name(group.c_str()).c_str()); + jsn->set_value(L"title", title.c_str()); + jsn->set_value(L"desc", desc.c_str()); + jsn->set_value(L"ver", ver); + jsn->set_value(L"pos", pos); + jsn->set_value(L"type", type.c_str()); + jsn->set_value(L"unit", unit.c_str()); + SANEOPT::affect_str(nv, affect, false); + jsn->set_value(L"affect", nv); + jsn->set_value(L"readonly", readonly); + jsn->set_value(L"visible", open); + jsn->set_value(L"enabled", enable); + jsn->set_value(L"size", (int)sizeof(int)); + + if (type == L"bool") + { + jsn->set_value(L"cur", wcscmp((wchar_t*)def_val.c_str(), L"true") == 0); + jsn->set_value(L"default", wcscmp((wchar_t*)def_val.c_str(), L"true") == 0); + } + else if (type == L"int") + { + known_file_util::IJsonW* rng = NULL; + + jsn->set_value(L"cur", *(int*)def_val.c_str()); + jsn->set_value(L"default", *(int*)def_val.c_str()); + if (range_type == L"list") + { + rng = known_file_util::create_jsonW(); + rng->set_as_array(true); + for (auto& v : range) + *rng += *(int*)v.c_str(); + } + else if (range_type == L"range" && range.size() == 3) + { + rng = known_file_util::create_jsonW(); + rng->set_value(L"min", *(int*)range[0].c_str()); + rng->set_value(L"max", *(int*)range[1].c_str()); + rng->set_value(L"step", *(int*)range[2].c_str()); + } + if (rng) + { + jsn->set_value(L"range", rng); + rng->release(); + } + } + else if (type == L"float") + { + known_file_util::IJsonW* rng = NULL; + + jsn->set_value(L"size", (int)sizeof(double)); + jsn->set_value(L"cur", *(double*)def_val.c_str()); + jsn->set_value(L"default", *(double*)def_val.c_str()); + if (range_type == L"list") + { + rng = known_file_util::create_jsonW(); + rng->set_as_array(true); + for (auto& v : range) + *rng += *(double*)v.c_str(); + } + else if (range_type == L"range" && range.size() == 3) + { + rng = known_file_util::create_jsonW(); + rng->set_value(L"min", *(double*)range[0].c_str()); + rng->set_value(L"max", *(double*)range[1].c_str()); + rng->set_value(L"step", *(double*)range[2].c_str()); + } + if (rng) + { + jsn->set_value(L"range", rng); + rng->release(); + } + } + else if (type == L"string") + { + int len = def_val.length(); + jsn->set_value(L"cur", def_val.c_str()); + jsn->set_value(L"default", def_val.c_str()); + if (range.size()) + { + known_file_util::IJsonW* rng = known_file_util::create_jsonW(); + rng->set_as_array(true); + for (auto& v : range) + { + *rng += v.c_str(); + if (len < v.length()) + len = v.length(); + } + jsn->set_value(L"range", rng); + rng->release(); + } + len += 4; + len *= 3; + jsn->set_value(L"size", len); + } + + if (depends.size()) + { + std::wstring oper(L""), n(L""); + + std::sort(depends.begin(), depends.end()); + if (depend_oper == L"and") + oper = L"depend_and"; + else if (depend_oper == L"or") + oper = L"depend_or"; + + if (!oper.empty()) + { + dep = known_file_util::create_jsonW(); + dep->set_as_array(true); + for (auto& v : depends) + { + std::wstring exp(v), name(coding::name_from_depend_exp(exp)); + + if (name.empty()) + continue; + + if (n != name) + { + n = name; + } + else + exp.erase(0, name.length()); + *dep += exp.c_str(); + } + + jsn->set_value(oper.c_str(), dep); + dep->release(); + } + } + + return jsn; +} +bool CDlgOptJson::SANEOPT::from_json(known_file_util::IJsonW* jsn) +{ + bool ret = true; + const wchar_t* strv = NULL; + known_file_util::IJsonW* child = NULL; + + SANEOPT::init(this); + name = jsn->key() ? jsn->key() : L""; + if (jsn->get_value(L"title", &strv) && strv) + title = strv; + + if (jsn->get_value(L"desc", &strv) && strv) + desc = strv; + + if (jsn->get_value(L"group", &strv) && strv) + group = known_name::group_title(strv); + + if (jsn->get_value(L"cat", &strv) && strv) + category = known_name::category_title(strv); + else if(jsn->get_value(L"field", &strv) && strv) + category = known_name::category_title(strv); + + if (jsn->get_value(L"unit", &strv) && strv) + unit = strv; + std::transform(unit.begin(), unit.end(), unit.begin(), tolower); + + if (jsn->get_value(L"type", &strv) && strv) + type = strv; + std::transform(type.begin(), type.end(), type.begin(), tolower); + + if (type == L"bool") + { + bool v = false; + std::wstring sv(L""); + + jsn->get_value(L"default", v); + sv = v ? L"true" : L"false"; + def_val = std::string((char*)&sv[0], sv.length() * 2 + 2); + } + else if(type == L"int") + { + int v = false; + jsn->get_value(L"default", v); + def_val = std::string((char*)&v, sizeof(v)); + } + else if(type == L"float") + { + double v = false; + jsn->get_value(L"default", v); + def_val = std::string((char*)&v, sizeof(v)); + } + else if(type == L"string") + { + jsn->get_value(L"default", &strv); + def_val = strv ? std::string((const char*)strv, lstrlenW(strv) * 2 + 2) : ""; + } + + jsn->get_value(L"affect", ver); + SANEOPT::affect_str(ver, affect, true); + jsn->get_value(L"ver", ver); + jsn->get_value(L"pos", pos); + jsn->get_value(L"readonly", readonly); + jsn->get_value(L"visible", open); + jsn->get_value(L"enabled", enable); + + if (jsn->get_value(L"range", &child) && child) + { + if (type == L"int") + { + int nv = 0; + if (child->get_value(L"min", nv)) + { + range_type = L"range"; + range.push_back(std::string((char*)&nv, sizeof(nv))); + child->get_value(L"max", nv); + range.push_back(std::string((char*)&nv, sizeof(nv))); + child->get_value(L"step", nv); + range.push_back(std::string((char*)&nv, sizeof(nv))); + } + else + { + range_type = L"list"; + known_file_util::JSONMEMW m = child->first_member(); + while (m.type != known_file_util::JV_UNKNOWN) + { + range.push_back(std::string((char*)&m.int_val, sizeof(m.int_val))); + m = child->next_member(); + } + } + } + else if (type == L"float") + { + double nv = 0; + if (child->get_value(L"min", nv)) + { + range_type = L"range"; + range.push_back(std::string((char*)&nv, sizeof(nv))); + child->get_value(L"max", nv); + range.push_back(std::string((char*)&nv, sizeof(nv))); + child->get_value(L"step", nv); + range.push_back(std::string((char*)&nv, sizeof(nv))); + } + else + { + range_type = L"list"; + known_file_util::JSONMEMW m = child->first_member(); + while (m.type != known_file_util::JV_UNKNOWN) + { + range.push_back(std::string((char*)&m.double_val, sizeof(m.double_val))); + m = child->next_member(); + } + } + } + else if (type == L"string") + { + range_type = L"list"; + known_file_util::JSONMEMW m = child->first_member(); + while (m.type != known_file_util::JV_UNKNOWN) + { + range.push_back(std::string((const char*)m.str_val, lstrlenW(m.str_val) * 2 + 2)); + m = child->next_member(); + } + } + child->release(); + } + + if (jsn->get_value(L"depend_and", &child) && child) + depend_oper = L"and"; + else if (jsn->get_value(L"depend_or", &child) && child) + depend_oper = L"or"; + if (child) + { + known_file_util::JSONMEMW m = child->first_member(); + std::wstring n(L""); + while (m.type != known_file_util::JV_UNKNOWN) + { + std::wstring exp(m.str_val), nm(coding::name_from_depend_exp(exp)); + + if (nm.empty()) + exp.insert(0, n); + else + n = nm; + depends.push_back(exp); + + m = child->next_member(); + } + child->release(); + } + + return ret; +} + +std::wstring CDlgOptJson::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); +} +bool CDlgOptJson::is_button_check(UINT id) +{ + return ((CButton*)GetDlgItem(id))->GetCheck() == BST_CHECKED; +} +void CDlgOptJson::set_button_check(UINT id, bool check) +{ + ((CButton*)GetDlgItem(id))->SetCheck(check ? BST_CHECKED : BST_UNCHECKED); +} + +void CDlgOptJson::from_ui(SANEOPT& sop) +{ + std::wstring val(L""); + + sop.name = get_item_text(IDC_EDIT_NAME); + sop.title = get_item_text(IDC_EDIT_TITLE); + sop.desc = get_item_text(IDC_EDIT_DESCRIPTION); + + sop.group = get_item_text(IDC_COMBO_GROUP); + if (group_.FindStringExact(-1, sop.group.c_str()) == -1) + group_.AddString(sop.group.c_str()); + + sop.category = get_item_text(IDC_COMBO_CATEGORY); + if (cat_.FindStringExact(-1, sop.category.c_str()) == -1) + cat_.AddString(sop.group.c_str()); + + sop.affect = get_item_text(IDC_COMBO_AFFECT); + sop.unit = get_item_text(IDC_COMBO_UNIT); + sop.ver = GetDlgItemInt(IDC_EDIT_VER); + sop.type = get_item_text(IDC_COMBO_DATA_TYPE); + sop.pos = GetDlgItemInt(IDC_EDIT_POSITION); + sop.readonly = is_button_check(IDC_CHECK_READONLY); + sop.open = is_button_check(IDC_CHECK_PUBLIC); + sop.range_type = get_item_text(IDC_COMBO_RANGE); + + if (GetDlgItem(IDC_EDIT_DEFAULT)->IsWindowVisible()) + val = get_item_text(IDC_EDIT_DEFAULT); + else + val = get_item_text(IDC_COMBO_DEFAULT); + sop.def_val = std::string((const char*)val.c_str(), val.length() * 2 + 2); + + sop.enable = is_button_check(IDC_CHECK_ENABLE); + sop.range_type = get_item_text(IDC_COMBO_RANGE); + sop.depend_oper = get_item_text(IDC_COMBO_DEPEND); + if (sop.depend_oper != L"none") + { + wchar_t buf[256] = { 0 }; + for (int i = 0; i < depends_.GetCount(); ++i) + { + depends_.GetText(i, buf); + + std::wstring exp(buf), n(coding::name_from_depend_exp(exp)); + + if (n.empty()) + continue; + + // title to name ... + exp.erase(0, n.length()); + for (auto& v : opts_) + { + if (v.title == n) + { + exp.insert(0, v.name); + break; + } + } + sop.depends.push_back(exp); + } + } +} +void CDlgOptJson::to_ui(const SANEOPT& sop) +{ + int n = 0; + + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_NAME, sop.name.c_str()); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_TITLE, sop.title.c_str()); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_DESCRIPTION, sop.desc.c_str()); + + n = group_.FindStringExact(-1, sop.group.c_str()); + if (n == -1) + n = group_.AddString(sop.group.c_str()); + group_.SetCurSel(n); + + n = cat_.FindStringExact(-1, sop.category.c_str()); + if (n == -1) + n = cat_.AddString(sop.category.c_str()); + cat_.SetCurSel(n); + + n = affect_.FindStringExact(-1, sop.affect.c_str()); + affect_.SetCurSel(n); + + n = unit_.FindStringExact(-1, sop.unit.c_str()); + unit_.SetCurSel(n); + + SetDlgItemInt(IDC_EDIT_VER, sop.ver); + + n = type_.FindStringExact(-1, sop.type.c_str()); + type_.SetCurSel(n); + + SetDlgItemInt(IDC_EDIT_POSITION, sop.pos); + + set_button_check(IDC_CHECK_READONLY, sop.readonly); + set_button_check(IDC_CHECK_PUBLIC, sop.open); + set_button_check(IDC_CHECK_ENABLE, sop.enable); + + n = range_.FindStringExact(-1, sop.range_type.c_str()); + range_.SetCurSel(n); + + n = depend_.FindStringExact(-1, sop.depend_oper.c_str()); + depend_.SetCurSel(n); + + depends_.ResetContent(); + for (auto& v : sop.depends) + { + std::wstring n(coding::name_from_depend_exp(v)), str(v); + + if (n.empty()) + continue; + + // name to title ... + str.erase(0, n.length()); + for (auto& e : opts_) + { + if (e.name == n) + { + str.insert(0, e.title); + break; + } + } + depends_.AddString(str.c_str()); + } + + // default value ... + + // depend item ... + n = sop.depend_oper != L"none"; + parent_.EnableWindow(n); + logic_.EnableWindow(n); + depends_.EnableWindow(n); + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(n); + GetDlgItem(IDC_EDIT_LOW)->EnableWindow(n); + GetDlgItem(IDC_EDIT_LOW)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_COMBO_LOW)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_AND)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_BIG)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_COMBO_BIG)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_BUTTON_SET)->EnableWindow(sop.range_type != L"none"); + + parent_.ResetContent(); + for (auto& v : opts_) + { + if (v.name == sop.name) + continue; + + parent_.AddString(v.title.c_str()); + } + + OnCbnDataTypeSelchange(); + OnCbnRangeSelchange(); + OnCbnDependSelchange(); + + // default value ... + if (sop.type == L"bool") + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_HIDE); + def_val_.ShowWindow(SW_SHOW); + def_val_.ResetContent(); + def_val_.AddString(L"false"); + def_val_.AddString(L"true"); + def_val_.SetCurSel(def_val_.FindStringExact(-1, (const wchar_t*)sop.def_val.c_str())); + } + else if (sop.type == L"int") + { + if (sop.range_type == L"list") + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_HIDE); + def_val_.ShowWindow(SW_SHOW); + def_val_.ResetContent(); + for (auto& v : sop.range) + { + def_val_.AddString(std::to_wstring(*(int*)v.c_str()).c_str()); + } + def_val_.SetCurSel(def_val_.FindStringExact(-1, std::to_wstring(*(int*)sop.def_val.c_str()).c_str())); + } + else + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_SHOW); + SetDlgItemInt(IDC_EDIT_DEFAULT, *(int*)sop.def_val.c_str()); + def_val_.ShowWindow(SW_HIDE); + } + } + else if (sop.type == L"float") + { + if (sop.range_type == L"list") + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_HIDE); + def_val_.ShowWindow(SW_SHOW); + def_val_.ResetContent(); + for (auto& v : sop.range) + { + def_val_.AddString(std::to_wstring(*(double*)v.c_str()).c_str()); + } + def_val_.SetCurSel(def_val_.FindStringExact(-1, std::to_wstring(*(double*)sop.def_val.c_str()).c_str())); + } + else + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_SHOW); + SetDlgItemInt(IDC_EDIT_DEFAULT, *(double*)sop.def_val.c_str()); + def_val_.ShowWindow(SW_HIDE); + } + } + else if (sop.type == L"string") + { + if (sop.range_type == L"list") + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_HIDE); + def_val_.ShowWindow(SW_SHOW); + def_val_.ResetContent(); + for (auto& v : sop.range) + { + def_val_.AddString((const wchar_t*)v.c_str()); + } + def_val_.SetCurSel(def_val_.FindStringExact(-1, (const wchar_t*)sop.def_val.c_str())); + } + else + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_SHOW); + SetDlgItemText(IDC_EDIT_DEFAULT, (const wchar_t*)sop.def_val.c_str()); + def_val_.ShowWindow(SW_HIDE); + } + } +} +HTREEITEM CDlgOptJson::insert_to_tree(const SANEOPT& opt) +{ + HTREEITEM item = tree_.InsertItem(opt.title.c_str()); + wchar_t* name = new wchar_t[opt.name.length() + 2]; + + wcscpy(name, opt.name.c_str()); + if (!tree_.SetItemData(item, (DWORD_PTR)name)) + delete[] name; + + return item; +} +void CDlgOptJson::delete_from_tree(const wchar_t* name) +{ + if (name) + { + HTREEITEM item = tree_.GetRootItem(); + while (item) + { + wchar_t* buf = (wchar_t*)tree_.GetItemData(item); + if (buf && wcscmp(buf, name) == 0) + { + delete[] buf; + tree_.DeleteItem(item); + break; + } + + item = tree_.GetNextSiblingItem(item); + } + } + else + { + HTREEITEM item = tree_.GetRootItem(); + while (item) + { + wchar_t* buf = (wchar_t*)tree_.GetItemData(item); + if (buf) + delete[] buf; + item = tree_.GetNextSiblingItem(item); + } + tree_.DeleteAllItems(); + } +} + +bool CDlgOptJson::load_from_file(const wchar_t* path_file) +{ + std::string cont(""); + std::wstring unic(L""); + bool ret = false; + + file_util::load_file(path_file, coding::get_string, &cont); + coding_util::bom::to_unicode(cont.c_str(), cont.length(), coding::get_wstring, &unic); + if (unic.length()) + { + if (!load_from_json_text(unic.c_str())) + { + unic = path_file; + unic.insert(0, L"Parse json file '"); + unic += L"' failed"; + ::MessageBoxW(m_hWnd, unic.c_str(), L"Error", MB_OK); + } + else + ret = true; + } + + return ret; +} +bool CDlgOptJson::load_from_json_text(const wchar_t* txt, std::wstring* err_msg) +{ + int pos = 0; + known_file_util::IJsonW* jsn = known_file_util::create_jsonW(txt, &pos), * child = NULL; + + if (!jsn) + { + int ep = 10, len = 10; + if (lstrlenW(txt + pos) < 10) + len = lstrlenW(txt + pos); + if (pos < 10) + { + ep = pos; + pos = 10; + } + pos -= 10; + + std::wstring info(txt + pos, len + ep + 1); + wchar_t msg[80] = { 0 }; + + swprintf_s(msg, L"Error at position %d of char '%c'!\r\n\r\n", ep, info[ep]); + if (err_msg) + *err_msg = msg + info; + else + ::MessageBoxW(m_hWnd, (msg + info).c_str(), L"Load Error", MB_OK); + + return false; + } + + delete_from_tree(); + opts_.clear(); + child = jsn->first_child(); + while (child) + { + SANEOPT opt; + + if (opt.from_json(child)) + { + opts_.push_back(opt); + insert_to_tree(opt); + } + + child->release(); + child = jsn->next_child(); + } + jsn->release(); + return true; +} + +void CDlgOptJson::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO_GROUP, group_); + DDX_Control(pDX, IDC_COMBO_CATEGORY, cat_); + DDX_Control(pDX, IDC_COMBO_AFFECT, affect_); + DDX_Control(pDX, IDC_COMBO_UNIT, unit_); + DDX_Control(pDX, IDC_COMBO_DATA_TYPE, type_); + DDX_Control(pDX, IDC_COMBO_RANGE, range_); + DDX_Control(pDX, IDC_COMBO_DEFAULT, def_val_); + DDX_Control(pDX, IDC_COMBO_DEPEND, depend_); + DDX_Control(pDX, IDC_COMBO_PARENT, parent_); + DDX_Control(pDX, IDC_COMBO_LOGIC, logic_); + DDX_Control(pDX, IDC_COMBO_LOW, lower_); + DDX_Control(pDX, IDC_COMBO_BIG, upper_); + DDX_Control(pDX, IDC_COMBO_EXPORT, export_type_); + DDX_Control(pDX, IDC_LIST_DEPEND, depends_); + DDX_Control(pDX, IDC_TREE2, tree_); +} +BOOL CDlgOptJson::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + group_.SetCurSel(0); + cat_.SetCurSel(0); + affect_.SetCurSel(0); + unit_.SetCurSel(0); + type_.SetCurSel(0); + range_.SetCurSel(0); + def_val_.SetCurSel(0); + depend_.SetCurSel(0); + + parent_.EnableWindow(FALSE); + logic_.EnableWindow(FALSE); + GetDlgItem(IDC_EDIT_LOW)->EnableWindow(FALSE); + depends_.EnableWindow(FALSE); + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(FALSE); + + BITMAP bmi = { 0 }; + GetObject(LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1)), sizeof(bmi), &bmi); + tree_img_.Create(IDB_BITMAP1, bmi.bmWidth / 2, bmi.bmWidth / 2, RGB(255, 255, 255)); + tree_.SetImageList(&tree_img_, TVSIL_NORMAL); + + tree_menu_.LoadMenu(IDR_MENU1); + + export_type_.SetCurSel(1); + + return TRUE; // return TRUE unless you set the focus to a control +} + + +BEGIN_MESSAGE_MAP(CDlgOptJson, CDialogEx) + ON_WM_PASTE() + ON_CBN_SELCHANGE(IDC_COMBO_DATA_TYPE, &CDlgOptJson::OnCbnDataTypeSelchange) + ON_CBN_SELCHANGE(IDC_COMBO_RANGE, &CDlgOptJson::OnCbnRangeSelchange) + ON_CBN_SELCHANGE(IDC_COMBO_DEPEND, &CDlgOptJson::OnCbnDependSelchange) + ON_CBN_SELCHANGE(IDC_COMBO_PARENT, &CDlgOptJson::OnCbnParentSelchange) + ON_CBN_SELCHANGE(IDC_COMBO_LOGIC, &CDlgOptJson::OnCbnLogicSelchange) + ON_BN_CLICKED(IDC_BUTTON_MODIFY, &CDlgOptJson::OnBnClickedButtonModify) + ON_BN_CLICKED(IDC_BUTTON_ADD, &CDlgOptJson::OnBnClickedButtonAdd) + ON_NOTIFY(TVN_SELCHANGED, IDC_TREE2, &CDlgOptJson::OnTvnSelchangedTree2) + ON_NOTIFY(NM_RCLICK, IDC_TREE2, &CDlgOptJson::OnNMRClickTree2) + ON_NOTIFY(TVN_SELCHANGING, IDC_TREE2, &CDlgOptJson::OnTvnSelchangingTree2) + ON_COMMAND(ID_TREE_LOADFILE, &CDlgOptJson::OnTreeLoadfile) + ON_COMMAND(ID_TREE_LOADCLIPBOARD, &CDlgOptJson::OnTreeLoadclipboard) + ON_LBN_DBLCLK(IDC_LIST_DEPEND, &CDlgOptJson::OnLbnDblclkListDepend) + ON_BN_CLICKED(IDC_BUTTON_SET, &CDlgOptJson::OnBnClickedButtonSet) + ON_COMMAND(ID_TREE_DELITEM, &CDlgOptJson::OnTreeDelitem) + ON_BN_CLICKED(IDC_BUTTON_EXPORT, &CDlgOptJson::OnBnClickedButtonExport) +END_MESSAGE_MAP() + + +// CDlgOptJson message handlers +void CDlgOptJson::OnCbnSelchange() +{ + +} +void CDlgOptJson::OnCbnDataTypeSelchange() +{ + std::wstring val(get_item_text(IDC_COMBO_DATA_TYPE)); + + range_.EnableWindow(); + if (val == L"bool") + { + range_.SetCurSel(range_.FindStringExact(-1, L"none")); + OnCbnRangeSelchange(); + range_.EnableWindow(FALSE); + } +} +void CDlgOptJson::OnCbnRangeSelchange() +{ + std::wstring val(get_item_text(IDC_COMBO_RANGE)), + type(get_item_text(IDC_COMBO_DATA_TYPE)); + + GetDlgItem(IDC_BUTTON_SET)->EnableWindow(val != L"none"); + if (val == L"list" || type == L"bool") + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_COMBO_DEFAULT)->ShowWindow(SW_SHOW); + def_val_.ResetContent(); + if (type == L"bool") + { + def_val_.AddString(L"false"); + def_val_.AddString(L"true"); + def_val_.SetCurSel(0); + } + } + else + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_COMBO_DEFAULT)->ShowWindow(SW_HIDE); + } +} +void CDlgOptJson::OnCbnDependSelchange() +{ + std::wstring val(get_item_text(IDC_COMBO_DEPEND)); + + parent_.EnableWindow(val != L"none"); + logic_.EnableWindow(val != L"none"); + depends_.EnableWindow(val != L"none"); + lower_.EnableWindow(val != L"none"); + upper_.EnableWindow(val != L"none"); + + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(val != L"none"); + GetDlgItem(IDC_EDIT_LOW)->EnableWindow(val != L"none"); + GetDlgItem(IDC_EDIT_BIG)->EnableWindow(val != L"none"); + + if (val != L"none") + { + val = get_item_text(IDC_EDIT_NAME); + parent_.ResetContent(); + for (auto& v : opts_) + { + if (val == v.name) + continue; + parent_.AddString(v.title.c_str()); + } + } +} +void CDlgOptJson::OnCbnParentSelchange() +{ + std::wstring val(get_item_text(IDC_COMBO_PARENT)); + SANEOPT opt; + + for (auto& v : opts_) + { + if (val == v.title) + { + opt = v; + break; + } + } + + if (opt.type == L"bool") + { + logic_.ResetContent(); + logic_.AddString(L"=="); + logic_.SetCurSel(0); + OnCbnLogicSelchange(); + + GetDlgItem(IDC_EDIT_LOW)->ShowWindow(SW_HIDE); + lower_.ShowWindow(SW_SHOW); + lower_.ResetContent(); + lower_.AddString(L"false"); + lower_.AddString(L"true"); + lower_.SetCurSel(0); + } + else if (opt.type == L"int" || opt.type == L"float") + { + logic_.ResetContent(); + logic_.AddString(L"=="); + logic_.AddString(L"!="); + logic_.AddString(L"<"); + logic_.AddString(L"<="); + logic_.AddString(L">"); + logic_.AddString(L">="); + logic_.AddString(L"between"); + logic_.AddString(L"out of"); + logic_.SetCurSel(0); + OnCbnLogicSelchange(); + + if (opt.range_type == L"list") + { + GetDlgItem(IDC_EDIT_LOW)->ShowWindow(SW_HIDE); + lower_.ShowWindow(SW_SHOW); + lower_.ResetContent(); + upper_.ResetContent(); + + if (opt.type == L"int") + { + for (auto& v : opt.range) + { + std::wstring val(std::to_wstring(*(int*)v.c_str())); + lower_.AddString(val.c_str()); + upper_.AddString(val.c_str()); + } + } + else + { + for (auto& v : opt.range) + { + std::wstring val(std::to_wstring(*(double*)v.c_str())); + lower_.AddString(val.c_str()); + upper_.AddString(val.c_str()); + } + } + } + else + { + GetDlgItem(IDC_EDIT_LOW)->ShowWindow(SW_SHOW); + lower_.ShowWindow(SW_HIDE); + } + } + else if (opt.type == L"string") + { + logic_.ResetContent(); + logic_.AddString(L"=="); + logic_.AddString(L"!="); + logic_.SetCurSel(0); + OnCbnLogicSelchange(); + + if (opt.range_type == L"list") + { + GetDlgItem(IDC_EDIT_LOW)->ShowWindow(SW_HIDE); + lower_.ShowWindow(SW_SHOW); + lower_.ResetContent(); + for (auto& v : opt.range) + { + std::wstring val((const wchar_t*)v.c_str()); + lower_.AddString(val.c_str()); + } + } + else + { + GetDlgItem(IDC_EDIT_LOW)->ShowWindow(SW_SHOW); + lower_.ShowWindow(SW_HIDE); + } + } +} +void CDlgOptJson::OnCbnLogicSelchange() +{ + std::wstring val(get_item_text(IDC_COMBO_LOGIC)); + + if (val == L"between" || val == L"out of") + { + GetDlgItem(IDC_STATIC_AND)->ShowWindow(SW_SHOW); + // upper_.ShowWindow(SW_SHOW); + + val = get_item_text(IDC_COMBO_PARENT); + for (auto& v : opts_) + { + if (val == v.title) + { + val = v.range_type; + break; + } + } + if (val == L"list") + { + upper_.ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_BIG)->ShowWindow(SW_HIDE); + } + else + { + upper_.ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_BIG)->ShowWindow(SW_SHOW); + } + } + else + { + GetDlgItem(IDC_STATIC_AND)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_BIG)->ShowWindow(SW_HIDE); + upper_.ShowWindow(SW_HIDE); + } +} + +void CDlgOptJson::OnPaste() +{ + coding::CLPD clpb; + + file_util::get_clipboard(coding::get_clipboard_content, &clpb); + if (clpb.cont.empty()) + { + MessageBox(TEXT("clipboard is empty.")); + return; + } + + if (clpb.file) + { + size_t pos = clpb.cont.find(L"\r\n"); + bool loaded = false; + + while (!loaded && pos != std::wstring::npos) + { + loaded = load_from_file(clpb.cont.substr(0, pos).c_str()); + clpb.cont.erase(0, pos + 2); + pos = clpb.cont.find(L"\r\n"); + } + if (!loaded && file_util::is_file_existing(clpb.cont.c_str())) + load_from_file(clpb.cont.c_str()); + } + else + { + std::wstring err(L""); + if (load_from_json_text(clpb.cont.c_str(), &err)) + return; + + // we assum the content from codes ... + std::wstring jsn(L""); + size_t pos = clpb.cont.find(L" std::string"); + + while (pos != std::wstring::npos) + { + clpb.cont.erase(0, pos); + pos = clpb.cont.find(L"\""); + if (pos == std::wstring::npos) + break; + clpb.cont.erase(0, pos + 1); + pos = clpb.cont.find(L"\");"); + if (pos == std::wstring::npos) + { + jsn += clpb.cont; + break; + } + else + jsn += clpb.cont.substr(0, pos); + clpb.cont.erase(0, pos); + pos = clpb.cont.find(L" std::string"); + } + + if (jsn.length()) + { + pos = jsn.find(L"\\\\"); + while (pos != std::wstring::npos) + { + jsn.erase(pos++, 1); + pos = jsn.find(L"\\\\", pos); + } + pos = jsn.find(L"\\\""); + while (pos != std::wstring::npos) + { + jsn.erase(pos++, 1); + pos = jsn.find(L"\\\"", pos); + } + + load_from_json_text(jsn.c_str()); + } + else + ::MessageBoxW(m_hWnd, err.c_str(), L"Load Error", MB_OK); + } +} + + + +void CDlgOptJson::OnBnClickedButtonModify() +{ + // TODO: ڴӿؼ֪ͨ + SANEOPT sop; + + from_ui(sop); + if (sop.name.empty() || sop.title.empty()) + { + MessageBox(TEXT("Name and Title must input!")); + return; + } + + for (auto& v : opts_) + { + if (v.title == sop.title && v.name != sop.name) + { + if (::MessageBoxW(m_hWnd, (L"\u5DF2\u7ECF\u5B58\u5728\u540D\u4E3A\u201C" + v.title + L"\u201D\u7684\u914D\u7F6E\u9879\uFF01\uFF0C\u60F3\u4FEE\u6539Name\u5B57\u6BB5\u5417\uFF1F").c_str(), L"Error", MB_ICONSTOP | MB_YESNO) == IDYES) + { + v = std::move(sop); + } + return; + } + } + + for (auto& v : opts_) + { + if (v.name == sop.name) + { + v = std::move(sop); + return; + } + } + + opts_.push_back(sop); +} + + +void CDlgOptJson::OnBnClickedButtonAdd() +{ + // TODO: ڴӿؼ֪ͨ - add depend items + std::wstring opt(get_item_text(IDC_COMBO_PARENT)), + logic(get_item_text(IDC_COMBO_LOGIC)), + l(L""), u(L""); + int ind = 0; + + if (lower_.IsWindowVisible()) + l = get_item_text(IDC_COMBO_LOW); + else + l = get_item_text(IDC_EDIT_LOW); + + if (upper_.IsWindowVisible()) + u = get_item_text(IDC_COMBO_BIG); + else if (GetDlgItem(IDC_EDIT_BIG)->IsWindowVisible()) + u = get_item_text(IDC_EDIT_BIG); + + if (logic == L"between") + { + opt += L"==[" + l + L"," + u + L"]"; + } + else if (logic == L"out of") + { + opt += L"!=[" + l + L"," + u + L"]"; + } + else + { + opt += logic + l; + } + + ind = depends_.FindStringExact(-1, opt.c_str()); + if (ind == -1) + { + ind = depends_.AddString(opt.c_str()); + } + depends_.SetCurSel(ind); +} + + +void CDlgOptJson::OnTvnSelchangedTree2(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); + // TODO: ڴӿؼ֪ͨ + HTREEITEM item = tree_.GetSelectedItem(); + + if (item) + { + TVITEM tvi; + + tvi.mask = TVIF_SELECTEDIMAGE; + tvi.iSelectedImage = 1; + tvi.hItem = item; + tree_.SetItem(&tvi); + + wchar_t* name = (wchar_t*)tree_.GetItemData(item); + for (auto& v : opts_) + { + if (v.name == name) + { + to_ui(v); + break; + } + } + } + + *pResult = 0; +} + + +void CDlgOptJson::OnNMRClickTree2(NMHDR* pNMHDR, LRESULT* pResult) +{ + // TODO: ڴӿؼ֪ͨ + *pResult = 0; + + POINT pt = { 0 }; + HTREEITEM hsel = tree_.GetSelectedItem(); + + tree_menu_.EnableMenuItem(ID_TREE_ADDGROUP, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_ADDITEM, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_ADDPRODUCT, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_DELITEM, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_RENAME, MF_DISABLED); + + tree_menu_.EnableMenuItem(ID_TREE_TOOLTIPS, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_EXPORTCHAR, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_UNIFYSEQUENCE, MF_DISABLED); + + if (hsel) + { + tree_menu_.EnableMenuItem(ID_TREE_DELITEM, MF_ENABLED); + } + + GetCursorPos(&pt); + tree_menu_.GetSubMenu(0)->TrackPopupMenu(0, pt.x, pt.y, this); +} + + +void CDlgOptJson::OnTvnSelchangingTree2(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); + // TODO: ڴӿؼ֪ͨ + HTREEITEM hsel = tree_.GetSelectedItem(); + + if (hsel) + { + + } + + *pResult = 0; +} + + +void CDlgOptJson::OnTreeLoadfile() +{ + // TODO: ڴ + file_util::PATHFILE path = { 0 }; + + if (file_util::browser_file(m_hWnd, &path)) + { + load_from_file(path.path); + } +} + + +void CDlgOptJson::OnTreeLoadclipboard() +{ + // TODO: ڴ + OnPaste(); +} + + +void CDlgOptJson::OnLbnDblclkListDepend() +{ + // TODO: ڴӿؼ֪ͨ + int sel = depends_.GetCurSel(); + + if (sel >= 0 && sel < depends_.GetCount()) + depends_.DeleteString(sel); +} + + +void CDlgOptJson::OnBnClickedButtonSet() +{ + // TODO: ڴӿؼ֪ͨ + std::wstring val(get_item_text(IDC_COMBO_RANGE)); + CDlgRange dlg(val == L"list", this); + SANEOPT opt; + + val = get_item_text(IDC_EDIT_NAME); + if (val.empty()) + { + MessageBox(TEXT("ΨһƣNameֵֶ")); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_NAME)); + return; + } + for (auto& v : opts_) + { + if (v.name == val) + { + opt = v; + break; + } + } + if (!opt.name.empty()) + { + val = get_item_text(IDC_COMBO_DATA_TYPE); + if (val == L"int") + { + dlg.init_ = std::to_wstring(*(int*)opt.def_val.c_str()); + for (auto& v : opt.range) + dlg.vals_.push_back(std::to_wstring(*(int*)v.c_str())); + } + else if (val == L"float") + { + dlg.init_ = std::to_wstring(*(double*)opt.def_val.c_str()); + for (auto& v : opt.range) + dlg.vals_.push_back(std::to_wstring(*(double*)v.c_str())); + } + else + { + dlg.init_ = (const wchar_t*)opt.def_val.c_str(); + for (auto& v : opt.range) + dlg.vals_.push_back((const wchar_t*)v.c_str()); + } + } + + if (dlg.DoModal() == IDOK) + { + if (val == L"int") + { + int n = _wtoi(dlg.init_.c_str()); + opt.def_val = std::string((char*)&n, sizeof(n)); + + opt.range.clear(); + for (auto& v : dlg.vals_) + { + n = _wtoi(v.c_str()); + opt.range.push_back(std::string((char*)&n, sizeof(n))); + } + } + else if (val == L"float") + { + double n = _wtof(dlg.init_.c_str()); + opt.def_val = std::string((char*)&n, sizeof(n)); + + opt.range.clear(); + for (auto& v : dlg.vals_) + { + n = _wtof(v.c_str()); + opt.range.push_back(std::string((char*)&n, sizeof(n))); + } + } + else + { + opt.range.clear(); + opt.def_val = std::string((const char*)dlg.init_.c_str(), dlg.init_.length() * 2 + 2); + for (auto& v : dlg.vals_) + opt.range.push_back(std::string((const char*)v.c_str(), v.length() * 2 + 2)); + } + + // add or insert ... + for (auto& v : opts_) + { + if (v.name == opt.name) + { + v = std::move(opt); + return; + } + } + + std::vector r(std::move(opt.range)); + + from_ui(opt); + opt.range = std::move(r); + opts_.push_back(opt); + insert_to_tree(opt); + } +} + + +void CDlgOptJson::OnTreeDelitem() +{ + // TODO: ڴ + HTREEITEM item = tree_.GetSelectedItem(); + + if (item) + { + CString text(tree_.GetItemText(item)); + + if (MessageBox(TEXT("ȷҪɾ"), text.GetBuffer(), MB_YESNO) == IDYES) + { + wchar_t* buf = (wchar_t*)tree_.GetItemData(item); + tree_.DeleteItem(item); + if (buf) + { + for (int i = 0; i < opts_.size(); ++i) + { + if (opts_[i].name == buf) + { + opts_.erase(opts_.begin() + i); + break; + } + } + delete[] buf; + } + } + text.ReleaseBuffer(); + } +} + + +void CDlgOptJson::OnBnClickedButtonExport() +{ + // TODO: ڴӿؼ֪ͨ + known_file_util::IJsonW* root = known_file_util::create_jsonW(), * child = NULL; + + for (auto& v : opts_) + { + child = v.to_json(); + if (child) + { + root->set_value(v.name.c_str(), child); + child->release(); + } + } + + std::wstring type(get_item_text(IDC_COMBO_EXPORT)), + cont(L""); + + root->to_string(coding::get_wstring, &cont, type == L"\u683C\u5F0F\u6587\u672C" ? L"\t" : NULL); + root->release(); + if (cont.empty()) + { + MessageBox(TEXT("No content has been serialized! change exporting type and try again."), NULL, MB_OK | MB_ICONERROR); + return; + } + + if (type == L"\u4EE3\u7801\u6587\u672C") + { + size_t pos = cont.find(L"\\"); + + while (pos++ != std::wstring::npos) + { + cont.insert(pos++, L"\\"); + pos = cont.find(L"\\", pos); + } + + pos = cont.find(L"\""); + while (pos != std::wstring::npos) + { + cont.insert(pos, L"\\"); + pos = cont.find(L"\"", pos + 2); + } + } + + int n = file_util::set_clipboard(cont.c_str(), cont.length() * 2, CF_UNICODETEXT); + MessageBox(TEXT("JSON text has set to clipboard already")); +} diff --git a/pc/code_twain/sln/hgjson/DlgOptJson.h b/pc/code_twain/sln/hgjson/DlgOptJson.h new file mode 100644 index 0000000..48a8549 --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgOptJson.h @@ -0,0 +1,174 @@ +#pragma once + + +// CDlgInput dialog +#include +#include + +#include +#include +#include +#include + +namespace coding +{ + typedef struct _clp_d + { + bool file; + std::wstring cont; + }CLPD, * LPCLPD; + + INTER_MODULE_CALLBACK(get_string); + INTER_MODULE_CALLBACK(get_wstring); + INTER_MODULE_CALLBACK(get_clipboard_content); + std::wstring name_from_depend_exp(const std::wstring& depend_exp); +}; + +// Group: ;ͼ;ֽʽ;߼; +// +// Cat: ͼ; +// + +class CDlgOptJson : public CDialogEx +{ + DECLARE_DYNAMIC(CDlgOptJson) + + CComboBox group_; + CComboBox cat_; + CComboBox affect_; + CComboBox unit_; + CComboBox type_; + CComboBox range_; + CComboBox def_val_; + CComboBox depend_; + CComboBox parent_; + CComboBox logic_; + CComboBox lower_; + CComboBox upper_; + CComboBox export_type_; + CListBox depends_; + CTreeCtrl tree_; + CMenu tree_menu_; + CImageList tree_img_; + + std::wstring get_item_text(UINT id); + bool is_button_check(UINT id); + void set_button_check(UINT id, bool check); + +public: + CDlgOptJson(CWnd* pParent = NULL); // standard constructor + virtual ~CDlgOptJson(); + +// Dialog Data + enum { IDD = IDD_NEW_JSON }; + + typedef struct _sane_opt_json + { + std::wstring name; + std::wstring title; + std::wstring desc; + std::wstring group; + std::wstring category; + std::wstring affect; + std::wstring unit; + std::wstring type; + std::string def_val; + std::wstring range_type; + std::vector range; + std::wstring depend_oper; + std::vector depends; + + int ver; + int pos; + bool readonly; + bool open; + bool enable; + + struct _sane_opt_json() + { + init(this); + } + struct _sane_opt_json(known_file_util::IJsonW* jsn) + { + if (!from_json(jsn)) + { + init(this); + } + } + static void init(struct _sane_opt_json* opt) + { + opt->name = opt->title = opt->desc = L""; + opt->group = L"\u57FA\u672C\u8BBE\u7F6E"; + opt->category = opt->unit = opt->affect = opt->depend_oper = opt->range_type = L"none"; + opt->range.clear(); + opt->depends.clear(); + + opt->def_val = ""; + opt->type = L"int"; + opt->ver = 1; + opt->pos = -1; + opt->readonly = false; + opt->open = true; + opt->enable = true; + } + static void affect_str(int& val, std::wstring& str, bool to_str) + { + static std::wstring affect_desc[] = { L"none", L"", L"ͼ", L"+" }; + + if (to_str) + { + int ind = val >> 1; + if (ind >= 0 && ind < _countof(affect_desc)) + str = affect_desc[ind]; + else + str = affect_desc[0]; + } + else + { + val = 0; + for (int i = 0; i < _countof(affect_desc); ++i) + { + if (str == affect_desc[i]) + val = i << 1; + } + } + } + + known_file_util::IJsonW* to_json(void); + bool from_json(known_file_util::IJsonW* jsn); + }SANEOPT; + std::vector opts_; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + + void from_ui(SANEOPT& sop); + void to_ui(const SANEOPT& sop); + HTREEITEM insert_to_tree(const SANEOPT& opt); + void delete_from_tree(const wchar_t* name = NULL); + + bool load_from_file(const wchar_t* path_file); + bool load_from_json_text(const wchar_t* txt, std::wstring* err_msg = NULL); + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnCbnDataTypeSelchange(); + afx_msg void OnCbnRangeSelchange(); + afx_msg void OnCbnDependSelchange(); + afx_msg void OnCbnParentSelchange(); + afx_msg void OnCbnLogicSelchange(); + afx_msg void OnCbnSelchange(); + afx_msg void OnPaste(); + afx_msg void OnBnClickedButtonModify(); + afx_msg void OnBnClickedButtonAdd(); + afx_msg void OnTvnSelchangedTree2(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnNMRClickTree2(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnTvnSelchangingTree2(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnTreeLoadfile(); + afx_msg void OnTreeLoadclipboard(); + afx_msg void OnLbnDblclkListDepend(); + afx_msg void OnBnClickedButtonSet(); + afx_msg void OnTreeDelitem(); + afx_msg void OnBnClickedButtonExport(); +}; diff --git a/pc/code_twain/sln/hgjson/DlgRange.cpp b/pc/code_twain/sln/hgjson/DlgRange.cpp new file mode 100644 index 0000000..cb6dffa --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgRange.cpp @@ -0,0 +1,217 @@ +// DlgRange.cpp: 实现文件 +// + +#include "stdafx.h" +#include "hgjson.h" +#include "DlgRange.h" +#include "afxdialogex.h" + + +// CDlgRange 对话框 + +IMPLEMENT_DYNAMIC(CDlgRange, CDialogEx) + +CDlgRange::CDlgRange(bool is_lst, CWnd* pParent /*=nullptr*/) + : CDialogEx(IDD_RANGE, pParent) + , is_list_(is_lst) +{ + +} + +CDlgRange::~CDlgRange() +{ +} + +std::wstring CDlgRange::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); +} + +void CDlgRange::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST1, list_); +} + +BOOL CDlgRange::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + list_.SetExtendedStyle(list_.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP); + list_.InsertColumn(0, TEXT("Value lists"), 0, 177); + list_.InsertColumn(1, TEXT("Default"), 0, 48); + + GetDlgItem(IDC_EDIT_VAL)->EnableWindow(is_list_); + list_.EnableWindow(is_list_); + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(is_list_); + + GetDlgItem(IDC_EDIT_FROM)->EnableWindow(!is_list_); + GetDlgItem(IDC_EDIT_TO)->EnableWindow(!is_list_); + GetDlgItem(IDC_EDIT_STEP)->EnableWindow(!is_list_); + GetDlgItem(IDC_EDIT_INIT2)->EnableWindow(!is_list_); + + if (is_list_) + { + for (auto& v: vals_) + { + int ind = list_.InsertItem(list_.GetItemCount(), v.c_str()); + if (v == init_) + list_.SetItemText(ind, 1, L"yes"); + } + } + else if(vals_.size() == 3) + { + SetDlgItemTextW(IDC_EDIT_FROM, vals_[0].c_str()); + SetDlgItemTextW(IDC_EDIT_TO, vals_[1].c_str()); + SetDlgItemTextW(IDC_EDIT_STEP, vals_[2].c_str()); + + SetDlgItemTextW(IDC_EDIT_INIT2, init_.c_str()); + } + + return TRUE; // return TRUE unless you set the focus to a control +} + +BEGIN_MESSAGE_MAP(CDlgRange, CDialogEx) + ON_BN_CLICKED(IDC_BUTTON1, &CDlgRange::OnBnClickedButton1) + ON_BN_CLICKED(IDOK, &CDlgRange::OnBnClickedOk) + ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CDlgRange::OnNMDblclkList1) +END_MESSAGE_MAP() + + +// CDlgRange 消息处理程序 + + +void CDlgRange::OnBnClickedButton1() +{ + // TODO: 在此添加控件通知处理程序代码 + std::wstring val(get_item_text(IDC_EDIT_VAL)); + + for (int i = 0; i < list_.GetItemCount(); ++i) + { + wchar_t buf[25] = { 0 }; + list_.GetItemText(i, 0, buf, _countof(buf) - 1); + if (val == buf) + { + list_.SetItemState(i, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); + list_.SetSelectionMark(i); + return; + } + } + + list_.InsertItem(list_.GetItemCount(), val.c_str()); +} + + +void CDlgRange::OnBnClickedOk() +{ + // TODO: 在此添加控件通知处理程序代码 + vals_.clear(); + if (is_list_) + { + if (init_.empty()) + { + MessageBox(TEXT("请确定默认值!双击列表中的某项进行选择。 "), TEXT("No Default"), MB_OK); + return; + } + if(list_.GetItemCount() == 0) + { + MessageBox(TEXT("没有输入有效的值列表"), TEXT("No Value"), MB_OK); + return; + } + + for (int i = 0; i < list_.GetItemCount(); ++i) + { + wchar_t buf[256] = { 0 }; + list_.GetItemText(i, 0, buf, _countof(buf) - 1); + vals_.push_back(buf); + } + } + else + { + std::wstring val(get_item_text(IDC_EDIT_FROM)); + + if (val.empty()) + { + MessageBox(TEXT("没有输入有效初始值"), TEXT("No Value"), MB_OK); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_FROM)); + return; + } + vals_.push_back(val); + + val = get_item_text(IDC_EDIT_TO); + if (val.empty()) + { + MessageBox(TEXT("没有输入有效终止值"), TEXT("No Value"), MB_OK); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_TO)); + return; + } + vals_.push_back(val); + + val = get_item_text(IDC_EDIT_STEP); + if (val.empty()) + { + MessageBox(TEXT("没有输入有效步长值"), TEXT("No Value"), MB_OK); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_TO)); + return; + } + vals_.push_back(val); + + init_ = get_item_text(IDC_EDIT_INIT2); + if (init_.empty()) + { + MessageBox(TEXT("没有输入有效默认值"), TEXT("No Value"), MB_OK); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_INIT2)); + return; + } + } + + CDialogEx::OnOK(); +} + + +void CDlgRange::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); + // TODO: 在此添加控件通知处理程序代码 + *pResult = 0; + + + POINT pos = { 0 }; + int item = -1; + + GetCursorPos(&pos); + list_.ScreenToClient(&pos); + item = list_.HitTest(pos); + if (item != -1) + { + wchar_t buf[256] = { 0 }; + int ret = 0; + + list_.GetItemText(item, 0, buf, _countof(buf) - 1); + ret = ::MessageBoxW(m_hWnd, L"是否将该项设置为默认值?\r\nYes: 是\r\nNo: 删除该项\r\nCancel: 放弃操作", buf, MB_YESNOCANCEL); + if (ret == IDYES) + { + init_ = buf; + for (int i = 0; i < list_.GetItemCount(); ++i) + { + list_.SetItemText(i, 1, i == item ? L"yes" : L""); + } + } + else if (ret == IDNO) + { + list_.DeleteItem(item); + } + } +} diff --git a/pc/code_twain/sln/hgjson/DlgRange.h b/pc/code_twain/sln/hgjson/DlgRange.h new file mode 100644 index 0000000..9fc5ebc --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgRange.h @@ -0,0 +1,38 @@ +#pragma once + + +// CDlgRange 对话框 +#include +#include + +class CDlgRange : public CDialogEx +{ + DECLARE_DYNAMIC(CDlgRange) + + std::wstring get_item_text(UINT id); + +public: + CDlgRange(bool is_lst, CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CDlgRange(); + +// 对话框数据 +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_RANGE }; +#endif + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual BOOL OnInitDialog(); + + DECLARE_MESSAGE_MAP() +public: + + std::vector vals_; + std::wstring init_; + bool is_list_; + + afx_msg void OnBnClickedButton1(); + CListCtrl list_; + afx_msg void OnBnClickedOk(); + afx_msg void OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult); +}; diff --git a/pc/code_twain/sln/hgjson/DlgTwain.cpp b/pc/code_twain/sln/hgjson/DlgTwain.cpp new file mode 100644 index 0000000..54d8a0a --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgTwain.cpp @@ -0,0 +1,886 @@ +// DlgInput.cpp : implementation file +// + +#include "stdafx.h" +#include "hgjson.h" +#include "DlgTwain.h" +#include "afxdialogex.h" + +#include + +#include +#include + + +namespace util +{ + enum + { + BOM_ANSI, + BOM_UTF8, + BOM_UNICODE, + }; + static INTER_MODULE_CALLBACK(got_str) + { + *(std::string*)param += std::string(data, len); + + return inter_module_data::SET_RESULT_CONTINUE; + } + static INTER_MODULE_CALLBACK(got_wstr) + { + *(std::wstring*)param += std::wstring((const wchar_t*)data, len / 2); + + return inter_module_data::SET_RESULT_CONTINUE; + } + + static bool is_space(wchar_t ch) + { + return ch == L' ' || ch == L'\t' || ch == L'\r' || ch == L'\n'; + } + static bool is_var_char(wchar_t ch, bool allow_num) + { + return ch == L'_' || + (ch >= L'0' && ch <= L'9' && allow_num) || + (ch >= L'a' && ch <= L'z') || + (ch >= L'A' && ch <= L'Z'); + } + static bool skip_space(const wchar_t** str) + { + const wchar_t* bgn = *str; + + while (is_space(str[0][0])) + (*str)++; + + return *str > bgn; + } + static void to_line_head(const wchar_t** str) + { + while (str[0][0] != L'\n') + (*str)--; + } + static void erase_multiline_comment(std::wstring& cont) + { + for (int i = 0; i < cont.length(); ++i) + { + if (cont[i] == L'/') + { + if (cont[i + 1] == L'/') + { + std::wstring val(L""); + int next = 0; + coding_util::pick_line(cont.c_str() + i, got_wstr, &val, &next); + i += next; + } + else if (cont[i + 1] == L'*') + { + size_t pos = cont.find(L"*/", i + 2); + if (pos++ == std::wstring::npos) + { + cont.erase(i); + break; + } + else + cont.erase(i, pos - i + 1); + } + } + } + } + static void transform_hz(std::wstring& hz) + { + int prev = -1; + std::string inner(""); + for (int i = 0; i < hz.length() - 3; ++i) + { + if (hz[i] == L'\\') + { + if (hz[i + 1] == L'u') + { + + } + else if (hz[i + 1] == L'x') + { + + } + else if (hz[i + 1] >= L'0' && hz[i + 1] <= L'7') + { + if (hz[i + 2] >= L'0' && hz[i + 2] <= L'7' && + hz[i + 3] >= L'0' && hz[i + 3] <= L'7') + { + if (prev == -1) + prev = i; + char ch = (hz[i + 1] - L'0') * 64 + (hz[i + 2] - L'0') * 8 + hz[i + 3] - L'0'; + inner.append(1, ch); + i += 3; + } + } + } + else + { + if (inner.length()) + { + std::wstring trans(L""); + coding_util::utf8_2_unicode(inner.c_str(), got_wstr, &trans); + hz.replace(prev, i - prev, trans); + i = prev + trans.length(); + } + prev = -1; + inner = ""; + } + } + if (inner.length()) + { + std::wstring trans(L""); + coding_util::utf8_2_unicode(inner.c_str(), got_wstr, &trans); + hz.replace(prev, hz.length() - prev, trans); + } + } + static std::wstring now(void) + { + time_t t = time(NULL); + tm* pt = localtime(&t); + wchar_t buf[40] = { 0 }; + + swprintf_s(buf, _countof(buf) - 1, L"%04d-%02d-%02d %02d:%02d:%02d", + pt->tm_year + 1900, pt->tm_mon + 1, pt->tm_mday, pt->tm_hour, pt->tm_min, pt->tm_sec); + + return buf; + } + static std::wstring get_text(HWND wnd) + { + int len = GetWindowTextLengthW(wnd); + wchar_t * buf = new wchar_t[len + 128]; + std::wstring ret(L""); + + len = ::GetWindowTextW(wnd, buf, len + 20); + buf[len] = 0; + ret = buf; + delete[] buf; + + return std::move(ret); + } + static void append_log(const wchar_t* log, HWND edit, bool scroll_last) + { + std::wstring text(std::move(get_text(edit))), cur(now() + L": "), str(log), space(L""); + size_t pos = str.find(L"\r\n"); + + space.append(cur.length() * 2, L' '); + while (pos != std::wstring::npos && pos < str.length() - 2) + { + str.insert(pos + 2, space); + pos = str.find(L"\r\n", pos + space.length() + 2); + } + text += cur + str; + ::SetWindowTextW(edit, text.c_str()); + if (scroll_last) + ::SendMessage(edit, EM_LINESCROLL, 0, ::SendMessageW(edit, EM_GETLINECOUNT, 0, 0)); + else + ::SendMessageW(edit, EM_LINESCROLL, 0, (LPARAM)::GetPropW(edit, L"stop_line")); + } + static std::wstring load_file(const wchar_t* file, int *bom) + { + std::wstring cont(L""); + std::string raw(""); + + file_util::load_file(file, got_str, &raw); + if (raw.empty()) + return false; + if (bom) + *bom = coding_util::bom::is_unicode(raw.c_str(), NULL) ? BOM_UNICODE : (coding_util::bom::is_utf8(raw.c_str()) ? BOM_UTF8 : BOM_ANSI); + coding_util::bom::to_unicode(raw.c_str(), raw.length(), got_wstr, &cont); + + return std::move(cont); + } + static bool save_file(const wchar_t* file, const wchar_t* cont, int bom, std::wstring* bak = NULL) + { + std::string raw(""); + if (bom == BOM_UNICODE) + coding_util::bom::from_unicode(cont, lstrlenW(cont) * 2, got_str, &raw); + else if (bom == BOM_UTF8) + { + std::string utf8(""); + coding_util::unicode_2_utf8(cont, got_str, &utf8); + coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), got_str, &raw); + } + else + coding_util::unicode_2_ansi(cont, got_str, &raw); + + if (bak) + { + *bak = file; + *bak += L".bak"; + file_util::force_copy_file(file, bak->c_str()); + } + + return file_util::save_2_file(raw.c_str(), raw.length(), file) == 0; + } + std::string u2a(const wchar_t* u, bool to_utf8 = false) + { + std::string a(""); + + if (to_utf8) + coding_util::unicode_2_utf8(u, got_str, &a); + else + coding_util::unicode_2_ansi(u, got_str, &a); + + return std::move(a); + } + std::wstring a2u(const char* a, bool from_utf8 = false) + { + std::wstring u(L""); + + if (from_utf8) + coding_util::utf8_2_unicode(a, got_wstr, &u); + else + coding_util::ansi_2_unicode(a, got_wstr, &u); + + return std::move(u); + } + + static std::wstring get_sane_opt_title(const wchar_t* key, const std::wstring& cont) + { + size_t pos = cont.find(key); + std::wstring title(L""); + + while (pos != std::wstring::npos) + { + if (pos) + { + int check = pos - 1; + if (cont[check] == L' ' || cont[check] == L'\t') + { + const wchar_t* l = cont.c_str() + check; + to_line_head(&l); + skip_space(&l); + if (wcsstr(l, L"#define") == l) + { + l += 7; + skip_space(&l); + if (wcsstr(l, key) == l) + { + l += lstrlenW(key); + if (skip_space(&l) && *l++ == L'\"') + { + while (*l != L'\r' && *l != L'\n' && *l != L'\"' && *l != 0) + title.append(1, *l++); + transform_hz(title); + break; + } + } + } + } + } + pos += lstrlenW(key); + pos = cont.find(key, pos); + } + + return std::move(title); + } + static void get_sane_opts(const wchar_t* file, std::vector& opts) + { + std::wstring tf(file), name(L"\r\n"), title(L"\r\n") + , pre_n(L"SANE_STD_OPT_NAME_"), pre_t(L"OPTION_TITLE_"), define(L"#define") + , line(L""), val(L""); + std::string bom(""); + SANEOPT opt; + int off = 0, next = 0; + + STR_PARENT_FOLDER(tf); + tf += L"\\sane_option_definitions.h"; + STR_TO_ABSOLUTE_PATH(tf); + + file_util::load_file(file, got_str, &bom); + if (bom.empty()) + return; + coding_util::bom::to_unicode(bom.c_str(), bom.length(), got_wstr, &name); + erase_multiline_comment(name); + + bom = ""; + file_util::load_file(tf.c_str(), got_str, &bom); + if (bom.empty()) + return; + coding_util::bom::to_unicode(bom.c_str(), bom.length(), got_wstr, &title); + bom = ""; + erase_multiline_comment(title); + + // search ... + coding_util::pick_line(name.c_str(), got_wstr, &line, &next); + while (line.length() || next) + { + size_t pos = line.find(define); + if (pos == 0 && line.length() > define.length() && is_space(line[define.length()])) + { + const wchar_t* str = line.c_str() + define.length(), * bgn = NULL;; + util::skip_space(&str); + if (wcsstr(str, pre_n.c_str()) == str) + { + bgn = str; + str += pre_n.length(); + while (is_var_char(*str, true)) + str++; + opt.name_key = std::wstring(bgn, str - bgn); + if (util::skip_space(&str) && *str++ == L'\"') + { + bgn = str; + while (*str != L'\"') + str++; + opt.name = std::wstring(bgn, str - bgn); + str++; + util::skip_space(&str); + if (wcsstr(str, L"//") == str) + { + str += 2; + util::skip_space(&str); + if (wcsstr(str, pre_t.c_str()) == str) + { + bgn = str; + str += pre_t.length(); + while (is_var_char(*str, true)) + str++; + opt.title_key = std::wstring(bgn, str - bgn); + opt.title = std::move(get_sane_opt_title(opt.title_key.c_str(), title)); + opts.push_back(opt); + } + } + } + } + } + off += next; + line = L""; + coding_util::pick_line(name.c_str() + off, got_wstr, &line, &next); + } + } + + static bool pick_option_id_function(std::wstring& code, int* off = NULL, const wchar_t* api_decl = L"scanner::init_options_id(void)", const wchar_t* ret = L"int") + { + std::wstring api(api_decl); + size_t pos = code.find(api); + const wchar_t* l = NULL; + + while (pos != std::wstring::npos) + { + l = code.c_str() + pos; + to_line_head(&l); + skip_space(&l); + if (wcsstr(l, ret) == l) + { + l += lstrlenW(ret); + if (skip_space(&l)) + { + if (wcsstr(l, api.c_str()) == l) + { + int bgn = 0, end = 0; + + coding_util::pick_value(l, L"{", L"}", &bgn, &end); + if (end > bgn) + { + api = std::wstring(l + bgn, end - bgn + 1); + if (off) + *off = l + bgn - code.c_str(); + code = std::move(api); + return true; + } + } + } + } + pos += api.length(); + pos = code.find(api, pos); + } + + return false; + } + static bool pick_twain_ex_enum(std::wstring& code, int* start = NULL) + { + // enum CapTypeEx : unsigned short { + size_t pos = code.find(L"enum"); + + while (pos != std::wstring::npos) + { + const wchar_t* l = code.c_str() + pos; + to_line_head(&l); + skip_space(&l); + if (wcsstr(l, L"enum") == l) + { + l += 4; + if (skip_space(&l)) + { + if (wcsstr(l, L"CapTypeEx") == l) + { + int bgn = 0, end = 0; + coding_util::pick_value(l, L"{", L"}", &bgn, &end); + if (start) + *start = l + bgn - code.c_str(); + code = std::move(std::wstring(l + bgn, end - bgn + 1)); + + return true; + } + } + } + pos = code.find(L"enum", pos + 4); + } + + return false; + } + static bool get_twain_id(const std::wstring& idtext, std::vector& used) + { + std::wstring pre(L"CAP_EX_SANE_"), line(L""), key(L""); + OPTUSED ou; + int off = 0, next = 0, id = 0x8801; + + coding_util::pick_line(idtext.c_str(), got_wstr, &line, &next); + while (!line.empty() || next) + { + const wchar_t* bgn = line.c_str(), * l = bgn; + skip_space(&l); + if (wcsstr(l, pre.c_str()) == l) + { + l += pre.length(); + bgn = l; + while (is_var_char(*l, true)) + l++; + key = std::wstring(bgn, l - bgn); + ou.id_key = ""; + coding_util::unicode_2_ansi(key.c_str(), got_str, &ou.id_key); + ou.id = id++; + used.push_back(ou); + } + + off += next; + line.clear(); + coding_util::pick_line(idtext.c_str() + off, got_wstr, &line, &next); + } + std::sort(used.begin(), used.end()); + + return true; + } + static void get_used_opts(const wchar_t* file, std::vector& used) + { + std::wstring key(L""), id(L""), idf(file), line(L""), pre_nk(L"SANE_STD_OPT_NAME_"), pre_ik(L"CAP_EX_SANE_"), setoid(L"SET_OPT_ID("); + std::string bom(""); + OPTUSED ou; + int off = 0, next = 0; + + STR_PARENT_FOLDER(idf); + idf += L"\\..\\..\\code_twain\\twain\\twain\\huagaods.cpp"; + STR_TO_ABSOLUTE_PATH(idf); + + file_util::load_file(file, got_str, &bom); + if (bom.empty()) + return; + coding_util::bom::to_unicode(bom.c_str(), bom.length(), got_wstr, &key); + erase_multiline_comment(key); + + bom = ""; + file_util::load_file(idf.c_str(), got_str, &bom); + if (bom.empty()) + return; + coding_util::bom::to_unicode(bom.c_str(), bom.length(), got_wstr, &id); + erase_multiline_comment(id); + get_twain_id(id, used); + + if (!pick_option_id_function(key) || !pick_twain_ex_enum(id)) + return; + + bom = ""; + coding_util::pick_line(key.c_str(), got_wstr, &line, &next); + while (!line.empty() || next > 0) + { + const wchar_t* l = line.c_str(), * bgn = NULL; + skip_space(&l); + if (wcsstr(l, L"else") == l) + { + l += 4; + skip_space(&l); + } + if (wcsstr(l, setoid.c_str()) == l) + { + l += setoid.length(); + bgn = l; + if (is_var_char(*l++, false)) + { + while (is_var_char(*l, true)) + l++; + ou.id_key = ""; + coding_util::unicode_2_ansi(std::wstring(bgn, l - bgn).c_str(), got_str, &ou.id_key); + skip_space(&l); + if (*l++ == L',') + { + skip_space(&l); + bgn = l; + if (is_var_char(*l++, false)) + { + while (is_var_char(*l, true)) + l++; + ou.name_key = std::wstring(bgn, l - bgn); + + std::vector::iterator it = std::find(used.begin(), used.end(), ou.id_key.c_str()); + if (it != used.end()) + it->name_key = std::move(L"SANE_STD_OPT_NAME_" + ou.name_key); + } + } + } + } + + off += next; + line = L""; + coding_util::pick_line(key.c_str() + off, got_wstr, &line, &next); + } + } + + static bool add_2_huagaods_cpp(const wchar_t* file, const SANEOPT& sane, const OPTUSED& twain, std::wstring* msg) + { + int off = 0, next = 0, bom = BOM_ANSI; + std::wstring cont(std::move(load_file(file, &bom))), line(L""), lead(L"CAP_EX_SANE_"); + + if (cont.empty()) + { + if (msg) + *msg = L"File 'huagaods.cpp' is not found or empty."; + return false; + } + + line = cont; + if (pick_twain_ex_enum(line, &off)) + { + size_t pos = line.rfind(L','); + const wchar_t* l = line.c_str() + pos, * bgn = NULL; + + to_line_head(&l); + bgn = ++l; + skip_space(&l); + + std::wstring en(bgn, l - bgn); + + en += lead + a2u(twain.id_key.c_str()) + L",\t\t// " + now() + L" " + sane.title; + lead = line; + lead.insert(pos + 1, L"\r\n" + en); + cont.replace(off, line.length(), lead); + + line = cont; + if (pick_option_id_function(line, &off, L"huagao_ds::init_support_caps_ex(void)", L"void")) + { + pos = line.rfind(L';'); + l = line.c_str() + pos; + to_line_head(&l); + l++; + bgn = l; + skip_space(&l); + en = std::wstring(bgn, l - bgn); + en += L"ADD_SANE_CAP("; + en += a2u(twain.id_key.c_str()); + en += L");\r\n"; + lead = line + en; + cont.replace(off, line.length(), lead); + + if (save_file(file, cont.c_str(), bom, &line)) + { + if (msg) + *msg += std::wstring(L"Changed: ") + file + L"\r\n"; + return true; + } + else if (msg) + *msg = L"Failed to save changes into file 'huagaods.cpp'."; + + if (file_util::is_file_existing(line.c_str())) + file_util::force_move_file(line.c_str(), file); + } + else if (msg) + { + *msg = L"Failed to find function 'huagao_ds::init_support_caps_ex(void)' in huagaods.cpp."; + } + } + else if (msg) + { + *msg = L"Failed to find 'enum CapTypeEx' in huagaods.cpp."; + } + + return false; + } + static bool add_2_scanner_codes(const wchar_t* cpp, const SANEOPT& sane, const OPTUSED& twain, std::wstring* msg) + { + int bom_c = BOM_ANSI, bom_h = BOM_ANSI; + std::wstring hf(cpp), code_c(load_file(cpp, &bom_c)), code_h(L""), tag(L"// SANE options ID ..."), val(L""), hbak(L""), cbak(L""); + size_t pos = hf.rfind(L'.'); + const wchar_t *l = NULL, *bgn = NULL; + + if (code_c.empty()) + { + if (msg) + *msg = std::wstring(L"File '") + cpp + L"' is not found or empty."; + return false; + } + + hf.erase(pos); + hf += L".h"; + code_h = std::move(load_file(hf.c_str(), &bom_h)); + if (code_h.empty()) + { + if (msg) + *msg = std::wstring(L"File '") + hf + L"' is not found or empty."; + return false; + } + + pos = code_h.find(tag); + if (pos == std::wstring::npos) + { + if (msg) + *msg = L"Cannot find tag '" + tag + L"' in file " + hf; + return false; + } + + bgn = l = code_h.c_str() + pos; + to_line_head(&bgn); + bgn++; + val = L"\r\n" + std::wstring(bgn, l - bgn) + L"SANE_OPTION_ID(" + a2u(twain.id_key.c_str()) + L");"; + code_h.insert(pos + tag.length(), val + L"\t\t// " + now() + L" " + sane.title); + if (save_file(hf.c_str(), code_h.c_str(), bom_h, &hbak)) + { + code_h.clear(); + + pos = code_c.find(L"SANE_OPTION_ID_IMPLEMENT("); + if (pos != std::wstring::npos) + { + int off = 0; + + val = L"SANE_OPTION_ID_IMPLEMENT(" + a2u(twain.id_key.c_str()) + L")\r\n"; + code_c.insert(pos, val); + code_h = code_c; + if (pick_option_id_function(code_h, &off)) + { + pos = code_h.find(L"op_id++;"); + if (pos != std::wstring::npos) + { + l = bgn = code_h.c_str() + pos; + to_line_head(&bgn); + bgn++; + tag = sane.name_key; + if (tag.find(L"SANE_STD_OPT_NAME_") == 0) + tag.erase(0, lstrlenW(L"SANE_STD_OPT_NAME_")); + val = std::wstring(bgn, l - bgn) + L"else SET_OPT_ID(" + a2u(twain.id_key.c_str()) + L", " + tag + L", extension_none)\r\n"; + off += bgn - code_h.c_str(); + code_c.insert(off, val); + if (save_file(cpp, code_c.c_str(), bom_c, &cbak)) + { + std::wstring s2t(hf); + + STR_PARENT_FOLDER(s2t); + s2t += L"\\s2t_api.h"; + code_h = std::move(load_file(s2t.c_str(), &bom_h)); + if (!code_h.empty()) + { + tag = L"// SANE options ID ..."; + pos = code_h.find(tag); + if (pos == std::wstring::npos) + { + if (msg) + *msg = L"Cannot find tag '// SANE options ID ...' in file " + s2t; + return false; + } + bgn = l = code_h.c_str() + pos; + to_line_head(&bgn); + bgn++; + val = L"\r\n" + std::wstring(bgn, l - bgn) + L"SANE_OPTION_ID_API(" + a2u(twain.id_key.c_str()) + L");"; + code_h.insert(pos + tag.length(), val + L"\t\t// " + now() + L" " + sane.title); + + if (save_file(s2t.c_str(), code_h.c_str(), bom_h, &val)) + { + if (msg) + *msg += std::wstring(L"Changed: ") + hf + L"\r\n" + L"Changed: " + cpp + L"\r\nChanged: " + s2t + L"\r\n"; + return true; + } + else if (msg) + *msg = L"Failed to save changes into file: " + s2t; + if (file_util::is_file_existing(val.c_str())) + file_util::force_move_file(val.c_str(), s2t.c_str()); + } + else if (msg) + *msg = std::wstring(L"File '") + s2t + L"' is not found or empty."; + } + else if (msg) + { + *msg = L"Failed to save changes into file: " + std::wstring(cpp); + } + + if (file_util::is_file_existing(cbak.c_str())) + file_util::force_move_file(cbak.c_str(), cpp); + } + else if (msg) + { + *msg = L"Failed to find function 'scanner::init_options_id(void) - op_id++' in file: " + std::wstring(cpp); + } + } + else if (msg) + { + *msg = L"Failed to find function 'scanner::init_options_id(void)' in file: " + std::wstring(cpp); + } + } + else if (msg) + { + *msg = L"Failed to find 'SANE_OPTION_ID_IMPLEMENT' in file: " + std::wstring(cpp); + } + } + else if (msg) + { + *msg = L"Failed to save changes into file: " + hf; + } + + if (file_util::is_file_existing(hbak.c_str())) + file_util::force_move_file(hbak.c_str(), hf.c_str()); + + return false; + } +} + +// CDlgTwain dialog + +IMPLEMENT_DYNAMIC(CDlgTwain, CDialogEx) + +CDlgTwain::CDlgTwain(CWnd* pParent /*=NULL*/) + : CDialogEx(CDlgTwain::IDD, pParent) +{ + +} + +CDlgTwain::~CDlgTwain() +{ +} + +void CDlgTwain::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO1, sane_); +} +BOOL CDlgTwain::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + + return TRUE; // return TRUE unless you set the focus to a control +} +void CDlgTwain::on_sln_path_changed(void) +{ + GetDlgItem(IDC_BUTTON_BROWSE)->EnableWindow(FALSE); + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(FALSE); + GetDlgItem(IDC_COMBO1)->EnableWindow(FALSE); + + util::append_log(L"parsing SANE attributes ...\r\n", GetDlgItem(IDC_EDIT2)->m_hWnd, true); + sane_.ResetContent(); + + std::wstring path(util::get_text(GetDlgItem(IDC_EDIT1)->m_hWnd)); + + opts_.clear(); + used_.clear(); + + STR_PARENT_FOLDER(path); + path += L"\\..\\..\\"; + STR_TO_ABSOLUTE_PATH(path); + root_ = path; + util::get_sane_opts((path + L"sdk\\include\\sane\\sane_ex.h").c_str(), opts_); + if (opts_.size() == 0) + { + ::MessageBoxW(m_hWnd, L"ûҵSANEԶ塣", L"", MB_OK | MB_ICONSTOP); + return; + } + for (auto& v : opts_) + sane_.AddString((v.title + L" (" + v.name + L")").c_str()); + + GetDlgItem(IDC_BUTTON_BROWSE)->EnableWindow(TRUE); + GetDlgItem(IDC_COMBO1)->EnableWindow(TRUE); + GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(TRUE); + util::append_log((L"Found " + std::to_wstring(opts_.size()) + L" options\r\n").c_str(), GetDlgItem(IDC_EDIT2)->m_hWnd, true); + + // find used ... + util::get_used_opts((path + L"code_twain\\sane\\scanner.cpp").c_str(), used_); +} +void CDlgTwain::synchronize_opt(const SANEOPT& opt) +{ + OPTUSED ou; + std::wstring pre(L"SANE_STD_OPT_NAME_"), key(L""), msg(L""); + + if (used_.size()) + ou.id = used_[used_.size() - 1].id + 1; + else + ou.id = 0x8801; + + ou.name_key = opt.name_key; + if (ou.name_key.find(pre) == 0) + key = ou.name_key.substr(pre.length()); + else + key = ou.name_key; + std::transform(key.begin(), key.end(), key.begin(), tolower); + coding_util::unicode_2_ansi(key.c_str(), util::got_str, &ou.id_key); + + std::vector::iterator it = std::find(used_.begin(), used_.end(), ou.id_key.c_str()); + if (it != used_.end()) + { + ::MessageBoxW(m_hWnd, (opt.title + L" already synchronized into TWAIN.").c_str(), L"Error", MB_OK | MB_ICONINFORMATION); + return; + } + + if (util::add_2_huagaods_cpp((root_ + L"code_twain\\twain\\twain\\huagaods.cpp").c_str(), opt, ou, &msg) && + util::add_2_scanner_codes((root_ + L"code_twain\\sane\\scanner.cpp").c_str(), opt, ou, &msg)) + { + used_.push_back(ou); + + std::wstring tips(L"Added New TWAIN extended ATTR: CAP_EX_SANE_"); + wchar_t hex[40] = { 0 }; + + coding_util::ansi_2_unicode(ou.id_key.c_str(), util::got_wstr, &tips); + swprintf_s(hex, _countof(hex) - 1, L" (ID: 0x%04x) - ", ou.id); + tips += hex + opt.title + L"\r\n"; + util::append_log(tips.c_str(), GetDlgItem(IDC_EDIT2)->m_hWnd, true); + } + util::append_log(msg.c_str(), GetDlgItem(IDC_EDIT2)->m_hWnd, true); +} + +BEGIN_MESSAGE_MAP(CDlgTwain, CDialogEx) + ON_BN_CLICKED(IDC_BUTTON_BROWSE, &CDlgTwain::OnBnClickedButtonBrowse) + ON_BN_CLICKED(IDC_BUTTON_ADD, &CDlgTwain::OnBnClickedButtonAdd) +END_MESSAGE_MAP() + + +// CDlgTwain message handlers + + + +void CDlgTwain::OnBnClickedButtonBrowse() +{ + // TODO: ڴӿؼ֪ͨ + file_util::PATHFILE path = { 0 }; + + if (file_util::browser_file(m_hWnd, &path, L"Solution File(*.sln)\0\0")) + { + ::SetDlgItemTextW(m_hWnd, IDC_EDIT1, path.path); + on_sln_path_changed(); + } +} + + +void CDlgTwain::OnBnClickedButtonAdd() +{ + // TODO: ڴӿؼ֪ͨ + std::wstring text(util::get_text(sane_.m_hWnd)); + std::string ansi(""); + size_t pos = text.rfind(L'('); + + if (pos++ == std::wstring::npos) + { + ::MessageBoxW(m_hWnd, L"Invalid option name! (lost '()')", L"Error", MB_OK | MB_ICONSTOP); + return; + } + text.erase(0, pos); + pos = text.find(L")"); + if (pos != std::wstring::npos) + text.erase(pos); + if (text.empty()) + { + ::MessageBoxW(m_hWnd, L"Invalid option name! (empty)", L"Error", MB_OK | MB_ICONSTOP); + return; + } + + coding_util::unicode_2_ansi(text.c_str(), util::got_str, &ansi); + + pos = sane_.GetCurSel(); + synchronize_opt(opts_[pos]); +} diff --git a/pc/code_twain/sln/hgjson/DlgTwain.h b/pc/code_twain/sln/hgjson/DlgTwain.h new file mode 100644 index 0000000..c32be1c --- /dev/null +++ b/pc/code_twain/sln/hgjson/DlgTwain.h @@ -0,0 +1,66 @@ +#pragma once + + +// CDlgTwain dialog +#include +#include + + +typedef struct _san_opt +{ + std::wstring name_key; + std::wstring name; + std::wstring title_key; + std::wstring title; +}SANEOPT; +typedef struct _opt_used +{ + std::wstring name_key; // same as SANEOPT::name_key + std::string id_key; + int id; // ID of CAP_SANE_EX_xxx + + bool operator==(const wchar_t* key) + { + return name_key == key; + } + bool operator==(const char* key) + { + return id_key == key; + } + bool operator==(const int eid) + { + return eid == id; + } + bool operator<(const struct _opt_used& r) + { + return id < r.id; + } +}OPTUSED; + +class CDlgTwain : public CDialogEx +{ + DECLARE_DYNAMIC(CDlgTwain) + +public: + CDlgTwain(CWnd* pParent = NULL); // standard constructor + virtual ~CDlgTwain(); + +// Dialog Data + enum { IDD = IDD_ADD_TWAIN_ATTR }; + + std::vector opts_; + std::vector used_; + std::wstring root_; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + void on_sln_path_changed(void); + void synchronize_opt(const SANEOPT& opt); + + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedButtonBrowse(); + afx_msg void OnBnClickedButtonAdd(); + CComboBox sane_; +}; diff --git a/pc/code_twain/sln/hgjson/ReadMe.txt b/pc/code_twain/sln/hgjson/ReadMe.txt new file mode 100644 index 0000000..4c8675c --- /dev/null +++ b/pc/code_twain/sln/hgjson/ReadMe.txt @@ -0,0 +1,99 @@ +================================================================================ + MICROSOFT FOUNDATION CLASS LIBRARY : hgjson Project Overview +=============================================================================== + +The application wizard has created this hgjson application for +you. This application not only demonstrates the basics of using the Microsoft +Foundation Classes but is also a starting point for writing your application. + +This file contains a summary of what you will find in each of the files that +make up your hgjson application. + +hgjson.vcxproj + This is the main project file for VC++ projects generated using an application wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + application wizard. + +hgjson.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +hgjson.h + This is the main header file for the application. It includes other + project specific headers (including Resource.h) and declares the + ChgjsonApp application class. + +hgjson.cpp + This is the main application source file that contains the application + class ChgjsonApp. + +hgjson.rc + This is a listing of all of the Microsoft Windows resources that the + program uses. It includes the icons, bitmaps, and cursors that are stored + in the RES subdirectory. This file can be directly edited in Microsoft + Visual C++. Your project resources are in 1033. + +res\hgjson.ico + This is an icon file, which is used as the application's icon. This + icon is included by the main resource file hgjson.rc. + +res\hgjson.rc2 + This file contains resources that are not edited by Microsoft + Visual C++. You should place all resources not editable by + the resource editor in this file. + + +///////////////////////////////////////////////////////////////////////////// + +The application wizard creates one dialog class: + +hgjsonDlg.h, hgjsonDlg.cpp - the dialog + These files contain your ChgjsonDlg class. This class defines + the behavior of your application's main dialog. The dialog's template is + in hgjson.rc, which can be edited in Microsoft Visual C++. + +///////////////////////////////////////////////////////////////////////////// + +Other Features: + +ActiveX Controls + The application includes support to use ActiveX controls. + +///////////////////////////////////////////////////////////////////////////// + +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named hgjson.pch and a precompiled types file named StdAfx.obj. + +Resource.h + This is the standard header file, which defines new resource IDs. + Microsoft Visual C++ reads and updates this file. + +hgjson.manifest + Application manifest files are used by Windows XP to describe an applications + dependency on specific versions of Side-by-Side assemblies. The loader uses this + information to load the appropriate assembly from the assembly cache or private + from the application. The Application manifest maybe included for redistribution + as an external .manifest file that is installed in the same folder as the application + executable or it may be included in the executable in the form of a resource. +///////////////////////////////////////////////////////////////////////////// + +Other notes: + +The application wizard uses "TODO:" to indicate parts of the source code you +should add to or customize. + +If your application uses MFC in a shared DLL, you will need +to redistribute the MFC DLLs. If your application is in a language +other than the operating system's locale, you will also have to +redistribute the corresponding localized resources mfc110XXX.DLL. +For more information on both of these topics, please see the section on +redistributing Visual C++ applications in MSDN documentation. + +///////////////////////////////////////////////////////////////////////////// diff --git a/pc/code_twain/sln/hgjson/hgjson.cpp b/pc/code_twain/sln/hgjson/hgjson.cpp new file mode 100644 index 0000000..3c60e09 --- /dev/null +++ b/pc/code_twain/sln/hgjson/hgjson.cpp @@ -0,0 +1,103 @@ + +// hgjson.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "hgjson.h" +#include "CDlgMain.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// ChgjsonApp + +BEGIN_MESSAGE_MAP(ChgjsonApp, CWinApp) + ON_COMMAND(ID_HELP, &CWinApp::OnHelp) +END_MESSAGE_MAP() + + +// ChgjsonApp construction + +ChgjsonApp::ChgjsonApp() +{ + // support Restart Manager + m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; + + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + + +// The one and only ChgjsonApp object + +ChgjsonApp theApp; + + +// ChgjsonApp initialization + +BOOL ChgjsonApp::InitInstance() +{ + AfxOleInit(); + // InitCommonControlsEx() is required on Windows XP if an application + // manifest specifies use of ComCtl32.dll version 6 or later to enable + // visual styles. Otherwise, any window creation will fail. + INITCOMMONCONTROLSEX InitCtrls; + InitCtrls.dwSize = sizeof(InitCtrls); + // Set this to include all the common control classes you want to use + // in your application. + InitCtrls.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&InitCtrls); + + CWinApp::InitInstance(); + + + AfxEnableControlContainer(); + + // Create the shell manager, in case the dialog contains + // any shell tree view or shell list view controls. + CShellManager *pShellManager = new CShellManager; + + // Activate "Windows Native" visual manager for enabling themes in MFC controls + CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need + // Change the registry key under which our settings are stored + // TODO: You should modify this string to be something appropriate + // such as the name of your company or organization + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + CDlgMain dlg; + m_pMainWnd = &dlg; + INT_PTR nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: Place code here to handle when the dialog is + // dismissed with OK + } + else if (nResponse == IDCANCEL) + { + // TODO: Place code here to handle when the dialog is + // dismissed with Cancel + } + else if (nResponse == -1) + { + TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n"); + TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n"); + } + + // Delete the shell manager created above. + if (pShellManager != NULL) + { + delete pShellManager; + } + + // Since the dialog has been closed, return FALSE so that we exit the + // application, rather than start the application's message pump. + return FALSE; +} + diff --git a/pc/code_twain/sln/hgjson/hgjson.h b/pc/code_twain/sln/hgjson/hgjson.h new file mode 100644 index 0000000..1a26657 --- /dev/null +++ b/pc/code_twain/sln/hgjson/hgjson.h @@ -0,0 +1,32 @@ + +// hgjson.h : main header file for the PROJECT_NAME application +// + +#pragma once + +#ifndef __AFXWIN_H__ + #error "include 'stdafx.h' before including this file for PCH" +#endif + +#include "resource.h" // main symbols + + +// ChgjsonApp: +// See hgjson.cpp for the implementation of this class +// + +class ChgjsonApp : public CWinApp +{ +public: + ChgjsonApp(); + +// Overrides +public: + virtual BOOL InitInstance(); + +// Implementation + + DECLARE_MESSAGE_MAP() +}; + +extern ChgjsonApp theApp; \ No newline at end of file diff --git a/pc/code_twain/sln/hgjson/hgjson.rc b/pc/code_twain/sln/hgjson/hgjson.rc new file mode 100644 index 0000000..c776e7f Binary files /dev/null and b/pc/code_twain/sln/hgjson/hgjson.rc differ diff --git a/pc/code_twain/sln/hgjson/hgjson.vcxproj b/pc/code_twain/sln/hgjson/hgjson.vcxproj new file mode 100644 index 0000000..54e517d --- /dev/null +++ b/pc/code_twain/sln/hgjson/hgjson.vcxproj @@ -0,0 +1,166 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D3579C48-F5AB-4F15-9B49-A2970FBA76C5} + hgjson + MFCProj + 10.0 + + + + Application + true + v142 + Unicode + Dynamic + + + Application + false + v142 + true + Unicode + Dynamic + + + + + + + + + + + + + true + $(ProjectDir)..\..\sdk\Include\;$(ProjectDir)..\..\..\..\sdk\Include\;$(IncludePath) + $(ProjectDir)..\..\sdk\lib\;$(LibraryPath) + $(OutDir)$(ProjectName)\ + $(ProjectDir)..\..\solution\$(Configuration)\ + + + false + $(ProjectDir)..\..\sdk\Include\;$(ProjectDir)..\..\..\..\sdk\Include\;$(IncludePath) + $(ProjectDir)..\..\sdk\lib\;$(LibraryPath) + $(OutDir)$(ProjectName)\ + $(ProjectDir)..\..\solution\$(Configuration)\ + + + + Use + Level3 + Disabled + WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + true + 4996 + + + Windows + true + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + true + 4996 + + + Windows + true + true + true + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pc/code_twain/sln/hgjson/hgjson.vcxproj.filters b/pc/code_twain/sln/hgjson/hgjson.vcxproj.filters new file mode 100644 index 0000000..345a314 --- /dev/null +++ b/pc/code_twain/sln/hgjson/hgjson.vcxproj.filters @@ -0,0 +1,114 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/pc/code_twain/sln/hgjson/hgjsonDlg.cpp b/pc/code_twain/sln/hgjson/hgjsonDlg.cpp new file mode 100644 index 0000000..6f26202 --- /dev/null +++ b/pc/code_twain/sln/hgjson/hgjsonDlg.cpp @@ -0,0 +1,8370 @@ + +// hgjsonDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "hgjson.h" +#include "hgjsonDlg.h" +#include "afxdialogex.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif +#pragma warning(disable: 4996) + +#include "DlgInput.h" + +#include +#include +#include +#include +#include +#include "../../../../code_device/hgdriver/hgdev/scanner_setting.h" + +#define TREE_ITEM_PRODUCT MAKELONG(MAKEWORD('P', 'R'), MAKEWORD('D', 'T')) +#define TREE_ITEM_GROUP MAKELONG(MAKEWORD('G', 'R'), MAKEWORD('U', 'P')) +#define TREE_ITEM_CONFIG MAKELONG(MAKEWORD('I', 'T'), MAKEWORD('E', 'M')) + +#define OPT_TITLE_PREFIX L"OPTION_TITLE_" // + py +#define OPT_VALUE_PREFIX L"OPTION_VALUE_" // + title_py + py + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// sane data types: + +const wchar_t* g_opt_unit_name[] = { // according to SANE_Unit + L"None", + L"Pixel", + L"Bit", + L"Millimeters", + L"DPI", + L"Percent", + L"Microsecond" +}; +const wchar_t* g_opt_field[] = { + L"Common", + L"ImageProc", + L"Hardware" +}; +static const wchar_t* unit_name(int ind) +{ + if (ind < 0 || ind >= _countof(g_opt_unit_name)) + ind = 0; + + return g_opt_unit_name[ind]; +} +static int unit_index(const wchar_t* name) +{ + for (int i = 0; i < _countof(g_opt_unit_name); ++i) + { + if (wcsicmp(name, g_opt_unit_name[i]) == 0) + return i; + } + + return 0; +} +static const wchar_t* field_name(int ind) +{ + if (ind < 0 || ind >= _countof(g_opt_field)) + ind = 0; + + return g_opt_field[ind]; +} +static int field_index(const wchar_t* name) +{ + for (int i = 0; i < _countof(g_opt_field); ++i) + { + if (wcsicmp(name, g_opt_field[i]) == 0) + return i; + } + + return 0; +} + +namespace coding +{ + INTER_MODULE_CALLBACK(get_string) + { + *((std::string*)param) += std::string(data, len); + + return inter_module_data::SET_RESULT_CONTINUE; + } + INTER_MODULE_CALLBACK(get_wstring) + { + *((std::wstring*)param) += std::wstring((const wchar_t*)data, len / 2); + + return inter_module_data::SET_RESULT_CONTINUE; + } + typedef struct _clp_d + { + bool file; + std::wstring cont; + }CLPD, *LPCLPD; + INTER_MODULE_CALLBACK(get_clipboard_content) + { + LPCLPD pclpd = (LPCLPD)param; + + if (total == CF_TEXT) + { + coding_util::ansi_2_unicode(data, get_wstring, &pclpd->cont); + pclpd->file = false; + } + else if (total == CF_UNICODETEXT) + { + pclpd->cont = std::wstring((const wchar_t*)data, len / 2); + pclpd->file = false; + } + else if (total == CF_HDROP) + { + pclpd->cont = std::wstring((const wchar_t*)data, len / 2); + pclpd->file = true; + } + + return inter_module_data::SET_RESULT_STOP; + } + std::wstring name_from_depend_exp(const std::wstring& depend_exp) + { + std::wstring name(L""); + size_t pos = depend_exp.find(L"="); + + if (pos == std::wstring::npos) + { + pos = depend_exp.find(L"!"); + if (pos == std::wstring::npos) + { + pos = depend_exp.find(L">"); + if (pos == std::wstring::npos) + { + pos = depend_exp.find(L"<"); + } + } + } + if (pos != std::wstring::npos) + { + name = depend_exp.substr(0, pos); + } + + return std::move(name); + } + + int string_need_bytes(const wchar_t* str) + { + int len = lstrlenW(str) * 3; + + len += 15; + len /= 8; + len *= 8; + + return len; + } + + std::string u2a(const wchar_t* u) + { + std::string a(""); + + coding_util::unicode_2_ansi(u, get_string, &a); + + return a; + } + std::string u2utf8(const wchar_t* u) + { + std::string a(""); + + coding_util::unicode_2_utf8(u, get_string, &a); + + return a; + } + std::wstring a2u(const char* a) + { + std::wstring u(L""); + + coding_util::ansi_2_unicode(a, get_wstring, &u); + + return u; + } + std::wstring utf82u(const char* utf8) + { + std::wstring u(L""); + + coding_util::utf8_2_unicode(utf8, get_wstring, &u); + + return u; + } + + // Base;Light;ImageProcess;Feeder; + static const wchar_t* group_name_[] = {L"none", L"base", L"light", L"imgproc", L"feeder"}; + const wchar_t* group_name(int ind) + { + if (ind >= 0 && ind < _countof(group_name_)) + return group_name_[ind]; + else + return group_name_[0]; + } + int group_index(const wchar_t* name) + { + for (int i = 0; i < _countof(group_name_); ++i) + { + if (wcsicmp(name, group_name_[i]) == 0) + return i; + } + + const wchar_t* hz_grp[] = { L"\u57FA\u672C\u8BBE\u7F6E", L"\u4EAE\u5EA6", L"\u56FE\u50CF\u5904\u7406", L"\u9001\u7EB8\u65B9\u5F0F\u8BBE\u7F6E" }; + for (int i = 0; i < _countof(hz_grp); ++i) + { + if (wcsicmp(name, hz_grp[i]) == 0) + return i + 1; + } + + return 0; + } +} + +namespace hz_2_py +{ + std::string findLetter(int nCode) + { + std::string strValue; + switch (nCode) + { + case 6325: + case 6436: + case 7571: + case 7925: + strValue = "A"; + break; + case 6263: + case 6440: + case 7040: + case 7208: + case 7451: + case 7733: + case 7945: + case 8616: + strValue = "AI"; + break; + case 5847: + case 5991: + case 6278: + case 6577: + case 6654: + case 7281: + case 7907: + case 8038: + case 8786: + strValue = "AN"; + break; + strValue = "ANG"; + break; + case 5974: + case 6254: + case 6427: + case 6514: + case 6658: + case 6959: + case 7033: + case 7081: + case 7365: + case 8190: + case 8292: + case 8643: + case 8701: + case 8773: + strValue = "AO"; + break; + case 6056: + case 6135: + case 6517: + case 7857: + case 8446: + case 8649: + case 8741: + strValue = "BA"; + break; + case 6267: + case 6334: + case 7494: + strValue = "BAI"; + break; + case 5870: + case 5964: + case 7851: + case 8103: + case 8113: + case 8418: + strValue = "BAN"; + break; + case 6182: + case 6826: + strValue = "BANG"; + break; + case 6165: + case 7063: + case 7650: + case 8017: + case 8157: + case 8532: + case 8621: + strValue = "BAO"; + break; + case 5635: + case 5873: + case 5893: + case 5993: + case 6141: + case 6703: + case 7753: + case 8039: + case 8156: + case 8645: + case 8725: + strValue = "BEI"; + break; + case 5946: + case 5948: + case 7458: + case 7928: + strValue = "BEN"; + break; + case 6452: + case 7420: + strValue = "BENG"; + break; + case 5616: + case 5734: + case 6074: + case 6109: + case 6221: + case 6333: + case 6357: + case 6589: + case 6656: + case 6725: + case 6868: + case 6908: + case 6986: + case 6994: + case 7030: + case 7052: + case 7221: + case 7815: + case 7873: + case 7985: + case 8152: + case 8357: + case 8375: + case 8387: + case 8416: + case 8437: + case 8547: + case 8734: + strValue = "BI"; + break; + case 5650: + case 5945: + case 6048: + case 6677: + case 6774: + case 7134: + case 7614: + case 7652: + case 7730: + case 7760: + case 8125: + case 8159: + case 8289: + case 8354: + case 8693: + strValue = "BIAN"; + break; + case 7027: + case 7084: + case 7609: + case 7613: + case 7958: + case 7980: + case 8106: + case 8149: + case 8707: + case 8752: + strValue = "BIAO"; + break; + case 8531: + strValue = "BIE"; + break; + case 5747: + case 6557: + case 7145: + case 7167: + case 7336: + case 7375: + case 7587: + case 7957: + case 8738: + case 8762: + strValue = "BIN"; + break; + case 5787: + case 5891: + case 6280: + strValue = "BING"; + break; + case 5781: + case 6403: + case 6636: + case 7362: + case 7502: + case 7771: + case 7864: + case 8030: + case 8404: + case 8543: + case 8559: + strValue = "BO"; + break; + case 6318: + case 6945: + case 7419: + case 7446: + case 7848: + case 7863: + case 8519: + strValue = "BU"; + break; + case 6474: + case 7769: + strValue = "CA"; + break; + strValue = "CAI"; + break; + case 6978: + case 7078: + case 7218: + case 8451: + case 8785: + strValue = "CAN"; + break; + case 5687: + strValue = "CANG"; + break; + case 6448: + case 6878: + case 8309: + case 8429: + strValue = "CAO"; + break; + case 6692: + strValue = "CE"; + break; + case 6515: + case 6825: + strValue = "CEN"; + break; + case 6465: + strValue = "CENG"; + break; + case 6639: + case 6766: + case 7017: + case 7230: + case 7311: + case 7322: + case 7363: + case 7942: + case 7979: + case 8135: + strValue = "CHA"; + break; + case 5713: + case 7846: + case 8091: + case 8218: + strValue = "CHAI"; + break; + case 5770: + case 5838: + case 6159: + case 6667: + case 6893: + case 6904: + case 6981: + case 7031: + case 7086: + case 7472: + case 7688: + case 7966: + case 8324: + case 8580: + strValue = "CHAN"; + break; + case 5686: + case 5943: + case 6041: + case 6137: + case 6660: + case 6568: + case 6749: + case 7029: + case 7047: + case 7438: + case 7509: + case 8680: + strValue = "CHANG"; + break; + case 6687: + case 7443: + case 8173: + strValue = "CHAO"; + break; + case 5969: + case 7726: + strValue = "CHE"; + break; + case 5840: + case 5863: + case 6251: + case 6433: + case 6923: + case 7201: + case 7320: + case 7755: + case 8619: + strValue = "CHEN"; + break; + case 5609: + case 5984: + case 7239: + case 7263: + case 7583: + case 7810: + case 7881: + case 7905: + case 8146: + case 8241: + case 8508: + strValue = "CHENG"; + break; + case 5749: + case 6015: + case 6061: + case 6319: + case 6374: + case 6420: + case 6445: + case 6633: + case 7042: + case 7523: + case 7787: + case 8023: + case 8101: + case 8161: + case 8231: + case 8304: + case 8355: + case 8388: + case 8489: + case 8556: + case 8746: + strValue = "CHI"; + break; + case 6091: + case 6671: + case 6731: + case 8409: + case 8430: + strValue = "CHONG"; + break; + case 5717: + case 6492: + case 6716: + case 8112: + case 8637: + strValue = "CHOU"; + break; + case 5601: + case 5927: + case 6680: + case 6732: + case 7109: + case 7238: + case 7290: + case 7343: + case 8150: + case 8260: + case 8573: + case 8777: + strValue = "CHU"; + break; + case 6285: + case 6408: + case 7590: + case 8563: + strValue = "CHUAI"; + break; + case 6622: + case 6955: + case 7516: + case 7843: + case 8413: + strValue = "CHUAN"; + break; + case 6675: + strValue = "CHUANG"; + break; + case 5879: + case 7302: + case 7319: + strValue = "CHUI"; + break; + case 6127: + case 8040: + case 8277: + strValue = "CHUN"; + break; + case 7401: + case 8554: + case 8626: + strValue = "CHUO"; + break; + strValue = "CI"; + break; + case 6075: + case 6358: + case 7684: + case 8043: + case 8457: + strValue = "4337 "; + break; + case 6042: + case 6840: + case 7085: + case 7193: + case 7214: + case 7240: + strValue = "CONG"; + break; + case 7308: + case 7403: + case 7577: + strValue = "COU"; + break; + case 6180: + case 6562: + case 6607: + case 7367: + case 8501: + case 8530: + case 8577: + strValue = "CU"; + break; + case 5764: + case 6305: + case 7664: + case 7973: + strValue = "CUAN"; + break; + case 6718: + case 6145: + case 6393: + case 7213: + case 7333: + case 7505: + case 8631: + strValue = "CUI"; + break; + case 6666: + case 8169: + strValue = "CUN"; + break; + case 5640: + case 6547: + case 7566: + case 7917: + case 7983: + case 8078: + case 8526: + case 8567: + strValue = "CUO"; + break; + case 6239: + case 6353: + case 6410: + case 6682: + case 7007: + case 8155: + case 8346: + case 8716: + case 8718: + strValue = "DA"; + break; + case 6004: + case 6316: + case 6523: + case 6942: + case 7110: + case 7173: + case 8776: + strValue = "DAI"; + break; + case 5757: + case 6144: + case 6402: + case 7373: + case 7470: + case 7781: + case 8067: + case 8087: + case 8185: + case 8376: + strValue = "DAN"; + break; + case 5852: + case 5942: + case 6148: + case 6920: + case 7724: + case 7885: + case 8141: + strValue = "DANG"; + break; + case 6322: + case 6665: + case 7514: + case 8478: + strValue = "DAO"; + break; + case 7929: + strValue = "DE"; + break; + case 6466: + case 6556: + case 7413: + case 7767: + case 7975: + case 8403: + strValue = "DENG"; + break; + case 5621: + case 5765: + case 5814: + case 5848: + case 5901: + case 5970: + case 6122: + case 6454: + case 7023: + case 7116: + case 7260: + case 7306: + case 7475: + case 7738: + case 7758: + case 7791: + case 7965: + case 8438: + case 8730: + strValue = "DI"; + break; + case 6439: + strValue = "DIA"; + break; + case 5871: + case 5967: + case 6559: + case 7172: + case 7868: + case 8116: + case 8118: + case 8401: + case 8558: + strValue = "DIAN"; + break; + case 7886: + case 8585: + case 8684: + strValue = "DIAO"; + break; + case 5976: + case 6006: + case 6273: + case 6409: + case 7526: + case 8012: + case 8183: + case 8562: + case 8688: + strValue = "DIE"; + break; + case 5674: + case 6404: + case 7164: + case 7575: + case 7754: + case 7814: + case 8059: + case 8184: + case 8490: + strValue = "DING"; + break; + case 7891: + strValue = "DIU"; + break; + case 5977: + case 6343: + case 6520: + case 6528: + case 7517: + case 7543: + case 7556: + case 7747: + case 8020: + strValue = "DONG"; + break; + case 6190: + case 8128: + case 8229: + case 8391: + strValue = "DOU"; + break; + case 6022: + case 6429: + case 6834: + case 7292: + case 7525: + case 8328: + case 8338: + case 8739: + case 8782: + strValue = "DU"; + break; + case 7318: + case 7649: + case 8393: + strValue = "DUAN"; + break; + case 7701: + case 7713: + case 7752: + strValue = "DUI"; + break; + case 6771: + case 7632: + case 7727: + case 7766: + case 7779: + case 7970: + case 8527: + strValue = "DUN"; + break; + case 6345: + case 6365: + case 6785: + case 7122: + case 7876: + case 8154: + case 8566: + strValue = "DUO"; + break; + case 5612: + case 5832: + case 5844: + case 5949: + case 6035: + case 6113: + case 6164: + case 6332: + case 6721: + case 6977: + case 7025: + case 7378: + case 7581: + case 7916: + case 7941: + case 8042: + case 8206: + case 8689: + strValue = "E"; + break; + case 6176: + case 6284: + strValue = "EN"; + break; + case 5706: + case 6939: + case 7177: + case 7879: + case 8025: + case 8660: + strValue = "ER"; + break; + case 5950: + case 7732: + strValue = "FA"; + break; + case 6212: + case 6232: + case 6506: + case 7283: + case 7660: + case 7818: + case 8576: + strValue = "FAN"; + break; + case 5890: + case 7242: + case 7853: + case 8419: + case 8648: + strValue = "FANG"; + break; + case 6032: + case 6584: + case 6713: + case 6839: + case 6990: + case 7119: + case 7328: + case 7572: + case 7619: + case 7673: + case 7948: + case 8082: + case 8267: + case 8385: + case 8468: + case 8613: + case 8678: + strValue = "FEI"; + break; + case 5739: + case 6915: + case 7291: + case 8687: + case 8787: + strValue = "FEN"; + break; + case 5726: + case 5926: + case 6155: + case 6384: + case 6767: + case 7731: + strValue = "FENG"; + break; + strValue = "FO"; + break; + case 8330: + strValue = "FOU"; + break; + case 5775: + case 5776: + case 5914: + case 6029: + case 6062: + case 6119: + case 6142: + case 6252: + case 6327: + case 6505: + case 6686: + case 6870: + case 6985: + case 7058: + case 7066: + case 7106: + case 7108: + case 7285: + case 7471: + case 7680: + case 7741: + case 7774: + case 7775: + case 7823: + case 7991: + case 8005: + case 8222: + case 8261: + case 8280: + case 8283: + case 8479: + case 8535: + case 8538: + case 8654: + case 8691: + strValue = "FU"; + break; + case 6246: + case 7056: + case 7057: + case 7424: + case 7837: + strValue = " GA"; + break; + case 5604: + case 5875: + case 5982: + case 7414: + case 7464: + strValue = "GAI"; + break; + case 5965: + case 6053: + case 6247: + case 6306: + case 6779: + case 6838: + case 6887: + case 7104: + case 7347: + case 7426: + case 7723: + case 8065: + case 8491: + strValue = "GAN"; + break; + case 7716: + case 7824: + case 8364: + strValue = "GANG"; + break; + case 5626: + case 5830: + case 5912: + case 6227: + case 7141: + case 7332: + case 7334: + case 7429: + case 7915: + strValue = "GAO"; + break; + case 5610: + case 5678: + case 5933: + case 5957: + case 6010: + case 6435: + case 7092: + case 7501: + case 7585: + case 7749: + case 7951: + case 8143: + case 8220: + case 8420: + case 8732: + strValue = "GE"; + break; + strValue = "GEI"; + break; + case 5608: + case 6102: + case 6371: + case 8462: + strValue = "GEN"; + break; + case 6376: + case 6657: + case 7114: + case 8665: + strValue = "GENG"; + break; + case 7178: + case 7537: + case 8228: + case 8601: + strValue = "GONG"; + break; + case 5694: + case 5824: + case 6524: + case 6960: + case 7037: + case 7135: + case 7259: + case 7477: + case 7616: + case 8349: + case 8384: + case 8724: + strValue = "GOU"; + break; + case 5637: + case 5812: + case 6152: + case 6536: + case 6773: + case 7284: + case 7379: + case 7484: + case 7486: + case 7591: + case 7617: + case 7813: + case 7825: + case 7860: + case 7932: + case 8019: + case 8083: + case 8233: + case 8494: + case 8593: + case 8681: + case 8729: + strValue = "GU"; + break; + case 5652: + case 5820: + case 6341: + case 7273: + case 7550: + case 8027: + strValue = "GUA"; + break; + strValue = "GUAI"; + break; + case 5736: + case 6124: + case 6272: + case 6842: + case 7834: + case 8057: + case 8170: + case 8704: + strValue = "GUAN"; + break; + case 6359: + case 6578: + case 7270: + case 7555: + strValue = "GUANG"; + break; + case 5648: + case 5659: + case 6649: + case 7003: + case 7277: + case 7433: + case 7448: + case 8007: + case 8394: + case 8657: + case 8712: + strValue = "GUI"; + break; + case 5782: + case 7121: + case 7762: + case 8671: + strValue = "GUN"; + break; + case 5769: + case 6266: + case 6335: + case 6494: + case 6538: + case 6603: + case 7304: + case 7529: + case 8188: + case 8268: + case 8269: + strValue = "GUO"; + break; + case 7894: + strValue = "HA"; + break; + case 6443: + case 7560: + case 8516: + strValue = "HAI"; + break; + case 5885: + case 6153: + case 6294: + case 6759: + case 6911: + case 7447: + case 7642: + case 8192: + case 8205: + case 8232: + case 8793: + strValue = "HAN"; + break; + case 6776: + case 7112: + case 8194: + strValue = "HANG"; + break; + case 6179: + case 6222: + case 6438: + case 6467: + case 6909: + case 6916: + case 7427: + case 8009: + case 8211: + case 8226: + strValue = "HAO"; + break; + case 5813: + case 5932: + case 5954: + case 6432: + case 6756: + case 7434: + case 7833: + case 8202: + case 8234: + case 8471: + strValue = "HE"; + break; + strValue = "HEI"; + break; + strValue = "HEN"; + break; + case 6231: + case 7181: + case 7276: + strValue = "HENG"; + break; + case 5768: + case 5774: + case 5807: + case 6106: + case 6214: + case 6216: + case 6740: + case 6792: + strValue = "HONG"; + break; + case 6009: + case 6565: + case 6943: + case 8090: + case 8383: + case 8455: + case 8655: + case 8731: + strValue = "HOU"; + break; + case 5792: + case 6392: + case 6481: + case 6518: + case 6609: + case 6679: + case 6717: + case 6816: + case 6879: + case 7190: + case 7346: + case 7385: + case 7618: + case 7635: + case 7646: + case 7670: + case 7672: + case 7679: + case 8013: + case 8032: + case 8041: + case 8055: + case 8343: + case 8513: + case 8590: + strValue = "HU"; + break; + case 7072: + case 7275: + case 7725: + case 7892: + strValue = "HUA"; + break; + case 8555: + strValue = "HUAI"; + break; + case 5928: + case 6140: + case 6307: + case 6487: + case 6621: + case 6801: + case 6829: + case 6881: + case 6930: + case 6953: + case 7157: + case 7944: + case 8673: + case 8763: + strValue = "HUAN"; + break; + case 5882: + case 6569: + case 6850: + case 6874: + case 6956: + case 7211: + case 7533: + case 8105: + case 8308: + case 8382: + case 8692: + strValue = "HUANG"; + break; + case 5822: + case 6078: + case 6086: + case 6205: + case 6352: + case 6360: + case 6425: + case 6736: + case 6807: + case 6811: + case 6971: + case 7132: + case 7185: + case 7445: + case 7703: + case 8219: + case 8319: + case 8766: + strValue = "HUI"; + break; + case 5827: + case 6638: + case 6752: + case 6867: + strValue = "HUN"; + break; + case 5669: + case 6229: + case 6311: + case 6475: + case 6623: + case 7856: + case 7933: + case 7976: + case 8175: + case 8322: + strValue = "HUO"; + break; + case 5629: + case 5632: + case 5662: + case 5705: + case 5742: + case 5952: + case 6024: + case 6033: + case 6193: + case 6210: + case 6265: + case 6320: + case 6350: + case 6383: + case 6507: + case 6553: + case 6809: + case 6976: + case 7087: + case 7160: + case 7165: + case 7314: + case 7374: + case 7410: + case 7411: + case 7469: + case 7473: + case 7487: + case 7620: + case 7722: + case 7831: + case 7990: + case 8002: + case 8104: + case 8217: + case 8337: + case 8339: + case 8463: + case 8550: + case 8611: + case 8661: + case 8674: + case 8757: + case 8768: + strValue = "JI"; + break; + case 5704: + case 5903: + case 6171: + case 6521: + case 6804: + case 6940: + case 7176: + case 7409: + case 7546: + case 7702: + case 7882: + case 7956: + case 8072: + case 8142: + case 8244: + case 8353: + case 8434: + case 8542: + strValue = "JIA"; + break; + case 5752: + case 5841: + case 5857: + case 6149: + case 6183: + case 6286: + case 6853: + case 6931: + case 6932: + case 7144: + case 7237: + case 7305: + case 7407: + case 7415: + case 7480: + case 7489: + case 7506: + case 7576: + case 7790: + case 7921: + case 8047: + case 8148: + case 8340: + case 8469: + case 8534: + case 8561: + case 8668: + case 8721: + strValue = "JIAN"; + break; + case 6092: + case 6814: + case 7113: + case 7154: + case 7481: + case 7768: + case 8180: + case 8461: + case 8488: + strValue = "JIANG"; + break; + case 5714: + case 5753: + case 6020: + case 6090: + case 6256: + case 6461: + case 6572: + case 7015: + case 7524: + case 8008: + case 8052: + case 8252: + case 8520: + case 8551: + case 8662: + strValue = "JIAO"; + break; + case 5806: + case 5821: + case 6255: + case 6414: + case 7028: + case 7061: + case 7278: + case 7757: + case 8060: + case 8201: + case 8227: + case 8441: + case 8658: + case 8726: + strValue = "JIE"; + break; + case 5865: + case 6103: + case 6132: + case 6468: + case 6643: + case 6659: + case 7138: + case 7210: + case 7340: + case 7465: + case 7478: + case 8138: + strValue = "JIN"; + break; + case 5751: + case 5869: + case 6128: + case 6616: + case 6729: + case 6794: + case 6941: + case 6982: + case 7026: + case 7534: + case 7554: + case 7570: + case 7626: + strValue = "JIANG"; + break; + case 6936: + case 7671: + strValue = "JIONG"; + break; + case 5754: + case 6417: + case 6746: + case 7249: + case 7274: + case 8015: + case 8053: + case 8481: + case 8761: + strValue = "JIU"; + break; + case 5738: + case 5810: + case 6036: + case 6058: + case 6076: + case 6268: + case 6965: + case 6980: + case 7202: + case 7307: + case 7316: + case 7323: + case 7357: + case 7381: + case 7488: + case 7611: + case 7850: + case 7924: + case 8022: + case 8132: + case 8153: + case 8482: + case 8522: + case 8565: + case 8620: + case 8634: + case 8722: + strValue = "JU"; + break; + case 5918: + case 6590: + case 6824: + case 7280: + case 7835: + case 7935: + case 7952: + case 8633: + strValue = "JUAN"; + break; + case 5642: + case 5667: + case 5860: + case 5939: + case 6207: + case 6421: + case 6457: + case 6469: + case 6540: + case 6617: + case 7062: + case 7169: + case 7286: + case 7351: + case 7663: + case 7967: + case 8574: + case 8591: + strValue = "JUE"; + break; + case 6260: + case 8168: + case 8362: + case 8769: + strValue = "JUN"; + break; + case 5671: + case 6339: + case 7544: + strValue = "KA"; + break; + case 5660: + case 5978: + case 6160: + case 6673: + case 6693: + case 7888: + case 7920: + case 7939: + strValue = "KAI"; + break; + case 5709: + case 6108: + case 7412: + case 7772: + case 7811: + strValue = "KAN"; + break; + case 5688: + case 6742: + case 7854: + strValue = "KANG"; + break; + case 6974: + case 7264: + case 7491: + case 7877: + strValue = "KAO"; + break; + case 6430: + case 6519: + case 6701: + case 6859: + case 7076: + case 7128: + case 7170: + case 7380: + case 7520: + case 7807: + case 7861: + case 7930: + case 7993: + case 8066: + case 8129: + case 8204: + case 8282: + case 8733: + strValue = "KE"; + break; + case 8144: + strValue = "KEN"; + break; + case 7912: + strValue = "KENG"; + break; + case 5737: + case 6539: + case 8377: + strValue = "KONG"; + break; + case 6050: + case 6202: + case 6321: + case 7778: + case 8356: + strValue = "KOU"; + break; + case 5658: + case 6005: + case 6423: + case 7111: + case 8728: + strValue = "KU"; + break; + case 5708: + strValue = "KUA"; + break; + case 5665: + case 5906: + case 6364: + case 6586: + case 7558: + strValue = "KUAI"; + break; + case 8737: + strValue = "KUAN"; + break; + case 5818: + case 5831: + case 5887: + case 5959: + case 6237: + case 6349: + case 7094: + case 7460: + strValue = "KUANG"; + break; + case 5624: + case 5649: + case 5771: + case 6162: + case 6281: + case 6413: + case 6416: + case 6720: + case 6951: + case 7450: + case 7805: + case 8606: + case 8743: + strValue = "KUI"; + break; + case 6204: + case 6245: + case 6458: + case 6618: + case 6928: + case 7152: + case 7841: + case 8051: + strValue = "LIAO"; + break; + case 5793: + case 5988: + case 6270: + case 6354: + case 6803: + case 8483: + case 8581: + case 8764: + strValue = "LIE"; + break; + case 6194: + case 6388: + case 6555: + case 6662: + case 6733: + case 6964: + case 7361: + case 7405: + case 7602: + case 7812: + case 8452: + case 8579: + case 8775: + strValue = "LIN"; + break; + case 5925: + case 6063: + case 6342: + case 6482: + case 6786: + case 7117: + case 7258: + case 7289: + case 7418: + case 8186: + case 8240: + case 8465: + case 8676: + strValue = "LING"; + break; + case 6815: + case 6962: + case 7082: + case 7124: + case 7628: + case 7654: + case 7919: + case 7954: + case 8050: + case 8644: + strValue = "LIU"; + break; + case 5966: + case 6055: + case 6781: + case 7171: + case 7248: + case 7542: + case 7735: + case 8110: + strValue = "LONG"; + break; + case 5745: + case 6168: + case 6422: + case 6548: + case 7946: + case 8092: + case 8179: + case 8287: + case 8735: + strValue = "LOU"; + break; + case 6744: + case 7321: + case 7586: + case 7918: + case 7989: + case 8158: + strValue = "L"; + break; + case 5968: + case 6303: + case 6464: + case 6782: + case 6843: + case 6885: + case 6954: + case 7220: + case 7251: + case 7354: + case 7391: + case 7404: + case 7510: + case 7545: + case 7969: + case 8021: + case 8056: + case 8392: + case 8421: + case 8652: + strValue = "LU"; + break; + case 5785: + case 7014: + case 7279: + case 8029: + case 8639: + strValue = "LUAN"; + break; + strValue = "LE"; + break; + strValue = "LUN"; + break; + case 5732: + case 5789: + case 6093: + case 6259: + case 6291: + case 6604: + case 6788: + case 6880: + case 7183: + case 7301: + case 7565: + case 7961: + case 8107: + case 8635: + strValue = "LUO"; + break; + case 6328: + strValue = "M"; + break; + case 6373: + case 6579: + case 7054: + case 7231: + case 8301: + strValue = "MA"; + break; + case 5929: + case 6104: + case 8618: + strValue = "MAI"; + break; + case 6012: + case 6503: + case 7147: + case 7655: + case 7960: + case 8209: + case 8293: + case 8709: + case 8720: + strValue = "MAN"; + break; + case 5888: + case 6861: + case 7743: + case 8294: + strValue = "MANG"; + break; + case 5783: + case 6066: + case 6525: + case 6787: + case 7203: + case 7436: + case 7483: + case 7503: + case 7624: + case 7714: + case 7806: + case 8317: + case 8754: + strValue = "MAO"; + break; + case 6114: + case 6550: + case 6613: + case 6828: + case 6856: + case 7325: + case 7949: + case 8044: + case 8139: + case 8740: + strValue = "MEI"; + break; + case 6249: + case 7643: + case 7715: + case 7845: + strValue = "MEN"; + break; + case 5934: + case 6189: + case 6211: + case 6734: + case 7592: + case 7770: + case 8221: + case 8276: + case 8323: + case 8427: + case 8431: + strValue = "MENG"; + break; + case 5634: + case 5855: + case 6234: + case 6368: + case 6455: + case 6608: + case 6772: + case 6921: + case 6984: + case 7563: + case 7682: + case 8445: + case 8767: + case 8771: + strValue = "MI"; + break; + case 6770: + case 6837: + case 6847: + case 7579: + case 7777: + strValue = "MIAN"; + break; + case 6387: + case 6967: + case 7131: + case 7149: + case 7234: + case 7721: + case 7780: + case 8037: + strValue = "MIAO"; + break; + case 5631: + case 6367: + case 8326: + case 8390: + strValue = "MIE"; + break; + case 6069: + case 6526: + case 6741: + case 6793: + case 7137: + case 7168: + case 7175: + case 7710: + case 8710: + case 8628: + strValue = "MIN"; + break; + case 5804: + case 6088: + case 6873: + case 7452: + case 7808: + case 8504: + strValue = "MING"; + break; + strValue = "MIU"; + break; + case 5851: + case 6052: + case 6175: + case 6641: + case 7038: + case 7366: + case 7950: + case 7987: + case 8102: + case 8182: + case 8586: + case 8588: + case 8765: + strValue = "MO"; + break; + case 5716: + case 6372: + case 7788: + case 8254: + case 8290: + case 8642: + strValue = "MOU"; + break; + case 5679: + case 5973: + case 6057: + case 6769: + case 7504: + case 7866: + strValue = "MU"; + break; + case 6437: + strValue = "N"; + break; + case 6264: + case 7539: + case 7953: + case 8136: + strValue = "NA"; + break; + case 5630: + case 6021: + case 6133: + case 7245: + strValue = "NAI"; + break; + case 6411: + case 6478: + case 6479: + case 7310: + case 7578: + case 8279: + case 8486: + strValue = "NAN"; + break; + case 6313: + case 6476: + case 6646: + case 7457: + strValue = "NANG"; + break; + case 5611: + case 5981: + case 6346: + case 6614: + case 7207: + case 7748: + case 7883: + case 8245: + strValue = "NAO"; + break; + case 5811: + strValue = "NE"; + break; + strValue = "NEI"; + break; + case 7705: + strValue = "NEN"; + break; + strValue = "NENG"; + break; + case 5703: + case 5972: + case 6605: + case 6685: + case 7439: + case 7627: + case 7711: + case 7794: + case 7874: + case 8682: + strValue = "NI"; + break; + case 5605: + case 5994: + case 7393: + case 8004: + case 8651: + case 8683: + strValue = "NIAN"; + break; + strValue = "NIANG"; + break; + case 6064: + case 7053: + case 7569: + case 8433: + strValue = "NIAO"; + break; + case 5877: + case 6233: + case 6431: + case 8208: + case 8411: + case 8570: + strValue = "NIE"; + break; + strValue = "NIN"; + break; + case 5690: + case 6344: + case 6924: + case 8187: + strValue = "NING"; + break; + case 6580: + case 6678: + case 7004: + strValue = "NIU"; + break; + case 5715: + case 6370: + strValue = "NONG"; + break; + case 8181: + strValue = "NOU"; + break; + case 6983: + case 7032: + case 7059: + case 7069: + strValue = "NU"; + break; + case 7704: + case 7847: + case 8412: + strValue = "N"; + break; + strValue = "NUAN"; + break; + strValue = "NUE"; + break; + case 5748: + case 6289: + case 6386: + case 7927: + strValue = "NUO"; + break; + case 6424: + case 6462: + strValue = "O"; + break; + case 5809: + case 6670: + case 7417: + case 8178: + strValue = "OU"; + break; + case 6166: + case 7243: + case 8365: + strValue = "PA"; + break; + case 5729: + case 6169: + case 6363: + strValue = "PAI"; + break; + case 6761: + case 6790: + case 8140: + case 8165: + case 8320: + case 8571: + strValue = "PAN"; + break; + case 6561: + case 6872: + case 6944: + case 8306: + strValue = "PANG"; + break; + case 6243: + case 6583: + case 6650: + case 7567: + case 8069: + strValue = "PAO"; + break; + case 6446: + case 6490: + case 7623: + case 7934: + case 8512: + case 8612: + strValue = "PEI"; + break; + case 6852: + strValue = "PEN"; + break; + case 6001: + case 6456: + case 6681: + case 8318: + strValue = "PENG"; + break; + case 5607: + case 5682: + case 5880: + case 5892: + case 5915: + case 5960: + case 6017: + case 6037: + case 6308: + case 6472: + case 6647: + case 6836: + case 7039: + case 7102: + case 7233: + case 7422: + case 7802: + case 7828: + case 7875: + case 8117: + case 8166: + case 8223: + case 8271: + case 8589: + strValue = "PI"; + break; + case 5850: + case 7073: + case 7490: + case 7561: + case 8470: + case 8568: + strValue = "PIAN"; + break; + case 5666: + case 6449: + case 7046: + case 7146: + case 7372: + case 7809: + case 8310: + strValue = "PIAO"; + break; + case 6054: + case 7513: + strValue = "PIE"; + break; + case 7041: + case 6253: + case 7016: + case 7315: + case 7482: + case 8213: + strValue = "PIN"; + break; + case 5723: + case 7019: + case 7250: + case 8650: + strValue = "PING"; + break; + case 5647: + case 5922: + case 7174: + case 7839: + case 7862: + case 8011: + case 8345: + strValue = "PO"; + break; + case 5786: + case 6269: + strValue = "POU"; + break; + case 5773: + case 6459: + case 6863: + case 6907: + case 7217: + case 7511: + case 7968: + case 7972: + case 8575: + strValue = "PU"; + break; + case 5633: + case 5725: + case 5963: + case 6027: + case 6046: + case 6089: + case 6129: + case 6134: + case 6161: + case 6213: + case 6366: + case 6450: + case 6508: + case 6510: + case 6764: + case 6831: + case 7075: + case 7118: + case 7187: + case 7189: + case 7229: + case 7271: + case 7342: + case 7440: + case 7605: + case 7687: + case 7712: + case 7751: + case 8193: + case 8251: + case 8264: + case 8475: + case 8476: + case 8572: + case 8702: + case 8772: + strValue = "QI"; + break; + case 6154: + case 8736: + strValue = "QIA"; + break; + case 5727: + case 5761: + case 5868: + case 6023: + case 6045: + case 6071: + case 6271: + case 6509: + case 6705: + case 6727: + case 6925: + case 6926: + case 6929: + case 7155: + case 7293: + case 7541: + case 7709: + case 7852: + case 8215: + case 8373: + strValue = "QIAN"; + break; + case 6762: + case 7045: + case 7341: + case 7408: + case 7633: + case 7926: + case 7947: + case 7974: + case 8163: + case 8262: + case 8439: + case 8536: + strValue = "QIANG"; + break; + case 5668: + case 5829: + case 5859: + case 6081: + case 6529: + case 6724: + case 6730: + case 7352: + case 7745: + case 8546: + case 8719: + strValue = "QIAO"; + break; + case 5907: + case 6711: + case 7010: + case 7492: + case 7938: + case 8370: + strValue = "QIE"; + break; + case 6043: + case 6276: + case 6336: + case 6426: + case 6463: + case 6858: + case 7353: + case 7923: + case 8291: + case 8432: + strValue = "QIN"; + break; + case 6060: + case 6485: + case 7349: + case 7764: + case 8263: + case 8332: + case 8368: + case 8605: + case 8675: + case 8784: + strValue = "QING"; + break; + case 5886: + case 6068: + case 8123: + case 8243: + case 8344: + case 8528: + case 8638: + strValue = "QIONG"; + break; + case 5720: + case 5947: + case 6576: + case 6848: + case 6947: + case 6957: + case 7317: + case 7468: + case 8216: + case 8239: + case 8288: + case 8435: + case 8460: + case 8690: + case 8792: + strValue = "QIU"; + break; + case 5816: + case 5930: + case 6201: + case 6230: + case 6511: + case 6573: + case 6754: + case 7219: + case 7479: + case 7512: + case 7552: + case 7678: + case 7765: + case 8119: + case 8248: + case 8329: + case 8480: + case 8636: + case 8781: + strValue = "QU"; + break; + case 5825: + case 6085: + case 6710: + case 7125: + case 7390: + case 7816: + case 7893: + case 8273: + case 8360: + case 8760: + strValue = "QUAN"; + break; + case 6755: + case 6758: + case 7708: + strValue = "QUE"; + break; + case 6950: + strValue = "QUN"; + break; + case 6059: + case 8237: + case 8755: + strValue = "RAN"; + break; + case 7692: + case 8006: + strValue = "RANG"; + break; + case 6073: + case 7012: + case 7267: + strValue = "RAO"; + break; + strValue = "RE"; + break; + case 5680: + case 6083: + case 6156: + case 6631: + case 7377: + case 7994: + case 8137: + strValue = "REN"; + break; + strValue = "RENG"; + break; + strValue = "RI"; + break; + case 6541: + case 6585: + case 7337: + case 7532: + case 8278: + strValue = "RONG"; + break; + case 8459: + case 8569: + case 8723: + strValue = "ROU"; + break; + case 6174: + case 6224: + case 6473: + case 6818: + case 6865: + case 6906: + case 7140: + case 7908: + case 8164: + case 8212: + strValue = "RU"; + break; + case 7535: + strValue = "RUAN"; + break; + case 6039: + case 6208: + case 7236: + case 7803: + case 8224: + strValue = "RUI"; + break; + strValue = "RUN"; + break; + case 5728: + case 8372: + strValue = "RUO"; + break; + case 5606: + case 5677: + case 7493: + case 7559: + case 7610: + strValue = "SA"; + break; + case 6471: + strValue = "SAI"; + break; + case 6644: + case 7507: + case 8454: + strValue = "SAN"; + break; + case 6290: + case 7763: + case 8210: + strValue = "SANG"; + break; + case 6003: + case 7150: + case 7156: + case 7593: + case 8094: + case 8694: + strValue = "SAO"; + break; + strValue = "SE"; + break; + strValue = "SEN"; + break; + strValue = "SENG"; + break; + case 6394: + case 7606: + case 7901: + case 8080: + case 8436: + case 8614: + case 8672: + strValue = "SHA"; + break; + case 8507: + strValue = "SHAI"; + break; + case 5663: + case 5808: + case 5923: + case 5979: + case 6047: + case 6890: + case 7009: + case 7051: + case 7083: + case 7594: + case 7844: + case 8062: + case 8321: + case 8414: + case 8539: + case 8713: + strValue = "SHAN"; + break; + case 5980: + case 7120: + case 7368: + case 7656: + case 8592: + strValue = "SHANG"; + break; + case 5931: + case 6070: + case 6891: + case 7228: + case 8366: + case 8425: + strValue = "SHAO"; + break; + case 5639: + case 5760: + case 6606: + case 6860: + case 7608: + case 7820: + case 8774: + strValue = "SHE"; + break; + case 5837: + case 6123: + case 6351: + case 6841: + case 7309: + case 7547: + case 7982: + case 8255: + strValue = "SHEN"; + break; + case 6551: + case 7441: + case 7782: + case 8347: + strValue = "SHENG"; + break; + case 5854: + case 5985: + case 6110: + case 6173: + case 6317: + case 7388: + case 7459: + case 7634: + case 7870: + case 8307: + case 8334: + case 8363: + case 8525: + case 8669: + case 8685: + strValue = "SHI"; + break; + case 6587: + case 7123: + case 8428: + strValue = "SHOU"; + break; + case 5731: + case 5951: + case 6136: + case 6283: + case 6780: + case 6888: + case 7013: + case 7508: + case 7582: + case 7988: + strValue = "SHU"; + break; + case 6407: + strValue = "SHUA"; + break; + case 8316: + strValue = "SHUAI"; + break; + case 6737: + case 6844: + strValue = "SHUAN"; + break; + case 7055: + strValue = "SHUANG"; + break; + strValue = "SHUI"; + break; + strValue = "SHUN"; + break; + case 6184: + case 6287: + case 6989: + case 7335: + case 7869: + strValue = "SHUO"; + break; + case 5643: + case 5778: + case 5944: + case 6348: + case 6765: + case 6784: + case 6889: + case 7006: + case 7065: + case 7133: + case 7675: + case 7940: + case 8024: + case 8174: + case 8247: + case 8351: + strValue = "SI"; + break; + case 5801: + case 6131: + case 6534: + case 6552: + case 6676: + case 6704: + case 6833: + case 8121: + strValue = "SONG"; + break; + case 5937: + case 6220: + case 6418: + case 6453: + case 6640: + case 6849: + case 7612: + case 7804: + case 7943: + case 8284: + strValue = "SOU"; + break; + case 5777: + case 5853: + case 6188: + case 6428: + case 6726: + case 6819: + case 8389: + case 8602: + case 8653: + strValue = "SU"; + break; + case 6601: + strValue = "SUAN"; + break; + case 5839: + case 6120: + case 6901: + case 6968: + case 7661: + case 7785: + case 7801: + strValue = "SUI"; + break; + case 6105: + case 6588: + case 6624: + case 7330: + case 8632: + strValue = "SUN"; + break; + case 6379: + case 6434: + case 6442: + case 7022: + case 7288: + case 7792: + case 8440: + strValue = "SUO"; + break; + case 6743: + case 6866: + case 6961: + case 7329: + case 7719: + case 7872: + case 8533: + case 8703: + strValue = "TA"; + break; + case 5902: + case 6223: + case 6330: + case 7070: + case 7536: + case 7638: + case 7849: + case 8544: + case 8656: + strValue = "TAI"; + break; + case 5916: + case 6903: + case 7428: + case 7694: + case 7867: + case 7936: + case 8191: + strValue = "TAN"; + break; + case 5746: + case 6491: + case 6871: + case 7209: + case 7344: + case 7906: + case 7959: + case 8177: + case 8305: + case 8311: + case 8442: + case 8517: + strValue = "TANG"; + break; + case 5627: + case 6391: + case 6812: + case 7226: + case 7666: + strValue = "TAO"; + break; + strValue = "1845 "; + break; + case 6315: + case 7693: + case 7911: + strValue = "TE"; + break; + case 7588: + strValue = "TENG"; + break; + case 5735: + case 6709: + case 6949: + case 7130: + case 8035: + case 8151: + case 8514: + strValue = "TI"; + break; + case 6261: + case 6735: + case 6757: + case 7369: + case 7817: + strValue = "TIAN"; + break; + case 5712: + case 7686: + case 8127: + case 8272: + case 8352: + case 8448: + case 8622: + case 8670: + case 8756: + strValue = "TIAO"; + break; + case 6138: + case 8749: + strValue = "TIE"; + break; + case 6080: + case 6167: + case 7035: + case 7272: + case 7890: + case 8249: + case 8610: + strValue = "TING"; + break; + case 5701: + case 5758: + case 6077: + case 6444: + case 6690: + case 6892: + case 7737: + strValue = "TONG"; + break; + case 7855: + case 7822: + case 8727: + strValue = "TOU"; + break; + case 6002: + case 6117: + case 6143: + case 7842: + case 8509: + strValue = "TU"; + break; + case 6250: + case 6972: + strValue = "TUAN"; + break; + case 7653: + strValue = "TUI"; + break; + case 5759: + case 6629: + case 7453: + case 7564: + strValue = "TUN"; + break; + case 5617: + case 5702: + case 5971: + case 6653: + case 6791: + case 7256: + case 7262: + case 7350: + case 7740: + case 8374: + case 8502: + case 8541: + case 8630: + strValue = "TUO"; + break; + case 5684: + case 7020: + case 7580: + strValue = "WA"; + break; + strValue = "WAI"; + break; + case 5664: + case 6025: + case 6150: + case 7093: + case 7126: + case 7194: + case 7568: + case 7821: + case 8274: + strValue = "WAN"; + break; + case 5672: + case 6244: + case 6715: + case 7394: + case 8745: + strValue = "WANG"; + break; + case 5743: + case 5835: + case 5881: + case 5883: + case 6158: + case 6217: + case 6488: + case 6501: + case 6543: + case 6545: + case 6611: + case 6612: + case 6739: + case 6777: + case 6802: + case 6822: + case 6952: + case 7024: + case 7166: + case 7224: + case 7406: + case 7631: + case 7648: + case 8084: + case 8426: + case 8659: + strValue = "WEI"; + break; + case 5656: + case 6751: + case 6775: + case 7223: + case 8609: + strValue = "WEN"; + break; + case 6178: + case 6219: + strValue = "WENG"; + break; + case 5733: + case 6111: + case 6502: + case 6855: + case 7531: + case 7750: + case 8627: + strValue = "WO"; + break; + case 5603: + case 5685: + case 5867: + case 5889: + case 5956: + case 6044: + case 6377: + case 6648: + case 6668: + case 6672: + case 6820: + case 6927: + case 6935: + case 6992: + case 7036: + case 7080: + case 7227: + case 7485: + case 7641: + case 8036: + case 8045: + case 8077: + case 8258: + case 8640: + case 8789: + strValue = "WU"; + break; + case 5750: + case 5766: + case 5884: + case 5913: + case 6130: + case 6163: + case 6191: + case 6241: + case 6381: + case 6567: + case 6630: + case 6750: + case 6827: + case 6832: + case 6979: + case 7050: + case 7184: + case 7356: + case 7456: + case 7474: + case 7604: + case 7668: + case 7689: + case 7691: + case 8010: + case 8122: + case 8265: + case 8303: + case 8312: + case 8410: + case 8424: + case 8443: + case 8449: + case 8466: + case 8521: + case 8791: + strValue = "XI"; + break; + case 6340: + case 6582: + case 6958: + case 7206: + case 7252: + case 7744: + case 8093: + case 8333: + case 8779: + strValue = "XIA"; + break; + case 5794: + case 5823: + case 6040: + case 6118: + case 6226: + case 6513: + case 6593: + case 6963: + case 7021: + case 7515: + case 7662: + case 7676: + case 8034: + case 8079: + case 8225: + case 8358: + case 8444: + case 8503: + case 8548: + case 8549: + case 8617: + strValue = "XIAN"; + break; + case 6028: + case 6157: + case 6635: + case 6652: + case 7088: + case 7129: + case 8313: + case 8663: + case 8747: + strValue = "XIANG"; + break; + case 6356: + case 6537: + case 6876: + case 6948: + case 7071: + case 7115: + case 7241: + case 7253: + case 8257: + case 8367: + case 8379: + case 8744: + strValue = "XIAO"; + break; + case 5741: + case 5784: + case 5936: + case 5938: + case 6215: + case 6302: + case 6619: + case 6661: + case 6845: + case 6912: + case 6966: + case 7105: + case 7151: + case 7331: + case 7339: + case 8583: + strValue = "XIE"; + break; + case 5622: + case 6016: + case 7431: + case 7607: + case 8646: + strValue = "XIN"; + break; + case 5874: + case 6084: + case 6309: + case 6712: + case 7742: + strValue = "XING"; + break; + case 6026: + strValue = "XIONG"; + break; + case 6361: + case 6522: + case 6642: + case 6651: + case 6869: + case 8028: + case 8587: + case 8759: + strValue = "XIU"; + break; + case 5828: + case 5935: + case 5955: + case 6203: + case 6810: + case 6851: + case 7179: + case 7282: + case 7667: + case 7776: + case 8167: + case 8458: + case 8515: + strValue = "XU"; + break; + case 5756: + case 5846: + case 6170: + case 6279: + case 6789: + case 6854: + case 6886: + case 7215: + case 7324: + case 7449: + case 7637: + case 7651: + case 7759: + case 7871: + case 7964: + case 8071: + strValue = "XUAN"; + break; + case 5842: + case 7720: + case 8529: + case 8708: + strValue = "XUE"; + break; + case 5767: + case 5908: + case 5987: + case 6087: + case 6101: + case 6206: + case 6225: + case 6530: + case 6563: + case 6620: + case 6694: + case 6813: + case 6817: + case 7454: + case 8131: + case 8524: + case 8664: + strValue = "XUN"; + break; + case 5683: + case 5975: + case 6275: + case 6512: + case 6934: + case 7011: + case 7180: + case 7266: + case 7518: + case 7728: + case 7793: + case 8073: + strValue = "YA"; + break; + case 5641: + case 5645: + case 5718: + case 5740: + case 5780: + case 5861: + case 5917: + case 5919: + case 6030: + case 6146: + case 6535: + case 6691: + case 6738: + case 6753: + case 6846: + case 6857: + case 6991: + case 7044: + case 7192: + case 7360: + case 7444: + case 7557: + case 7645: + case 7827: + case 8359: + case 8506: + case 8742: + case 8748: + case 8790: + strValue = "YAN"; + break; + case 6564: + case 6683: + case 7630: + case 7640: + case 7706: + case 8253: + case 8717: + strValue = "YANG"; + break; + case 5618: + case 5619: + case 6326: + case 6542: + case 6570: + case 7159: + case 7182: + case 7235: + case 7387: + case 7455: + case 7540: + case 7902: + case 8046: + case 8126: + case 8477: + case 8705: + strValue = "YAO"; + break; + case 5644: + case 5843: + case 5894: + case 6262: + case 7442: + case 7639: + case 7884: + strValue = "YE"; + break; + case 5655: + case 5657: + case 5670: + case 5693: + case 5711: + case 5817: + case 5961: + case 5992: + case 6018: + case 6051: + case 6072: + case 6218: + case 6236: + case 6240: + case 6258: + case 6314: + case 6329: + case 6355: + case 6362: + case 6441: + case 6470: + case 6527: + case 6558: + case 6602: + case 6634: + case 6688: + case 6689: + case 6708: + case 6884: + case 6938: + case 7068: + case 7143: + case 7376: + case 7383: + case 7461: + case 7629: + case 7658: + case 7784: + case 7838: + case 7955: + case 7978: + case 8074: + case 8089: + case 8115: + case 8120: + case 8270: + case 8415: + case 8464: + case 8472: + case 8493: + case 8780: + strValue = "YI"; + break; + case 5623: + case 5920: + case 5983: + case 6007: + case 6065: + case 6337: + case 6419: + case 6594: + case 6625: + case 6806: + case 7519: + case 7887: + case 8111: + case 8230: + case 8615: + case 8624: + strValue = "YIN"; + break; + case 5788: + case 5911: + case 6067: + case 6094: + case 6126: + case 6151: + case 6186: + case 6292: + case 6451: + case 6663: + case 6862: + case 6875: + case 6913: + case 7188: + case 7212: + case 7326: + case 7584: + case 8048: + case 8108: + case 8203: + case 8331: + strValue = "YING"; + break; + case 6401: + strValue = "YO"; + break; + case 5724: + case 5953: + case 6013: + case 6415: + case 6728: + case 7163: + case 7962: + case 8014: + case 8711: + case 8751: + strValue = "YONG"; + break; + case 5653: + case 5692: + case 5707: + case 6112: + case 6115: + case 6121: + case 6347: + case 6483: + case 6922: + case 7254: + case 7364: + case 7527: + case 7880: + case 8064: + case 8236: + case 8242: + case 8286: + case 8647: + case 8778: + case 8788: + strValue = "YOU"; + break; + case 5614: + case 5625: + case 5681: + case 5722: + case 5836: + case 5845: + case 6139: + case 6187: + case 6277: + case 6484: + case 6486: + case 6546: + case 6592: + case 6632: + case 6637: + case 6655: + case 6748: + case 6987: + case 6993: + case 7005: + case 7090: + case 7204: + case 7437: + case 7476: + case 7573: + case 7603: + case 7622: + case 7647: + case 7659: + case 7718: + case 7858: + case 8033: + case 8054: + case 8085: + case 8086: + case 8130: + case 8133: + case 8266: + case 8285: + case 8336: + case 8407: + case 8408: + case 8607: + case 8625: + strValue = "YU"; + break; + case 5989: + case 6011: + case 6282: + case 6768: + case 7034: + case 7205: + case 7358: + case 7528: + case 7783: + case 8016: + case 8302: + case 8378: + case 8629: + strValue = "YUAN"; + break; + case 5763: + case 6914: + case 7348: + case 7530: + case 7865: + strValue = "YUE"; + break; + case 5909: + case 6031: + case 6581: + case 6702: + case 6719: + case 7101: + case 7225: + case 7370: + case 7432: + case 7521: + case 7657: + strValue = "YUN"; + break; + case 6257: + case 6338: + strValue = "ZA"; + break; + case 6544: + case 7162: + strValue = "ZAI"; + break; + case 7222: + case 7435: + case 8402: + case 8456: + case 8485: + case 8641: + strValue = "ZAN"; + break; + case 6242: + case 7064: + case 7416: + strValue = "ZANG"; + break; + case 6380: + strValue = "ZAO"; + break; + case 5638: + case 8369: + case 5651: + case 6385: + case 6493: + case 6937: + case 7430: + case 8348: + case 8423: + strValue = "ZE"; + break; + strValue = "ZEI"; + break; + case 5858: + strValue = "ZEN"; + break; + case 7153: + case 7421: + case 7832: + case 7913: + strValue = "ZENG"; + break; + case 6610: + case 6274: + case 6324: + case 6369: + case 6378: + case 7736: + case 8068: + case 8238: + case 8794: + strValue = "ZHA"; + break; + case 7746: + case 8109: + strValue = "ZHAI"; + break; + case 5862: + case 6288: + case 7625: + strValue = "ZHAN"; + break; + case 5675: + case 5921: + case 6504: + case 6554: + case 6615: + case 7049: + case 7216: + case 8315: + strValue = "ZHANG"; + break; + case 5815: + case 7294: + case 7840: + case 8341: + strValue = "ZHAO"; + break; + case 5856: + case 6301: + case 7247: + case 7392: + case 7761: + case 8049: + case 8162: + case 8256: + case 8487: + strValue = "ZHE"; + break; + case 5958: + case 6172: + case 6805: + case 7139: + case 7269: + case 7327: + case 7384: + case 7466: + case 7551: + case 7562: + case 7685: + case 7819: + case 8001: + case 8018: + case 8380: + strValue = "ZHEN"; + break; + case 5826: + case 6531: + case 6571: + case 7859: + case 7903: + case 8361: + strValue = "ZHENG"; + break; + case 5620: + case 5876: + case 5904: + case 5990: + case 6038: + case 6293: + case 6489: + case 6669: + case 6973: + case 6975: + case 7079: + case 7246: + case 7255: + case 7257: + case 7268: + case 7382: + case 7389: + case 7462: + case 7553: + case 7589: + case 7677: + case 7683: + case 7773: + case 7984: + case 8026: + case 8075: + case 8246: + case 8474: + case 8505: + case 8537: + case 8557: + case 8560: + case 8584: + case 8603: + strValue = "ZHI"; + break; + case 5803: + case 7981: + case 8314: + case 8417: + case 8564: + strValue = "ZHONG"; + break; + case 6107: + case 6390: + case 7008: + case 7091: + case 7107: + case 7548: + case 7756: + case 8406: + case 8492: + strValue = "ZHOU"; + break; + case 5689: + case 5710: + case 5905: + case 6049: + case 6079: + case 6808: + case 6830: + case 6883: + case 7244: + case 7338: + case 7345: + case 7636: + case 7889: + case 8070: + case 8081: + case 8335: + case 8371: + case 8422: + case 8467: + case 8578: + case 8770: + strValue = "ZHU"; + break; + strValue = "ZHUA"; + break; + strValue = "ZHUAI"; + break; + case 6389: + case 6645: + case 8207: + strValue = "ZHUAN"; + break; + case 5755: + strValue = "ZHUANG"; + break; + case 6723: + case 7077: + case 7136: + strValue = "ZHUI"; + break; + case 7538: + case 8124: + strValue = "ZHUN"; + break; + case 5730: + case 5834: + case 6310: + case 6823: + case 6835: + case 6910: + case 7644: + case 7690: + case 7729: + case 7977: + strValue = "ZHUO"; + break; + case 5849: + case 6549: + case 7002: + case 7060: + case 7127: + case 7287: + case 7402: + case 7463: + case 7707: + case 7786: + case 7937: + case 7986: + case 8172: + case 8342: + case 8450: + case 8484: + case 8594: + case 8604: + case 8623: + case 8686: + case 8758: + strValue = "ZI"; + break; + case 5744: + case 7574: + case 8453: + strValue = "ZONG"; + break; + case 5833: + case 5878: + case 5924: + case 7067: + case 8677: + strValue = "ZOU"; + break; + case 5762: + case 6147: + case 7963: + strValue = "ZU"; + break; + case 6312: + case 7158: + case 8582: + strValue = "ZUAN"; + break; + case 6209: + strValue = "ZUI"; + break; + case 6304: + case 7355: + case 8714: + strValue = "ZUN"; + break; + case 5872: + case 6382: + case 6460: + case 6684: + case 7549: + case 7681: + strValue = "ZUO"; + break; + default: + if (nCode >= 1601 && nCode <= 1602) + { + strValue = "A"; + break; + } + if (nCode >= 1603 && nCode <= 1615) + { + strValue = "AI"; + break; + } + if (nCode >= 1616 && nCode <= 1624) + { + strValue = "AN"; + break; + } + if (nCode >= 1625 && nCode <= 1627) + { + strValue = "ANG"; + break; + } + if (nCode >= 1628 && nCode <= 1636) + { + strValue = "AO"; + break; + } + if (nCode >= 1637 && nCode <= 1654) + { + strValue = "BA"; + break; + } + if (nCode >= 1655 && nCode <= 1662) + { + strValue = "BAI"; + break; + } + if (nCode >= 1663 && nCode <= 1677) + { + strValue = "BAN"; + break; + } + if (nCode >= 1678 && nCode <= 1689) + { + strValue = "BANG"; + break; + } + if (nCode >= 1690 && nCode <= 1712) + { + strValue = "BAO"; + break; + } + if (nCode >= 1713 && nCode <= 1727) + { + strValue = "BEI"; + break; + } + if (nCode >= 1728 && nCode <= 1731) + { + strValue = "BEN"; + break; + } + if (nCode >= 1732 && nCode <= 1737) + { + strValue = "BENG"; + break; + } + if (nCode > 1738 && nCode <= 1761) + { + strValue = "BI"; + break; + } + if (nCode >= 1762 && nCode <= 1773) + { + strValue = "BIAN"; + break; + } + if (nCode >= 1774 && nCode <= 1777) + { + strValue = "BIAO"; + break; + } + if (nCode >= 1778 && nCode <= 1781) + { + strValue = "BIE"; + break; + } + if (nCode >= 1782 && nCode <= 1787) + { + strValue = "BIN"; + break; + } + if (nCode >= 1788 && nCode <= 1794) + { + strValue = "BING"; + break; + } + if (nCode >= 1801 && nCode <= 1802) + { + strValue = "BING"; + break; + } + if (nCode >= 1803 && nCode <= 1821) + { + strValue = "BO"; + break; + } + if (nCode >= 1822 && nCode <= 1832) + { + strValue = "BU"; + break; + } + if (nCode == 1833) + { + strValue = "CA"; + break; + } + if (nCode >= 1834 && nCode <= 1844) + { + strValue = "CAI"; + break; + } + if (nCode >= 1845 && nCode <= 1851) + { + strValue = "CAN"; + break; + } + if (nCode >= 1852 && nCode <= 1856) + { + strValue = "CANG"; + break; + } + if (nCode >= 1857 && nCode <= 1861) + { + strValue = "CAO"; + break; + } + if (nCode >= 1862 && nCode <= 1866) + { + strValue = "CE"; + break; + } + if (nCode >= 1867 && nCode <= 1868) + { + strValue = "CENG"; + break; + } + if (nCode >= 1869 && nCode <= 1879) + { + strValue = "CHA"; + break; + } + if (nCode >= 1880 && nCode <= 1882) + { + strValue = "CHAI"; + break; + } + if (nCode >= 1883 && nCode <= 1892) + { + strValue = "CHAN"; + break; + } + if (nCode >= 1893 && nCode <= 1911) + { + strValue = "CHANG"; + break; + } + if (nCode >= 1912 && nCode <= 1920) + { + strValue = "CHAO"; + break; + } + if (nCode >= 1921 && nCode <= 1926) + { + strValue = "CHE"; + break; + } + if (nCode >= 1927 && nCode <= 1936) + { + strValue = "CHEN"; + break; + } + if (nCode >= 1937 && nCode <= 1951) + { + strValue = "CHENG"; + break; + } + if (nCode >= 1952 && nCode <= 1967) + { + strValue = "CHI"; + break; + } + if (nCode >= 1968 && nCode <= 1972) + { + strValue = "CHONG"; + break; + } + if (nCode >= 1973 && nCode <= 1984) + { + strValue = "CHOU"; + break; + } + if (nCode >= 1985 && nCode <= 2006) + { + strValue = "CHU"; + break; + } + if (nCode == 2007) + { + strValue = "CHUAI"; + break; + } + if (nCode >= 2008 && nCode <= 2014) + { + strValue = "CHUAN"; + break; + } + if (nCode >= 2015 && nCode <= 2020) + { + strValue = "CHUANG"; + break; + } + if (nCode >= 2021 && nCode <= 2025) + { + strValue = "CHUI"; + break; + } + if (nCode >= 2026 && nCode <= 2032) + { + strValue = "CHUN"; + break; + } + if (nCode >= 2033 && nCode <= 2034) + { + strValue = "CHUO"; + break; + } + if (nCode >= 2035 && nCode <= 2046) + { + strValue = "CI"; + break; + } + if (nCode >= 2047 && nCode <= 2052) + { + strValue = "CONG"; + break; + } + if (nCode >= 2054 && nCode <= 2057) + { + strValue = "CU"; + break; + } + if (nCode >= 2058 && nCode <= 2060) + { + strValue = "CUAN"; + break; + } + if (nCode >= 2061 && nCode <= 2068) + { + strValue = "CUI"; + break; + } + if (nCode >= 2069 && nCode <= 2071) + { + strValue = "CUN"; + break; + } + if (nCode >= 2072 && nCode <= 2077) + { + strValue = "CUO"; + break; + } + if (nCode >= 2078 && nCode <= 2083) + { + strValue = "DA"; + break; + } + if (nCode >= 2084 && nCode <= 2094) + { + strValue = "DAI"; + break; + } + if (nCode >= 2102 && nCode <= 2116) + { + strValue = "DAN"; + break; + } + if (nCode >= 2117 && nCode <= 2121) + { + strValue = "DANG"; + break; + } + if (nCode >= 2122 && nCode <= 2133) + { + strValue = "DAO"; + break; + } + if (nCode >= 2134 && nCode <= 2136) + { + strValue = "DE"; + break; + } + if (nCode >= 2137 && nCode <= 2143) + { + strValue = "DENG"; + break; + } + if (nCode >= 2144 && nCode <= 2162) + { + strValue = "DI"; + break; + } + if (nCode >= 2163 && nCode <= 2178) + { + strValue = "DIAN"; + break; + } + if (nCode >= 2179 && nCode <= 2187) + { + strValue = "DIAO"; + break; + } + if (nCode >= 2188 && nCode <= 2194) + { + strValue = "DIE"; + break; + } + if (nCode >= 2201 && nCode <= 2209) + { + strValue = "DING"; + break; + } + if (nCode == 2210) + { + strValue = "DIU"; + break; + } + if (nCode >= 2211 && nCode <= 2220) + { + strValue = "DONG"; + break; + } + if (nCode >= 2221 && nCode <= 2227) + { + strValue = "DOU"; + break; + } + if (nCode >= 2228 && nCode <= 2242) + { + strValue = "DU"; + break; + } + if (nCode >= 2243 && nCode <= 2248) + { + strValue = "DUAN"; + break; + } + if (nCode >= 2249 && nCode <= 2252) + { + strValue = "DUI"; + break; + } + if (nCode >= 2253 && nCode <= 2261) + { + strValue = "DUN"; + break; + } + if (nCode >= 2262 && nCode <= 2273) + { + strValue = "DUO"; + break; + } + if (nCode >= 2274 && nCode <= 2286) + { + strValue = "E"; + break; + } + if (nCode == 2287) + { + strValue = "EN"; + break; + } + if (nCode >= 2288 && nCode <= 2231) + { + strValue = "ER"; + break; + } + if (nCode >= 2302 && nCode <= 2309) + { + strValue = "FA"; + break; + } + if (nCode >= 2310 && nCode <= 2326) + { + strValue = "FAN"; + break; + } + if (nCode >= 2327 && nCode <= 2337) + { + strValue = "FANG"; + break; + } + if (nCode >= 2338 && nCode <= 2349) + { + strValue = "FEI"; + break; + } + if (nCode >= 2350 && nCode <= 2364) + { + strValue = "FEN"; + break; + } + if (nCode >= 2365 && nCode <= 2379) + { + strValue = "FENG"; + break; + } + if (nCode == 2380) + { + strValue = "FO"; + break; + } + if (nCode == 2381) + { + strValue = "FOU"; + break; + } + if (nCode >= 2382 && nCode <= 2432) + { + strValue = "FU"; + break; + } + if (nCode >= 2435 && nCode <= 2440) + { + strValue = "GAI"; + break; + } + if (nCode >= 2441 && nCode <= 2451) + { + strValue = "GAN"; + break; + } + if (nCode >= 2452 && nCode <= 2460) + { + strValue = "GANG"; + break; + } + if (nCode >= 2461 && nCode <= 2470) + { + strValue = "GAO"; + break; + } + if (nCode >= 2471 && nCode <= 2487) + { + strValue = "GE"; + break; + } + if (nCode == 2488) + { + strValue = "GEI"; + break; + } + if (nCode >= 2489 && nCode <= 2490) + { + strValue = "GEN"; + break; + } + if (nCode >= 2491 && nCode <= 2503) + { + strValue = "GENG"; + break; + } + if (nCode >= 2504 && nCode <= 2518) + { + strValue = "GONG"; + break; + } + if (nCode >= 2519 && nCode <= 2527) + { + strValue = "GOU"; + break; + } + if (nCode >= 2528 && nCode <= 2545) + { + strValue = "GU"; + break; + } + if (nCode >= 2546 && nCode <= 2551) + { + strValue = "GUA"; + break; + } + if (nCode >= 2552 && nCode <= 2554) + { + strValue = "GUAI"; + break; + } + if (nCode >= 2555 && nCode <= 2565) + { + strValue = "GUAN"; + break; + } + if (nCode >= 2566 && nCode <= 2568) + { + strValue = "GUANG"; + break; + } + if (nCode >= 2569 && nCode <= 2584) + { + strValue = "GUI"; + break; + } + if (nCode >= 2585 && nCode <= 2587) + { + strValue = "GUN"; + break; + } + if (nCode >= 2588 && nCode <= 2593) + { + strValue = "GUO"; + break; + } + if (nCode == 2594) + { + strValue = "HA"; + break; + } + if (nCode >= 2601 && nCode <= 2607) + { + strValue = "HAI"; + break; + } + if (nCode >= 2608 && nCode <= 2626) + { + strValue = "HAN"; + break; + } + if (nCode >= 2627 && nCode <= 2629) + { + strValue = "HANG"; + break; + } + if (nCode >= 2630 && nCode <= 2638) + { + strValue = "HAO"; + break; + } + if (nCode >= 2639 && nCode <= 2656) + { + strValue = "HE"; + break; + } + if (nCode >= 2657 && nCode <= 2658) + { + strValue = "HEI"; + break; + } + if (nCode >= 2659 && nCode <= 2662) + { + strValue = "HEN"; + break; + } + if (nCode >= 2663 && nCode <= 2667) + { + strValue = "HENG"; + break; + } + if (nCode >= 2668 && nCode <= 2676) + { + strValue = "HONG"; + break; + } + if (nCode >= 2677 && nCode <= 2683) + { + strValue = "HOU"; + break; + } + if (nCode >= 2684 && nCode <= 2707) + { + strValue = "HU"; + break; + } + if (nCode >= 2708 && nCode <= 2716) + { + strValue = "HUA"; + break; + } + if (nCode >= 2717 && nCode <= 2721) + { + strValue = "HUAI"; + break; + } + if (nCode >= 2722 && nCode <= 2735) + { + strValue = "HUAN"; + break; + } + if (nCode >= 2736 && nCode <= 2749) + { + strValue = "HUANG"; + break; + } + if (nCode >= 2750 && nCode <= 2770) + { + strValue = "HUI"; + break; + } + if (nCode >= 2771 && nCode <= 2776) + { + strValue = "HUN"; + break; + } + if (nCode >= 2777 && nCode <= 2786) + { + strValue = "HUO"; + break; + } + if (nCode >= 2787 && nCode <= 2845) + { + strValue = "JI"; + break; + } + if (nCode >= 2846 && nCode <= 2862) + { + strValue = "JIA"; + break; + } + if (nCode >= 2863 && nCode <= 2908) + { + strValue = "JIAN"; + break; + } + if (nCode >= 2909 && nCode <= 2921) + { + strValue = "JIANG"; + break; + } + if (nCode >= 2922 && nCode <= 2949) + { + strValue = "JIAO"; + break; + } + if (nCode >= 2950 && nCode <= 2976) + { + strValue = "JIE"; + break; + } + if (nCode >= 2977 && nCode <= 3002) + { + strValue = "JIN"; + break; + } + if (nCode >= 3003 && nCode <= 3027) + { + strValue = "JING"; + break; + } + if (nCode >= 3028 && nCode <= 3029) + { + strValue = "JIONG"; + break; + } + if (nCode >= 3030 && nCode <= 3046) + { + strValue = "JIU"; + break; + } + if (nCode >= 3047 && nCode <= 3071) + { + strValue = "JU"; + break; + } + if (nCode >= 3072 && nCode <= 3078) + { + strValue = "JUAN"; + break; + } + if (nCode >= 3079 && nCode <= 3088) + { + strValue = "JUE"; + break; + } + if (nCode >= 3089 && nCode <= 3105) + { + strValue = "JUN"; + break; + } + if (nCode >= 3106 && nCode <= 3109) + { + strValue = "KA"; + break; + } + if (nCode >= 3110 && nCode <= 3114) + { + strValue = "KAI"; + break; + } + if (nCode >= 3115 && nCode <= 3120) + { + strValue = "KAN"; + break; + } + if (nCode >= 3121 && nCode <= 3127) + { + strValue = "KANG"; + break; + } + if (nCode >= 3128 && nCode <= 3131) + { + strValue = "KAO"; + break; + } + if (nCode >= 3132 && nCode <= 3146) + { + strValue = "KE"; + break; + } + if (nCode >= 3147 && nCode <= 3150) + { + strValue = "KEN"; + break; + } + if (nCode >= 3151 && nCode <= 3152) + { + strValue = "KENG"; + break; + } + if (nCode >= 3153 && nCode <= 3156) + { + strValue = "KONG"; + break; + } + if (nCode >= 3157 && nCode <= 3160) + { + strValue = "KOU"; + break; + } + if (nCode >= 3161 && nCode <= 3167) + { + strValue = "KU"; + break; + } + if (nCode >= 3168 && nCode <= 3172) + { + strValue = "KUA"; + break; + } + if (nCode >= 3173 && nCode <= 3176) + { + strValue = "KUAI"; + break; + } + if (nCode >= 3177 && nCode <= 3178) + { + strValue = "KUAN"; + break; + } + if (nCode >= 3179 && nCode <= 3186) + { + strValue = "KUANG"; + break; + } + if (nCode >= 3187 && nCode <= 3203) + { + strValue = "KUI"; + break; + } + if (nCode >= 3204 && nCode <= 3207) + { + strValue = "KUN"; + break; + } + if (nCode >= 3208 && nCode <= 3211) + { + strValue = "KUO"; + break; + } + if (nCode >= 3212 && nCode <= 3218) + { + strValue = "LA"; + break; + } + if (nCode >= 3219 && nCode <= 3221) + { + strValue = "LAI"; + break; + } + if (nCode >= 3222 && nCode <= 3236) + { + strValue = "LAN"; + break; + } + if (nCode >= 3237 && nCode <= 3243) + { + strValue = "LANG"; + break; + } + if (nCode >= 3244 && nCode <= 3252) + { + strValue = "LAO"; + break; + } + if (nCode >= 3253 && nCode <= 3254) + { + strValue = "LE"; + break; + } + if (nCode >= 3255 && nCode <= 3265) + { + strValue = "LEI"; + break; + } + if (nCode >= 3266 && nCode <= 3268) + { + strValue = "LENG"; + break; + } + if (nCode >= 3269 && nCode <= 3308) + { + strValue = "LI"; + } + if (nCode == 3309) + { + strValue = "LIA"; + break; + } + if (nCode >= 3310 && nCode <= 3323) + { + strValue = "LIAN"; + break; + } + if (nCode >= 3324 && nCode <= 3334) + { + strValue = "LIANG"; + break; + } + if (nCode >= 3335 && nCode <= 3347) + { + strValue = "LIAO"; + break; + } + if (nCode >= 3348 && nCode <= 3352) + { + strValue = "LIE"; + break; + } + if (nCode >= 3353 && nCode <= 3363) + { + strValue = "LIN"; + break; + } + if (nCode >= 3364 && nCode <= 3378) + { + strValue = "LING"; + break; + } + if (nCode >= 3379 && nCode <= 3389) + { + strValue = "LIU"; + break; + } + if (nCode >= 3390 && nCode <= 3404) + { + strValue = "LONG"; + break; + } + if (nCode >= 3405 && nCode <= 3410) + { + strValue = "LOU"; + break; + } + if (nCode >= 3411 && nCode <= 3444) + { + strValue = "LU"; + break; + } + if (nCode >= 3445 && nCode <= 3450) + { + strValue = "LUAN"; + break; + } + if (nCode >= 3451 && nCode <= 3452) + { + strValue = "LUE"; + break; + } + if (nCode >= 3453 && nCode <= 3459) + { + strValue = "LUN"; + break; + } + if (nCode >= 3460 && nCode <= 3471) + { + strValue = "LUO"; + break; + } + if (nCode >= 3472 && nCode <= 3480) + { + strValue = "MA"; + break; + } + if (nCode >= 3481 && nCode <= 3486) + { + strValue = "MAI"; + break; + } + if (nCode >= 3487 && nCode <= 3501) + { + strValue = "MAN"; + break; + } + if (nCode >= 3502 && nCode <= 3507) + { + strValue = "MANG"; + break; + } + if (nCode >= 3508 && nCode <= 3519) + { + strValue = "MAO"; + break; + } + if (nCode == 3520) + { + strValue = "ME"; + break; + } + if (nCode >= 3521 && nCode <= 3536) + { + strValue = "MEI"; + break; + } + if (nCode >= 3537 && nCode <= 3539) + { + strValue = "MEN"; + break; + } + if (nCode >= 3540 && nCode <= 3547) + { + strValue = "MENG"; + break; + } + if (nCode >= 3548 && nCode <= 3561) + { + strValue = "MI"; + } + if (nCode >= 3562 && nCode <= 3570) + { + strValue = "MIAN"; + break; + } + if (nCode >= 3571 && nCode <= 3578) + { + strValue = "MIAO"; + break; + } + if (nCode >= 3579 && nCode <= 3580) + { + strValue = "MIE"; + break; + } + if (nCode >= 3581 && nCode <= 3586) + { + strValue = "MIN"; + break; + } + if (nCode >= 3587 && nCode <= 3592) + { + strValue = "MING"; + break; + } + if (nCode == 3593) + { + strValue == "MIU"; + break; + } + if (nCode >= 3594 && nCode <= 3616) + { + strValue = "MO"; + break; + } + if (nCode >= 3617 && nCode <= 3619) + { + strValue = "MOU"; + break; + } + if (nCode >= 3620 && nCode <= 3634) + { + strValue = "MU"; + break; + } + if (nCode >= 3635 && nCode <= 3641) + { + strValue = "NA"; + break; + } + if (nCode >= 3642 && nCode <= 3646) + { + strValue = "NAI"; + break; + } + if (nCode >= 3647 && nCode <= 3649) + { + strValue = "NAN"; + break; + } + if (nCode == 3650) + { + strValue = "NANG"; + break; + } + if (nCode >= 3651 && nCode <= 3655) + { + strValue = "NAO"; + break; + } + if (nCode == 3656) + { + strValue = "NE"; + break; + } + if (nCode >= 3657 && nCode <= 3658) + { + strValue = "NEI"; + break; + } + if (nCode == 3659) + { + strValue = "NEN"; + break; + } + if (nCode == 3660) + { + strValue = "NENG"; + break; + } + if (nCode >= 3661 && nCode <= 3671) + { + strValue = "NI"; + break; + } + if (nCode >= 3672 && nCode <= 3678) + { + strValue = "NIAN"; + break; + } + if (nCode >= 3679 && nCode <= 3680) + { + strValue = "NIANG"; + break; + } + if (nCode >= 3681 && nCode <= 3682) + { + strValue = "NIAO"; + break; + } + if (nCode >= 3683 && nCode <= 3689) + { + strValue = "NIE"; + break; + } + if (nCode == 3690) + { + strValue = "NIN"; + break; + } + if (nCode >= 3691 && nCode <= 3702) + { + strValue = "NING"; + break; + } + if (nCode >= 3703 && nCode <= 3706) + { + strValue = "NIU"; + break; + } + if (nCode >= 3707 && nCode <= 3710) + { + strValue = "NONG"; + break; + } + if (nCode >= 3711 && nCode <= 3714) + { + strValue = "NU"; + break; + } + if (nCode == 3715) + { + strValue = "NUAN"; + break; + } + if (nCode >= 3716 && nCode <= 3717) + { + strValue = "NUE"; + break; + } + if (nCode >= 3718 && nCode <= 3721) + { + strValue = "NUO"; + break; + } + if (nCode == 3722) + { + strValue = "O"; + break; + } + if (nCode >= 3723 && nCode <= 3729) + { + strValue = "OU"; + break; + } + if (nCode >= 3730 && nCode <= 3735) + { + strValue = "PA"; + break; + } + if (nCode >= 3736 && nCode <= 3741) + { + strValue = "PAI"; + break; + } + if (nCode >= 3742 && nCode <= 3749) + { + strValue = "PAN"; + break; + } + if (nCode >= 3750 && nCode <= 3754) + { + strValue = "PANG"; + break; + } + if (nCode >= 3755 && nCode <= 3761) + { + strValue = "PAO"; + break; + } + if (nCode >= 3762 && nCode <= 3770) + { + strValue = "PEI"; + break; + } + if (nCode >= 3771 && nCode <= 3772) + { + strValue = "PEN"; + break; + } + if (nCode >= 3773 && nCode <= 3786) + { + strValue = "PENG"; + break; + } + if (nCode >= 3787 && nCode <= 3809) + { + strValue = "PI"; + break; + } + if (nCode >= 3810 && nCode <= 3813) + { + strValue = "PIAN"; + break; + } + if (nCode >= 3814 && nCode <= 3817) + { + strValue = "PIAO"; + break; + } + if (nCode >= 3818 && nCode <= 3819) + { + strValue = "PIE"; + break; + } + if (nCode >= 3820 && nCode <= 3824) + { + strValue = "PIN"; + break; + } + if (nCode >= 3825 && nCode <= 3833) + { + strValue = "PING"; + break; + } + if (nCode >= 3834 && nCode <= 3841) + { + strValue = "PO"; + break; + } + if (nCode == 3842) + { + strValue = "POU"; + break; + } + if (nCode >= 3843 && nCode <= 3857) + { + strValue = "PU"; + break; + } + if (nCode >= 3858 && nCode <= 3893) + { + strValue = "QI"; + break; + } + if (nCode == 3894 || nCode >= 3901 && nCode <= 3902) + { + strValue = "QIA"; + break; + } + if (nCode >= 3903 && nCode <= 3924) + { + strValue = "QIAN"; + break; + } + if (nCode >= 3925 && nCode <= 3932) + { + strValue = "QIANG"; + break; + } + if (nCode >= 3933 && nCode <= 3947) + { + strValue = "QIAO"; + break; + } + if (nCode >= 3948 && nCode <= 3952) + { + strValue = "QIE"; + break; + } + if (nCode >= 3953 && nCode <= 3963) + { + strValue = "QIN"; + break; + } + if (nCode >= 3964 && nCode <= 3976) + { + strValue = "QING"; + break; + } + if (nCode >= 3977 && nCode <= 3978) + { + strValue = "QIONG"; + break; + } + if (nCode >= 3979 && nCode <= 3986) + { + strValue = "QIU"; + break; + } + if (nCode >= 3987 && nCode <= 4005) + { + strValue = "QU"; + break; + } + if (nCode >= 4006 && nCode <= 4016) + { + strValue = "QUAN"; + break; + } + if (nCode >= 4017 && nCode <= 4024) + { + strValue = "QUE"; + break; + } + if (nCode >= 4025 && nCode <= 4026) + { + strValue = "QUN"; + break; + } + if (nCode >= 4027 && nCode <= 4030) + { + strValue = "RAN"; + break; + } + if (nCode >= 4031 && nCode <= 4035) + { + strValue = "RANG"; + } + if (nCode >= 4036 && nCode <= 4038) + { + strValue = "RAO"; + break; + } + if (nCode >= 4039 && nCode <= 4040) + { + strValue = "RE"; + break; + } + if (nCode >= 4041 && nCode <= 4050) + { + strValue = "REN"; + break; + } + if (nCode >= 4051 && nCode <= 4052) + { + strValue = "RENG"; + break; + } + if (nCode == 4053) + { + strValue = "RI"; + break; + } + if (nCode >= 4054 && nCode <= 4063) + { + strValue = "RONG"; + break; + } + if (nCode >= 4064 && nCode <= 4066) + { + strValue = "ROU"; + break; + } + if (nCode >= 4067 && nCode <= 4076) + { + strValue = "RU"; + break; + } + if (nCode >= 4077 && nCode <= 4078) + { + strValue = "RUAN"; + break; + } + if (nCode >= 4079 && nCode <= 4081) + { + strValue = "RUI"; + break; + } + if (nCode >= 4082 && nCode <= 4083) + { + strValue = "RUN"; + break; + } + if (nCode >= 4084 && nCode <= 4085) + { + strValue = "RUO"; + break; + } + if (nCode >= 4086 && nCode <= 4088) + { + strValue = "SA"; + break; + } + if (nCode >= 4089 && nCode <= 4092) + { + strValue = "SAI"; + break; + } + if (nCode >= 4093 && nCode <= 4094) + { + strValue = "SAN"; + break; + } + if (nCode >= 4101 && nCode <= 4102) + { + strValue = "SAN"; + break; + } + if (nCode >= 4103 && nCode <= 4105) + { + strValue = "SANG"; + break; + } + if (nCode >= 4106 && nCode <= 4109) + { + strValue = "SAO"; + break; + } + if (nCode >= 4110 && nCode <= 4112) + { + strValue = "SE"; + break; + } + if (nCode == 4113) + { + strValue = "SEN"; + } + if (nCode == 4114) + { + strValue = "SENG"; + break; + } + if (nCode >= 4115 && nCode <= 4123) + { + strValue = "SHA"; + break; + } + if (nCode >= 4124 && nCode <= 4125) + { + strValue = "SHAI"; + break; + } + if (nCode >= 4126 && nCode <= 4141) + { + strValue = "SHAN"; + break; + } + if (nCode >= 4142 && nCode <= 4149) + { + strValue = "SHANG"; + break; + } + if (nCode >= 4150 && nCode <= 4160) + { + strValue = "SHAO"; + break; + } + if (nCode >= 4161 && nCode <= 4172) + { + strValue = "SHE"; + break; + } + if (nCode >= 4173 && nCode <= 4188) + { + strValue = "SHEN"; + break; + } + if (nCode >= 4189 && nCode <= 4205) + { + strValue = "SHENG"; + break; + } + if (nCode >= 4206 && nCode <= 4252) + { + strValue = "SHI"; + break; + } + if (nCode >= 4253 && nCode <= 4262) + { + strValue = "SHOU"; + break; + } + if (nCode >= 4263 && nCode <= 4301) + { + strValue = "SHU"; + break; + } + if (nCode >= 4302 && nCode <= 4303) + { + strValue = "SHUA"; + break; + } + if (nCode >= 4304 && nCode <= 4307) + { + strValue = "SHUAI"; + break; + } + if (nCode >= 4308 && nCode <= 4309) + { + strValue = "SHUAN"; + break; + } + if (nCode >= 4310 && nCode <= 4312) + { + strValue = "SHUANG"; + break; + } + if (nCode >= 4313 && nCode <= 4316) + { + strValue = "SHUI"; + break; + } + if (nCode >= 4317 && nCode <= 4320) + { + strValue = "SHUN"; + break; + } + if (nCode >= 4321 && nCode <= 4324) + { + strValue = "SHUO"; + break; + } + if (nCode >= 4325 && nCode <= 4340) + { + strValue = "SI"; + break; + } + if (nCode >= 4341 && nCode <= 4348) + { + strValue = "SONG"; + break; + } + if (nCode >= 4349 && nCode <= 4352) + { + strValue = "SOU"; + break; + } + if (nCode >= 4353 && nCode <= 4364) + { + strValue = "SU"; + break; + } + if (nCode >= 4365 && nCode <= 4367) + { + strValue = "SUAN"; + break; + } + if (nCode >= 4368 && nCode <= 4378) + { + strValue = "SUI"; + break; + } + if (nCode >= 4379 && nCode <= 4381) + { + strValue = "SUN"; + break; + } + if (nCode >= 4382 && nCode <= 4389) + { + strValue = "SUO"; + break; + } + if (nCode >= 4390 && nCode <= 4404) + { + strValue = "TA"; + break; + } + if (nCode >= 4405 && nCode <= 4413) + { + strValue = "TAI"; + break; + } + if (nCode >= 4414 && nCode <= 4431) + { + strValue = "TAN"; + break; + } + if (nCode >= 4432 && nCode <= 4444) + { + strValue = "TANG"; + break; + } + if (nCode >= 4445 && nCode <= 4455) + { + strValue = "TAO"; + break; + } + if (nCode == 4456) + { + strValue = "TE"; + break; + } + if (nCode >= 4457 && nCode <= 4460) + { + strValue = "TENG"; + break; + } + if (nCode >= 4461 && nCode <= 4475) + { + strValue = "TI"; + break; + } + if (nCode >= 4476 && nCode <= 4483) + { + strValue = "TIAN"; + break; + } + if (nCode >= 4484 && nCode <= 4488) + { + strValue = "TIAO"; + break; + } + if (nCode >= 4489 && nCode <= 4491) + { + strValue = "TIE"; + break; + } + if (nCode >= 4492 && nCode <= 4507) + { + strValue = "TING"; + break; + } + if (nCode >= 4508 && nCode <= 4520) + { + strValue = "TONG"; + break; + } + if (nCode >= 4521 && nCode <= 4524) + { + strValue = "TOU"; + break; + } + if (nCode >= 4525 && nCode <= 4535) + { + strValue = "TU"; + break; + } + if (nCode >= 4536 && nCode <= 4537) + { + strValue = "TUAN"; + break; + } + if (nCode >= 4538 && nCode <= 4543) + { + strValue = "TUI"; + break; + } + if (nCode >= 4544 && nCode <= 4546) + { + strValue = "TUN"; + break; + } + if (nCode >= 4547 && nCode <= 4557) + { + strValue = "TUO"; + break; + } + if (nCode >= 4558 && nCode <= 4564) + { + strValue = "WA"; + break; + } + if (nCode >= 4565 && nCode <= 4566) + { + strValue = "WAI"; + break; + } + if (nCode >= 4567 && nCode <= 4583) + { + strValue = "WAN"; + break; + } + if (nCode >= 4584 && nCode <= 4593) + { + strValue = "WANG"; + break; + } + if (nCode >= 4594 && nCode <= 4632) + { + strValue = "WEI"; + break; + } + if (nCode >= 4633 && nCode <= 4642) + { + strValue = "WEN"; + break; + } + if (nCode >= 4643 && nCode <= 4645) + { + strValue = "WENG"; + break; + } + if (nCode >= 4646 && nCode <= 4654) + { + strValue = "WO"; + break; + } + if (nCode >= 4655 && nCode <= 4683) + { + strValue = "WU"; + break; + } + if (nCode >= 4684 && nCode <= 4724) + { + strValue = "XI"; + break; + } + if (nCode >= 4725 && nCode <= 4737) + { + strValue = "XIA"; + break; + } + if (nCode >= 4738 && nCode <= 4763) + { + strValue = "XIAN"; + break; + } + if (nCode >= 4764 && nCode <= 4783) + { + strValue = "XIANG"; + break; + } + if (nCode >= 4784 && nCode <= 4807) + { + strValue = "XIAO"; + break; + } + if (nCode >= 4809 && nCode <= 4828) + { + strValue = "XIE"; + break; + } + if (nCode >= 4829 && nCode <= 4838) + { + strValue = "XIN"; + break; + } + if (nCode >= 4839 && nCode <= 4853) + { + strValue = "XING"; + break; + } + if (nCode >= 4854 && nCode <= 4860) + { + strValue = "XIONG"; + break; + } + if (nCode >= 4861 && nCode <= 4869) + { + strValue = "XIU"; + break; + } + if (nCode >= 4870 && nCode <= 4888) + { + strValue = "XU"; + break; + } + if (nCode >= 4889 && nCode <= 4904) + { + strValue = "XUAN"; + break; + } + if (nCode >= 4905 && nCode <= 4910) + { + strValue = "XUE"; + break; + } + if (nCode >= 4911 && nCode <= 4924) + { + strValue = "XUN"; + break; + } + if (nCode >= 4925 && nCode <= 4940) + { + strValue = "YA"; + break; + } + if (nCode >= 4941 && nCode <= 4973) + { + strValue = "YAN"; + break; + } + if (nCode >= 4974 && nCode <= 4990) + { + strValue = "YANG"; + break; + } + if (nCode >= 4991 && nCode <= 5011) + { + strValue = "YAO"; + break; + } + if (nCode >= 5012 && nCode <= 5026) + { + strValue = "YE"; + break; + } + if (nCode >= 5027 && nCode <= 5079) + { + strValue = "YI"; + break; + } + if (nCode >= 5080 && nCode <= 5101) + { + strValue = "YIN"; + break; + } + if (nCode >= 5102 && nCode <= 5119) + { + strValue = "YING"; + break; + } + if (nCode == 5120) + { + strValue = "YO"; + break; + } + if (nCode >= 5121 && nCode <= 5135) + { + strValue = "YONG"; + break; + } + if (nCode >= 5136 && nCode <= 5155) + { + strValue = "YOU"; + break; + } + if (nCode >= 5156 && nCode <= 5206) + { + strValue = "YU"; + break; + } + if (nCode >= 5207 && nCode <= 5226) + { + strValue = "YUAN"; + break; + } + if (nCode >= 5227 && nCode <= 5236) + { + strValue = "YUE"; + break; + } + if (nCode >= 5237 && nCode <= 5248) + { + strValue = "YUN"; + break; + } + if (nCode >= 5249 && nCode <= 5251) + { + strValue = "ZA"; + break; + } + if (nCode >= 5252 && nCode <= 5258) + { + strValue = "ZAI"; + break; + } + if (nCode >= 5259 && nCode <= 5262) + { + strValue = "ZAN"; + break; + } + if (nCode >= 5263 && nCode <= 5265) + { + strValue = "ZANG"; + break; + } + if (nCode >= 5266 && nCode <= 5279) + { + strValue = "ZAO"; + break; + } + if (nCode >= 5280 && nCode <= 5283) + { + strValue = "ZE"; + break; + } + if (nCode == 5284) + { + strValue = "ZEI"; + break; + } + if (nCode == 5285) + { + strValue = "ZEN"; + break; + } + if (nCode >= 5286 && nCode <= 5289) + { + strValue = "ZENG"; + break; + } + if (nCode >= 5290 && nCode <= 5309) + { + strValue = "ZHA"; + break; + } + if (nCode >= 5310 && nCode <= 5315) + { + strValue = "ZHAI"; + break; + } + if (nCode >= 5316 && nCode <= 5332) + { + strValue = "ZHAN"; + break; + } + if (nCode >= 5333 && nCode <= 5347) + { + strValue = "ZHANG"; + break; + } + if (nCode >= 5348 && nCode <= 5357) + { + strValue = "ZHAO"; + break; + } + if (nCode >= 5358 && nCode <= 5367) + { + strValue = "ZHE"; + break; + } + if (nCode >= 5368 && nCode <= 5383) + { + strValue = "ZHEN"; + break; + } + if (nCode >= 5384 && nCode <= 5404) + { + strValue = "ZHENG"; + break; + } + if (nCode >= 5405 && nCode <= 5447) + { + strValue = "ZHI"; + break; + } + if (nCode >= 5448 && nCode <= 5458) + { + strValue = "ZHONG"; + break; + } + if (nCode >= 5459 && nCode <= 5472) + { + strValue = "ZHOU"; + break; + } + if (nCode >= 5473 && nCode <= 5504) + { + strValue = "ZHU"; + break; + } + if (nCode >= 5505 && nCode <= 5506) + { + strValue = "ZHUA"; + break; + } + if (nCode == 5507) + { + strValue = "ZHUAI"; + break; + } + if (nCode >= 5508 && nCode <= 5513) + { + strValue = "ZHUAN"; + break; + } + if (nCode >= 5514 && nCode <= 5520) + { + strValue = "ZHUANG"; + break; + } + if (nCode >= 5521 && nCode <= 5526) + { + strValue = "ZHUI"; + break; + } + if (nCode >= 5527 && nCode <= 5528) + { + strValue = "ZHUN"; + break; + } + if (nCode >= 5529 && nCode <= 5539) + { + strValue = "ZHUO"; + break; + } + if (nCode >= 5540 && nCode <= 5554) + { + strValue = "ZI"; + break; + } + if (nCode >= 5555 && nCode <= 5561) + { + strValue = "ZONG"; + break; + } + if (nCode >= 5562 && nCode <= 5565) + { + strValue = "ZOU"; + break; + } + if (nCode >= 5566 && nCode <= 5573) + { + strValue = "ZU"; + break; + } + if (nCode >= 5574 && nCode <= 5575) + { + strValue = "ZUAN"; + break; + } + if (nCode >= 5576 && nCode <= 5579) + { + strValue = "ZUI"; + break; + } + if (nCode >= 5580 && nCode <= 5581) + { + strValue = "ZUN"; + break; + } + if (nCode >= 5582 && nCode <= 5589) + { + strValue = "ZUO"; + break; + } + } + if (strValue == "") strValue = "?"; + return strValue; + } + std::string getLetter(std::string strText, bool head_only = false) + { + bool m_blnSimaple = head_only; + bool m_blnFirstBig = true; + bool m_blnAllBiG = true; + bool m_LetterEnd = false; + + unsigned char ucHigh, ucLow; + int nCode, j; + std::string strValue = ""; + for (int i = 0; i < strText.length(); i++) + { + if ((unsigned char)strText[i] < 0x80) + { + strValue = strValue + strText[i]; + if (m_LetterEnd) strValue = strValue + '/'; + continue; + } + ucHigh = (unsigned char)strText[i]; + ucLow = (unsigned char)strText[i + 1]; + if (ucHigh < 0xa1 || ucLow < 0xa1) + continue; + else + nCode = (ucHigh - 0xa0) * 100 + ucLow - 0xa0; + std::string strRes = findLetter(nCode); + if (m_blnSimaple && strRes.length() > 0) + { + strRes = strRes.substr(0, 1); + + } + if (!m_blnFirstBig) + { + //strRes.SetAt(0,strRes.GetAt(0)+32); + strRes[0] = strRes[0] + 32; + } + if (!m_blnAllBiG) + { + for (j = 1; j < strRes.length(); j++) + { + //strRes.SetAt(j,(strRes.GetAt(j)+32)); + strRes[j] = strRes[j] + 32; + } + } + strValue = strValue + strRes; + i++; + if (m_LetterEnd) strValue = strValue + '/'; + } + return strValue; + } + + void erase_ill_def(std::wstring& str) + { + for (int i = 0; i < str.length(); ++i) + { + if (str[i] == L' ' || str[i] == L'?') + { + str.erase(i, 1); + i--; + } + else if (str[i] == L'-' || str[i] == L'+') + { + str.replace(i, 1, L"_"); + } + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// name & title map ... +struct +{ + const char* name; + const char* title; +}g_opts[] = { {SANE_STD_OPT_NAME_RESTORE , OPTION_TITLE_HFMRSZ} + , {SANE_STD_OPT_NAME_HELP , OPTION_TITLE_BZ} + , {SANE_STD_OPT_NAME_IS_MULTI_OUT , OPTION_TITLE_DLSC} + , {SANE_STD_OPT_NAME_MULTI_OUT_TYPE , OPTION_TITLE_DLSCLX} + , {SANE_STD_OPT_NAME_COLOR_MODE , OPTION_TITLE_YSMS} + , {SANE_STD_OPT_NAME_BINARY_THRESHOLD , OPTION_TITLE_HBTXYZ} + , {SANE_STD_OPT_NAME_REVERSE_01 , OPTION_TITLE_HBTXFSSC} + , {SANE_STD_OPT_NAME_FILTER , OPTION_TITLE_HDHHBTX_CSYZQ} + , {SANE_STD_OPT_NAME_RID_MULTIOUT_RED , OPTION_TITLE_24WCSTX_DLSCCH} + , {SANE_STD_OPT_NAME_RID_ANSWER_SHEET_RED , OPTION_TITLE_24WCSTX_DTKCH} + , {SANE_STD_OPT_NAME_ERASE_BACKGROUND , OPTION_TITLE_BJYC} + , {SANE_STD_OPT_NAME_BKG_COLOR_RANGE , OPTION_TITLE_BJSCFDFW} + , {SANE_STD_OPT_NAME_SHARPEN , OPTION_TITLE_RHYMH} + , {SANE_STD_OPT_NAME_RID_MORR , OPTION_TITLE_QCMW} + , {SANE_STD_OPT_NAME_RID_GRID , OPTION_TITLE_CWW} + , {SANE_STD_OPT_NAME_ERROR_EXTENSION , OPTION_TITLE_CWKS} + , {SANE_STD_OPT_NAME_NOISE_OPTIMIZE , OPTION_TITLE_HBTXZDYH} + , {SANE_STD_OPT_NAME_NOISE_SIZE , OPTION_TITLE_ZDYHCC} + , {SANE_STD_OPT_NAME_PAPER , OPTION_TITLE_ZZCC} + , {SANE_STD_OPT_NAME_CUSTOM_AREA , OPTION_TITLE_ZDYSMQY} + , {SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT , OPTION_TITLE_SMQYZCmm} + , {SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT , OPTION_TITLE_SMQYYCmm} + , {SANE_STD_OPT_NAME_CUSTOM_AREA_TOP , OPTION_TITLE_SMQYSCmm} + , {SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM , OPTION_TITLE_SMQYXCmm} + , {SANE_STD_OPT_NAME_SIZE_CHECK , OPTION_TITLE_CCJC} + , {SANE_STD_OPT_NAME_PAGE , OPTION_TITLE_SMYM} + , {SANE_STD_OPT_NAME_DISCARD_BLANK_SENS , OPTION_TITLE_TGKBYLMD} + , {SANE_STD_OPT_NAME_RESOLUTION , OPTION_TITLE_FBL} + , {SANE_STD_OPT_NAME_TIME_TO_SLEEP , OPTION_TITLE_XMSJ} + , {SANE_STD_OPT_NAME_IMAGE_QUALITY , OPTION_TITLE_HZ} + , {SANE_STD_OPT_NAME_EXCHANGE ,OPTION_TITLE_JHZFM} + , {SANE_STD_OPT_NAME_SPLIT ,OPTION_TITLE_TXCF } + , {SANE_STD_OPT_NAME_ANTI_SKEW , OPTION_TITLE_ZDJP} + , {SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA , OPTION_TITLE_QYSDQX} + , {SANE_STD_OPT_NAME_GAMMA , OPTION_TITLE_JMZ} + , {SANE_STD_OPT_NAME_BRIGHTNESS , OPTION_TITLE_LDZ} + , {SANE_STD_OPT_NAME_CONTRAST , OPTION_TITLE_DBD} + , {SANE_STD_OPT_NAME_IS_PHOTO_MODE , OPTION_TITLE_ZPMS} + , {SANE_STD_OPT_NAME_ERASE_BLACK_FRAME , OPTION_TITLE_XCHK} + , {SANE_STD_OPT_NAME_DARK_SAMPLE , OPTION_TITLE_SSYZ} + , {SANE_STD_OPT_NAME_THRESHOLD , OPTION_TITLE_YZ} + , {SANE_STD_OPT_NAME_ANTI_NOISE_LEVEL , OPTION_TITLE_BJKZDJ} + , {SANE_STD_OPT_NAME_MARGIN , OPTION_TITLE_BYSJ} + , {SANE_STD_OPT_NAME_FILL_BKG_MODE , OPTION_TITLE_BJTCFS} + , {SANE_STD_OPT_NAME_IS_ANTI_PERMEATE , OPTION_TITLE_FZST} + , {SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL , OPTION_TITLE_FZSTDJ} + , {SANE_STD_OPT_NAME_RID_HOLE_L , OPTION_TITLE_CKYCZC} + , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_L , OPTION_TITLE_ZCCKSSFWZFMBL} + , {SANE_STD_OPT_NAME_RID_HOLE_R , OPTION_TITLE_CKYCYC} + , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_R , OPTION_TITLE_YCCKSSFWZFMBL} + , {SANE_STD_OPT_NAME_RID_HOLE_T , OPTION_TITLE_CKYCSC} + , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_T , OPTION_TITLE_SCCKSSFWZFMBL} + , {SANE_STD_OPT_NAME_RID_HOLE_B , OPTION_TITLE_CKYCXC} + , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_B , OPTION_TITLE_XCCKSSFWZFMBL} + , {SANE_STD_OPT_NAME_IS_FILL_COLOR , OPTION_TITLE_SCTC} + , {SANE_STD_OPT_NAME_IS_ULTROSONIC_CHECK , OPTION_TITLE_CSBJC} + , {SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE , OPTION_TITLE_SZTPCL} + , {SANE_STD_OPT_NAME_IS_CHECK_STAPLE , OPTION_TITLE_ZDJC} + , {SANE_STD_OPT_NAME_SCAN_MODE , OPTION_TITLE_SMZS} + , {SANE_STD_OPT_NAME_SCAN_COUNT , OPTION_TITLE_SMSL} + , {SANE_STD_OPT_NAME_TEXT_DIRECTION , OPTION_TITLE_WGFX} + , {SANE_STD_OPT_NAME_IS_ROTATE_BKG_180 , OPTION_TITLE_BMXZ180} + , {SANE_STD_OPT_NAME_IS_CHECK_DOG_EAR , OPTION_TITLE_ZJJC} + , {SANE_STD_OPT_NAME_DOG_EAR_SIZE , OPTION_TITLE_ZJDX} + , {SANE_STD_OPT_NAME_IS_CHECK_ASKEW , OPTION_TITLE_WXJC} + , {SANE_STD_OPT_NAME_ASKEW_RANGE , OPTION_TITLE_WXRRD} + , {SANE_STD_OPT_NAME_FEED_STRENGTH , OPTION_TITLE_FZQD} + , {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , OPTION_TITLE_ZDFZQD} + , {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , OPTION_TITLE_JZSBL} + , {SANE_STD_OPT_NAME_WAIT_TO_SCAN , OPTION_TITLE_DZSM} + , {SANE_STD_OPT_NAME_FOLD_TYPE , OPTION_TITLE_DZMS} + , {SANE_STD_OPT_NAME_COLOR_CORRECTION , OPTION_TITLE_SPJZ} + , {SANE_STD_OPT_NAME_WAIT_SCAN_EXIT , OPTION_TITLE_DZSMTCSJ} +}, +g_discard[] = { {SANE_STD_OPT_NAME_REVERSE_01 , "\351\273\221\347\231\275\345\233\276\345\203\217\345\217\215\350\211\262\350\276\223\345\207\272\357\274\210\346\255\243\345\270\270\351\242\234\350\211\262\344\270\272\357\274\2320-\351\273\221\350\211\262\357\274\2331-\347\231\275\350\211\262\357\274\211"} // ڰͼɫɫΪ0-ɫ1-ɫ + , {SANE_STD_OPT_NAME_FILTER , "\347\201\260\345\272\246\346\210\226\351\273\221\347\231\275\345\233\276\345\203\217 - \351\231\244\350\211\262"} // ҶȻڰͼ - ɫ + , {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // Զֽǿ + , {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " ֵֽ" +}; + +static IMPLEMENT_OPTION_STRING_COMPARE(compare_title); +static const char* title_to_name(std::wstring& title) +{ + std::string utf8(coding::u2utf8(title.c_str())); + + for (size_t i = 0; i < _countof(g_discard); ++i) + { + if (compare_title(g_discard[i].title, utf8.c_str())) + { + for (size_t j = 0; j < _countof(g_opts); ++j) + { + if (strcmp(g_opts[j].name, g_discard[i].name) == 0) + { + title = coding::utf82u(g_opts[j].title); + break; + } + } + + return g_discard[i].name; + } + } + + for (size_t i = 0; i < _countof(g_opts); ++i) + { + if (compare_title(g_opts[i].title, utf8.c_str())) + return g_opts[i].name; + } + + return NULL; +} + + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ChgjsonDlg dialog +static bool is_match(const char* str, const char* pattern) +{ + std::vector parts; + std::string all(pattern); + size_t pos = all.find("*"); + + while (pos != std::string::npos) + { + if (pos++) + parts.push_back(all.substr(0, pos)); + all.erase(0, pos); + pos = all.find("*"); + } + if (!all.empty()) + parts.push_back(all); + + for (pos = 0; pos < parts.size(); ++pos) + { + str = strstr(str, parts[pos].c_str()); + if (!str) + break; + str += parts[pos].length(); + } + + return pos == parts.size(); +} + +ChgjsonDlg::ChgjsonDlg(CWnd* pParent /*=NULL*/) + : CDialogEx(ChgjsonDlg::IDD, pParent) + , show_tree_tooltips_(true) + , show_list_tooltips_(true) +{ + std::string py(hz_2_py::getLetter("ɫģʽ", true)); + is_match("/usr/bin/python3.9", "bin*.9"); +} + +void ChgjsonDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_TREE1, tree_); + DDX_Control(pDX, IDC_LIST3, depends_); + DDX_Control(pDX, IDC_LIST_VALUES, constraint_list_); + DDX_Control(pDX, IDC_COMBO3, type_); + DDX_Control(pDX, IDC_COMBO4, constraint_); + DDX_Control(pDX, IDC_COMBO2, logic_); + DDX_Control(pDX, IDC_COMBO1, depend_item_); + DDX_Control(pDX, IDC_COMBO_DEFAULT, combo_default_); + DDX_Control(pDX, IDC_COMBO5, field_); + DDX_Control(pDX, IDC_COMBO6, unit_); + DDX_Control(pDX, IDC_COMBO7, group_); + DDX_Control(pDX, IDC_COMBO8, affect_); +} + +BEGIN_MESSAGE_MAP(ChgjsonDlg, CDialogEx) + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() +// ON_WM_PASTE() + ON_COMMAND(ID_TREE_ADDGROUP, &ChgjsonDlg::OnTreeAddGroup) + ON_COMMAND(ID_TREE_ADDITEM, &ChgjsonDlg::OnTreeAddItem) + ON_COMMAND(ID_TREE_DELITEM, &ChgjsonDlg::OnTreeDelItem) + ON_COMMAND(ID_TREE_ADDPRODUCT, &ChgjsonDlg::OnTreeAddProduct) + ON_BN_CLICKED(IDC_BUTTON3, &ChgjsonDlg::OnBnClickedButton3) + ON_BN_CLICKED(IDC_BUTTON1, &ChgjsonDlg::OnBnClickedButton1) + ON_BN_CLICKED(IDC_BUTTON2, &ChgjsonDlg::OnBnClickedButton2) + ON_CBN_SELCHANGE(IDC_COMBO3, &ChgjsonDlg::OnCbnSelchangeDataType) + ON_CBN_SELCHANGE(IDC_COMBO4, &ChgjsonDlg::OnCbnSelchangeConstraintType) + ON_CBN_SELCHANGE(IDC_COMBO1, &ChgjsonDlg::OnCbnSelchangeDependItem) + ON_CBN_SELCHANGE(IDC_COMBO2, &ChgjsonDlg::OnCbnSelchangeLogic) + ON_NOTIFY(LVN_ENDLABELEDIT, IDC_LIST_VALUES, &ChgjsonDlg::OnLvnEndlabeleditListValues) + ON_BN_CLICKED(IDC_CHECK1, &ChgjsonDlg::OnBnClickedDepend) + ON_BN_CLICKED(IDC_BUTTON4, &ChgjsonDlg::OnBnClickedButton4) + ON_NOTIFY(NM_RCLICK, IDC_TREE1, &ChgjsonDlg::OnNMRClickMfcshelltree1) + ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &ChgjsonDlg::OnTvnSelchangedTree1) + ON_COMMAND(ID_LISTMENU_SETDEFAULT, &ChgjsonDlg::OnListmenuSetdefault) + ON_COMMAND(ID_LISTMENU_DELETE, &ChgjsonDlg::OnListmenuDelete) + ON_NOTIFY(NM_RCLICK, IDC_LIST_VALUES, &ChgjsonDlg::OnNMRClickListValues) + ON_LBN_DBLCLK(IDC_LIST3, &ChgjsonDlg::OnLbnDblclkList3) + ON_WM_DROPFILES() + ON_COMMAND(ID_TREE_RENAME, &ChgjsonDlg::OnTreeRename) + ON_COMMAND(ID_TREE_LOADFILE, &ChgjsonDlg::OnTreeLoadfile) + ON_NOTIFY(LVN_KEYDOWN, IDC_LIST_VALUES, &ChgjsonDlg::OnLvnKeydownListValues) + ON_NOTIFY(TVN_KEYDOWN, IDC_TREE1, &ChgjsonDlg::OnTvnKeydownTree1) + ON_NOTIFY(TVN_GETINFOTIP, IDC_TREE1, &ChgjsonDlg::OnTvnGetInfoTipTree1) + ON_NOTIFY(LVN_GETINFOTIP, IDC_LIST_VALUES, &ChgjsonDlg::OnLvnGetInfoTipListValues) + ON_COMMAND(ID_TREE_TOOLTIPS, &ChgjsonDlg::OnTreeTooltips) + ON_COMMAND(ID_LISTMENU_TOOLTIPS, &ChgjsonDlg::OnListmenuTooltips) + ON_COMMAND(ID_TREE_EXPORTCHAR, &ChgjsonDlg::OnTreeExportCharConstants) + ON_BN_CLICKED(IDC_TO_FILE, &ChgjsonDlg::OnBnClickedToFile) + ON_COMMAND(ID_TREE_LOADCLIPBOARD, &ChgjsonDlg::OnTreeLoadClipboard) + ON_COMMAND(ID_TREE_UNIFYSEQUENCE, &ChgjsonDlg::OnTreeUnifySequence) +END_MESSAGE_MAP() + + +// ChgjsonDlg message handlers +int get_cur_sel(CListCtrl* lc) +{ + POSITION pos = lc->GetFirstSelectedItemPosition(); + int sel = lc->GetNextSelectedItem(pos); + + return sel; +} +std::wstring get_tree_item_text(CTreeCtrl* tree, HTREEITEM root, DWORD_PTR* data = NULL) +{ + CString t(tree->GetItemText(root)); + std::wstring ret(t.GetBuffer()); + + t.ReleaseBuffer(); + if (data) + *data = tree->GetItemData(root); + + return ret; +} +std::wstring get_tree_selected_item_text(CTreeCtrl* tree, DWORD_PTR* data) +{ + HTREEITEM sel = tree->GetSelectedItem(); + + if (data) + *data = 0; + + if (sel) + return get_tree_item_text(tree, sel, data); + else + return L""; +} +bool split(std::wstring str, ChgjsonDlg::DEPENDITEM* di) +{ + size_t pos = str.find(L"!"); + + if (pos == std::wstring::npos) + { + pos = str.find(L">"); + if (pos == std::wstring::npos) + { + pos = str.find(L"<"); + if (pos == std::wstring::npos) + { + pos = str.find(L"="); + } + } + } + + if (pos == std::wstring::npos) + return false; + + di->parent = str.substr(0, pos); + di->logic_values = str.substr(pos); + + return true; +} + +BOOL ChgjsonDlg::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + + // TODO: Add extra initialization here + ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD); + constraint_list_.InsertColumn(0, TEXT("Value lists"), 0, 177); + constraint_list_.InsertColumn(1, TEXT("Default"), 0, 48); + type_.SetCurSel(0); + unit_.SetCurSel(0); + field_.SetCurSel(0); + constraint_.SetCurSel(0); + // constraint_list_.ModifyStyleEx(0, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP); + constraint_list_.SetExtendedStyle(constraint_list_.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP); + constraint_list_.SetItemData(constraint_list_.InsertItem(constraint_list_.GetItemCount(), TEXT("click me to add value ...")), 1); + tree_menu_.LoadMenu(IDR_MENU1); + func_menu_.LoadMenu(IDR_MENU2); + + BITMAP bmi = { 0 }; + GetObject(LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1)), sizeof(bmi), &bmi); + tree_img_.Create(IDB_BITMAP1, bmi.bmWidth / 2, bmi.bmWidth / 2, RGB(255, 255, 255)); + tree_.SetImageList(&tree_img_, TVSIL_NORMAL); + ((CButton*)GetDlgItem(IDC_CHECK_VISIBLE))->SetCheck(BST_CHECKED); + init_control_statu(); + + return TRUE; // return TRUE unless you set the focus to a control +} + +void ChgjsonDlg::to_define_header(std::vector& defs, const wchar_t* str, const wchar_t* parent) +{ + while (*str == L' ') + str++; + + ChgjsonDlg::DEFH h; + std::string ansi(coding::u2a(str)); + std::wstring py(coding::a2u(hz_2_py::getLetter(ansi, true).c_str())); + + if (parent) + { + ansi = coding::u2a(parent); + h.name = OPT_VALUE_PREFIX; + h.name += coding::a2u(hz_2_py::getLetter(ansi, true).c_str()) + L"_"; + } + else + h.name = OPT_TITLE_PREFIX; + h.name += py; + hz_2_py::erase_ill_def(h.name); + if (std::find(defs.begin(), defs.end(), h.name) != defs.end()) + { + ansi = coding::u2a(str); + py = coding::a2u(hz_2_py::getLetter(ansi, false).c_str()); + if (parent) + { + ansi = coding::u2a(parent); + h.name = OPT_VALUE_PREFIX; + h.name += coding::a2u(hz_2_py::getLetter(ansi, true).c_str()) + L"_"; + } + else + h.name = OPT_TITLE_PREFIX; + h.name += py; + hz_2_py::erase_ill_def(h.name); + } + + h.value = str; + + ansi = coding::u2utf8(str); + for (size_t i = 0; i < ansi.length(); ++i) + { + wchar_t buf[8] = { 0 }; + + if ((unsigned char)ansi[i] <= 0x7f) + buf[0] = ansi[i]; + else + swprintf_s(buf, _countof(buf) - 1, L"\\%03o", (unsigned char)ansi[i]); + h.utf8_in_oct += buf; + } + + defs.push_back(h); +} +std::string ChgjsonDlg::save_define_header_2_file(std::vector& defs, const wchar_t* file) +{ + int max_l = 0; + std::wstring space(L""), + cont(L"//\r\n// definitions for option titles and values\r\n//\r\n// all multi-bytes letter are in UTF-8 format\r\n//\r\n"), + prev(L"none"); + wchar_t buf[128] = { 0 }; + time_t t = time(NULL); + struct tm* now = localtime(&t); + + swprintf(buf, L"// Date: %04d-%02d-%02d %02d:%02d:%02d\r\n//\r\n", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday + , now->tm_hour, now->tm_min, now->tm_sec); + cont += buf; + cont += L"\r\n#pragma once\r\n\r\n\r\n"; + + for (size_t i = 0; i < defs.size(); ++i) + { + if (max_l < defs[i].name.length()) + max_l = defs[i].name.length(); + } + + max_l += 15; + max_l /= 8; + max_l *= 8; + space.resize(max_l, L' '); + + for (size_t i = 0; i < defs.size(); ++i) + { + if (defs[i].name.find(prev) == std::wstring::npos) + { + cont += L"\r\n"; + prev = defs[i].name; + size_t pos = prev.rfind(L'_'); + if (pos != std::wstring::npos) + prev = prev.substr(pos); + } + cont += L"// #define " + defs[i].name; + cont += space.substr(0, max_l - defs[i].name.length() - 3); + cont += L"\"" + defs[i].value + L"\"\r\n"; + + cont += L"#define " + defs[i].name; + cont += space.substr(0, max_l - defs[i].name.length()); + cont += L"\"" + defs[i].utf8_in_oct + L"\"\r\n"; + } + + // reserve ... + std::wstring reserve(L"#define OPTION_TITLE_GMZ"); + max_l += 8; + reserve += space.substr(0, max_l - reserve.length()); + reserve += L"OPTION_TITLE_JMZ\r\n"; + + space.clear(); + space.resize(max_l, L'/'); + cont += L"\r\n\r\n" + space + L"\r\n// reserved ...\r\n" + space + L"\r\n" + reserve; + + // compare ... + cont += L"\r\n\r\n" + space + L"\r\n// string compare ...\r\n" + space + L"\r\n"; + cont += L"#define IMPLEMENT_OPTION_STRING_COMPARE(func_name) \\\r\n"; + cont += L" bool func_name(const char* opt_define, const char* value) \\\r\n"; + cont += L" { \\\r\n"; + cont += L" while(*value++ == L' '); \\\r\n"; + cont += L" value--; \\\r\n"; + cont += L" return strcmp(opt_define, value) == 0; \\\r\n"; + cont += L" }\r\n\r\n\r\n"; + std::string bom(""), utf8(coding::u2utf8(cont.c_str())); + + coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), coding::get_string, &bom); + if (file) + file_util::save_2_file(bom.c_str(), bom.length(), file); + else + { + file_util::set_clipboard(cont.c_str(), cont.length() * 2, CF_UNICODETEXT); + } + + return bom; +} + +void ChgjsonDlg::init_control_statu(void) +{ + HTREEITEM root = tree_.GetSelectedItem(); + BOOL valid = FALSE; + int type_ind = 0, constraint_ind = 0, default_ind = 1; + + GetDlgItem(IDC_STATIC_DEFAULT2)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_COMBO_DEFAULT)->ShowWindow(SW_HIDE); + + if (root) + { + DWORD_PTR ptr = NULL; + std::wstring t(get_tree_selected_item_text(&tree_, &ptr)); + DWORD data = (DWORD)ptr; + + if (data == TREE_ITEM_CONFIG) + { + std::vector::iterator it = std::find(hg_items_.begin(), hg_items_.end(), t.c_str()); + if (it != hg_items_.end()) + { + valid = TRUE; + set_control_status(*it); + } + } + } + + GetDlgItem(IDC_EDIT_DESC)->EnableWindow(valid); + GetDlgItem(IDC_CHECK_ADVANCED)->EnableWindow(valid); + GetDlgItem(IDC_CHECK_READONLY)->EnableWindow(valid); + GetDlgItem(IDC_CHECK_DEVICEONLY)->EnableWindow(valid); + constraint_.EnableWindow(valid); + depends_.EnableWindow(valid); + type_.EnableWindow(valid); + + GetDlgItem(IDC_RADIO_ALL)->EnableWindow(valid); + GetDlgItem(IDC_RADIO_ANY)->EnableWindow(valid); + depend_item_.EnableWindow(valid); + logic_.EnableWindow(valid); + GetDlgItem(IDC_EDIT_LOWER)->EnableWindow(valid); + GetDlgItem(IDC_BUTTON1)->EnableWindow(valid); + GetDlgItem(IDC_BUTTON2)->EnableWindow(valid); + GetDlgItem(IDC_BUTTON3)->EnableWindow(valid); + GetDlgItem(IDC_BUTTON4)->EnableWindow(valid); +} +void ChgjsonDlg::delete_tree_item(HTREEITEM root) +{ + HTREEITEM child = tree_.GetChildItem(root); + + while (child) + { + delete_tree_item(child); + child = tree_.GetChildItem(root); + } + + std::wstring name(get_tree_item_text(&tree_, root)); + std::vector::iterator it = std::find(hg_items_.begin(), hg_items_.end(), name.c_str()); + + tree_.DeleteItem(root); + if (it != hg_items_.end()) + { + // delete depending items ... + for (size_t i = 0; i < hg_items_.size(); ++i) + { + if (i == it - hg_items_.begin()) + continue; + + std::vector::iterator d = std::find(hg_items_[i].depend.begin(), hg_items_[i].depend.end(), name.c_str()); + while (d != hg_items_[i].depend.end()) + { + hg_items_[i].depend.erase(d); + d = std::find(hg_items_[i].depend.begin(), hg_items_[i].depend.end(), name.c_str()); + } + } + hg_items_.erase(it); + } +} +int ChgjsonDlg::find_config_item(const wchar_t* item_name) +{ + std::vector::iterator it = std::find(hg_items_.begin(), hg_items_.end(), item_name); + + if (it == hg_items_.end()) + return -1; + else + return it - hg_items_.begin(); +} +int ChgjsonDlg::check_depend(const wchar_t* l, const wchar_t* r) +{ + // -1: l depends on r; 0: no depend; 1: r depends on l + int depend = 0; + std::vector::iterator il = std::find(hg_items_.begin(), hg_items_.end(), l), + ir = std::find(hg_items_.begin(), hg_items_.end(), r); + + if (il != hg_items_.end() && ir != hg_items_.end()) + { + std::vector::iterator it = std::find(il->depend.begin(), il->depend.end(), r); + if (it != il->depend.end()) + depend = -1; + else + { + it = std::find(ir->depend.begin(), ir->depend.end(), l); + if (it != ir->depend.end()) + depend = 1; + } + } + + return depend; +} +void ChgjsonDlg::set_control_status(const HGITEM& item) +{ + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_DESC, item.desc.c_str()); + + if (item.type == L"bool") + type_.SetCurSel(0); + else if (item.type == L"int") + type_.SetCurSel(1); + else if (item.type == L"float") + type_.SetCurSel(2); + else if (item.type == L"string") + type_.SetCurSel(3); + else // if (item.type == L"button") + type_.SetCurSel(4); + + ((CButton*)GetDlgItem(IDC_CHECK_ADVANCED))->SetCheck(item.advanced ? BST_CHECKED : BST_UNCHECKED); + ((CButton*)GetDlgItem(IDC_CHECK_READONLY))->SetCheck(item.readonly ? BST_CHECKED : BST_UNCHECKED); + //((CButton*)GetDlgItem(IDC_CHECK_DEVICEONLY))->SetCheck(item.deviceonly ? BST_CHECKED : BST_UNCHECKED); + ((CButton*)GetDlgItem(IDC_CHECK_VISIBLE))->SetCheck(item.visible ? BST_CHECKED : BST_UNCHECKED); + + SetDlgItemInt(IDC_EDIT_POS, item.position); + field_.SetCurSel(item.field); + unit_.SetCurSel(item.unit); + group_.SetCurSel(coding::group_index(item.group.c_str())); + affect_.SetCurSel(item.affect >> 1); + + // value ... + GetDlgItem(IDC_STATIC_FROM)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_TO)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_FROM)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_TO)->ShowWindow(SW_HIDE); + constraint_list_.ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_DEFAULT)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_COMBO_DEFAULT)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_STEP)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_STEP)->ShowWindow(SW_HIDE); + constraint_.SetCurSel(item.range.type); + if (item.range.type == RANGE_TYPE_NONE) + { + GetDlgItem(IDC_STATIC_DEFAULT)->ShowWindow(SW_SHOW); + if (item.type == L"bool") + { + GetDlgItem(IDC_COMBO_DEFAULT)->ShowWindow(SW_SHOW); + ((CComboBox*)GetDlgItem(IDC_COMBO_DEFAULT))->SetCurSel(item.init_val == L"true"); + } + else + { + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_SHOW); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_DEFAULT, item.init_val.c_str()); + } + } + else if (item.range.type == RANGE_TYPE_RANGE) + { + GetDlgItem(IDC_STATIC_DEFAULT)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_SHOW); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_DEFAULT, item.init_val.c_str()); + + GetDlgItem(IDC_STATIC_FROM)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_STATIC_TO)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_FROM)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_TO)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_STEP)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_STATIC_STEP)->ShowWindow(SW_SHOW); + + if (item.type == L"int") + { + SetDlgItemInt(IDC_EDIT_FROM, item.range.lower); + SetDlgItemInt(IDC_EDIT_TO, item.range.upper); + SetDlgItemInt(IDC_EDIT_STEP, item.range.step); + } + else + { + wchar_t buf[80] = { 0 }; + + swprintf_s(buf, _countof(buf) - 1, L"%f", item.range.lower); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_FROM, buf); + + swprintf_s(buf, _countof(buf) - 1, L"%f", item.range.upper); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_TO, buf); + + swprintf_s(buf, _countof(buf) - 1, L"%f", item.range.step); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_STEP, buf); + } + } + else // list + { + constraint_list_.ShowWindow(SW_SHOW); + constraint_list_.DeleteAllItems(); + for (size_t i = 0; i < item.range.queue.size(); ++i) + { + int ind = constraint_list_.InsertItem(constraint_list_.GetItemCount(), item.range.queue[i].c_str()); + if (item.range.queue[i] == item.init_val) + constraint_list_.SetItemText(ind, 1, TEXT("yes")); + } + + int ind = constraint_list_.InsertItem(constraint_list_.GetItemCount(), TEXT("click me to add new item ...")); + constraint_list_.SetItemData(ind, 1); + } + + // depend + ((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(BST_UNCHECKED); + ((CButton*)GetDlgItem(IDC_RADIO_ANY))->SetCheck(BST_UNCHECKED); + ((CButton*)GetDlgItem(IDC_RADIO_ALL))->SetCheck(BST_UNCHECKED); + GetDlgItem(IDC_RADIO_ALL)->EnableWindow(FALSE); + GetDlgItem(IDC_RADIO_ANY)->EnableWindow(FALSE); + GetDlgItem(IDC_EDIT_LOWER)->EnableWindow(FALSE); + GetDlgItem(IDC_COMBO_BOOL)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_AND)->EnableWindow(FALSE); + GetDlgItem(IDC_EDIT_UPPER)->EnableWindow(FALSE); + GetDlgItem(IDC_BUTTON3)->EnableWindow(FALSE); + GetDlgItem(IDC_LIST3)->EnableWindow(FALSE); + depends_.ResetContent(); + if (item.depend.size()) + { + ((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(BST_CHECKED); + OnBnClickedDepend(); + if (item.depend_or) + { + ((CButton*)GetDlgItem(IDC_RADIO_ANY))->SetCheck(BST_CHECKED); + ((CButton*)GetDlgItem(IDC_RADIO_ALL))->SetCheck(BST_UNCHECKED); + } + else + { + ((CButton*)GetDlgItem(IDC_RADIO_ANY))->SetCheck(BST_UNCHECKED); + ((CButton*)GetDlgItem(IDC_RADIO_ALL))->SetCheck(BST_CHECKED); + } + for (size_t i = 0; i < item.depend.size(); ++i) + { + depends_.AddString((item.depend[i].parent + item.depend[i].logic_values).c_str()); + } + } +} + +void* ChgjsonDlg::create_json(int item, std::vector* def_h, std::wstring* name) +{ + known_file_util::IJsonW* jsn = known_file_util::create_jsonW(); + wchar_t buf[128] = { 0 }; + int prefer_size = 0; + const char* opt_name = title_to_name(hg_items_[item].title); + + jsn->set_value(L"category", hg_items_[item].advanced ? L"advanced" : L"base"); + jsn->set_value(L"readonly", hg_items_[item].readonly); + jsn->set_value(L"affect", hg_items_[item].affect); + //jsn->set_value(L"hwonly", hg_items_[item].deviceonly); + jsn->set_value(L"group", hg_items_[item].group.c_str()); + jsn->set_value(L"visible", hg_items_[item].visible); + jsn->set_value(L"field", field_name(hg_items_[item].field)); + jsn->set_value(L"pos", hg_items_[item].position); + jsn->set_value(L"unit", unit_name(hg_items_[item].unit)); + if (name) + { + if (opt_name) + { + // jsn->set_value(L"name", coding::utf82u(opt_name).c_str()); + *name = coding::utf82u(opt_name); + } + else + { + swprintf_s(buf, _countof(buf) - 1, L"cfg-%d", hg_items_[item].index); + // jsn->set_value(L"name", buf); + *name = buf; + } + } + + jsn->set_value(L"title", hg_items_[item].title.c_str()); + if (def_h) + ChgjsonDlg::to_define_header(*def_h, hg_items_[item].title.c_str()); + jsn->set_value(L"desc", hg_items_[item].desc.c_str()); + jsn->set_value(L"type", hg_items_[item].type.c_str()); + if (hg_items_[item].type == L"bool") + { + jsn->set_value(L"cur", hg_items_[item].init_val == L"true"); + jsn->set_value(L"default", hg_items_[item].init_val == L"true"); + } + else if (hg_items_[item].type == L"int") + { + jsn->set_value(L"cur", _wtoi(hg_items_[item].init_val.c_str())); + jsn->set_value(L"default", _wtoi(hg_items_[item].init_val.c_str())); + } + else if (hg_items_[item].type == L"float") + { + jsn->set_value(L"cur", _wtof(hg_items_[item].init_val.c_str())); + jsn->set_value(L"default", _wtof(hg_items_[item].init_val.c_str())); + } + else + { + jsn->set_value(L"cur", hg_items_[item].init_val.c_str()); + jsn->set_value(L"default", hg_items_[item].init_val.c_str()); + } + jsn->set_value(L"size", hg_items_[item].bytes); + + if (hg_items_[item].range.type == RANGE_TYPE_RANGE) + { + known_file_util::IJsonW* r = known_file_util::create_jsonW(); + if (hg_items_[item].type == L"int") + { + r->set_value(L"min", (int)hg_items_[item].range.lower); + r->set_value(L"max", (int)hg_items_[item].range.upper); + r->set_value(L"step", (int)hg_items_[item].range.step); + } + else + { + r->set_value(L"min", hg_items_[item].range.lower); + r->set_value(L"max", hg_items_[item].range.upper); + r->set_value(L"step", hg_items_[item].range.step); + } + jsn->set_value(L"range", r); + r->release(); + } + else if (hg_items_[item].range.type == RANGE_TYPE_LIST) + { + known_file_util::IJsonW* r = known_file_util::create_jsonW(); + r->set_as_array(true); + if (hg_items_[item].type == L"int") + { + for (size_t i = 0; i < hg_items_[item].range.queue.size(); ++i) + { + *r += _wtoi(hg_items_[item].range.queue[i].c_str()); + } + } + else if (hg_items_[item].type == L"float") + { + for (size_t i = 0; i < hg_items_[item].range.queue.size(); ++i) + { + *r += _wtof(hg_items_[item].range.queue[i].c_str()); + } + } + else if (hg_items_[item].type == L"string") + { + int size = 0; + for (size_t i = 0; i < hg_items_[item].range.queue.size(); ++i) + { + *r += hg_items_[item].range.queue[i].c_str(); + if (def_h) + ChgjsonDlg::to_define_header(*def_h, hg_items_[item].range.queue[i].c_str(), hg_items_[item].title.c_str()); + if (size < coding::string_need_bytes(hg_items_[item].range.queue[i].c_str())) + size = coding::string_need_bytes(hg_items_[item].range.queue[i].c_str()); + } + if (hg_items_[item].bytes < size) + jsn->set_value(L"size", size); + } + jsn->set_value(L"range", r); + r->release(); + } + + if (hg_items_[item].depend.size()) + { + std::wstring prev(L""); + + std::sort(hg_items_[item].depend.begin(), hg_items_[item].depend.end()); + known_file_util::IJsonW* d = known_file_util::create_jsonW(); + d->set_as_array(true); + for (int i = 0; i < hg_items_[item].depend.size(); ++i) + { + int ind = find_config_item(hg_items_[item].depend[i].parent.c_str()); + if (ind != -1) + { + std::wstring n(coding::utf82u(title_to_name(hg_items_[ind].title))); + if (prev != n) + { + *d += (n + hg_items_[item].depend[i].logic_values).c_str(); + prev = n; + } + else + *d += hg_items_[item].depend[i].logic_values.c_str(); + } + } + + if (hg_items_[item].depend_or) + jsn->set_value(L"depend_or", d); + else + jsn->set_value(L"depend_and", d); + d->release(); + } + if (prefer_size) + jsn->set_value(L"size", prefer_size); + + return jsn; +} +std::string ChgjsonDlg::to_json_text(bool for_const, std::wstring* dev) +{ + known_file_util::IJsonW* jsn = known_file_util::create_jsonW(), * item = NULL, *glb = known_file_util::create_jsonW(); + HTREEITEM root = tree_.GetRootItem(), child = NULL; + std::wstring val(get_tree_item_text(&tree_, root)), grpname(L""); + int count = 1, group = 1, ind = 0; + wchar_t buf[128] = { 0 }; + + std::vector header; + std::wstring file(L""); + { + wchar_t path[MAX_PATH] = { 0 }, * name = NULL; + GetModuleFileNameW(NULL, path, _countof(path) - 1); + name = wcsrchr(path, L'\\'); + if (name++ == NULL) + name = path; + swprintf(name, L"%s_option_definitions.h", val.c_str()); + file = path; + } + + if (dev) + *dev = val; + glb->set_value(L"device_type", val.c_str()); + jsn->set_value(L"global", glb); + root = tree_.GetChildItem(root); + while (root) + { + if ((DWORD)tree_.GetItemData(root) == TREE_ITEM_CONFIG) + { + val = get_tree_item_text(&tree_, root); + ind = find_config_item(val.c_str()); + if (ind != -1) + { + std::wstring key(L""); + hg_items_[ind].index = count++; + item = (known_file_util::IJsonW*)create_json(ind, &header, &key); + //item->set_value(L"group", grpname.c_str()); + // swprintf_s(buf, _countof(buf) - 1, L"%d", hg_items_[ind].index); + jsn->set_value(key.c_str(), item); + item->release(); + item = NULL; + } + } + else + { + val = get_tree_item_text(&tree_, root); + item = known_file_util::create_jsonW(); + item->set_value(L"category", L"base"); + swprintf_s(buf, _countof(buf) - 1, L"grp-%d", group++); + grpname = buf; + // item->set_value(L"name", buf); + item->set_value(L"title", val.c_str()); + item->set_value(L"type", L"group"); + // swprintf_s(buf, _countof(buf) - 1, L"%d", count++); + count++; + jsn->set_value(buf, item); + + child = tree_.GetChildItem(root); + while (child) + { + val = get_tree_item_text(&tree_, child); + ind = find_config_item(val.c_str()); + if (ind != -1) + { + hg_items_[ind].index = count++; + if (item) + { + item->set_value(L"category", hg_items_[ind].advanced ? L"advanced" : L"base"); + item->set_value(L"readonly", hg_items_[ind].readonly); + item->set_value(L"affect", hg_items_[ind].affect); + //item->set_value(L"hwonly", hg_items_[ind].deviceonly); + item->set_value(L"group", hg_items_[ind].group.c_str()); + item->set_value(L"field", field_name(hg_items_[ind].field)); + item->set_value(L"pos", hg_items_[ind].position); + item->set_value(L"visible", hg_items_[ind].visible); + item->set_value(L"unit", unit_name(hg_items_[ind].unit)); + item->release(); + } + std::wstring key(L""); + item = (known_file_util::IJsonW*)create_json(ind, &header, &key); + //item->set_value(L"group", grpname.c_str()); + + // swprintf_s(buf, _countof(buf) - 1, L"%d", hg_items_[ind].index); + jsn->set_value(key.c_str(), item); + item->release(); + item = NULL; + } + child = tree_.GetNextSiblingItem(child); + } + if (item) + item->release(); + } + + root = tree_.GetNextSiblingItem(root); + } + + val = L""; + glb->set_value(L"option_count", count); + glb->release(); + jsn->to_string(coding::get_wstring, &val); + jsn->release(); + + std::string utf8(""); + coding_util::unicode_2_utf8(val.c_str(), coding::get_string, &utf8); + if (header.size()) + { + if (for_const) + { + utf8 = ChgjsonDlg::save_define_header_2_file(header, NULL); + } + //else + //{ + // ChgjsonDlg::save_define_header_2_file(header, file.c_str()); + // file_util::display_file_in_explorer(file.c_str()); + //} + } + + return utf8; +} +void ChgjsonDlg::add_item(void* jsn_root, void* jsn_obj, HTREEITEM parent, bool old_ver) +{ + known_file_util::IJsonW* jsn = (known_file_util::IJsonW*)jsn_obj, * child = NULL, + * root = (known_file_util::IJsonW*)jsn_root; + std::wstring grp(get_tree_item_text(&tree_, parent)); + const wchar_t* val = NULL; + HGITEM item; + wchar_t buf[128] = { 0 }; + + jsn->get_value(L"title", &val); + if (!val) + return; + + item.title = val; + parent = add_tree_item(val, TREE_ITEM_CONFIG, parent); + + jsn->get_value(L"desc", &val); + if (val) + item.desc = val; + + jsn->get_value(L"type", &val); + if (val) + item.type = val; + + if (item.type == L"bool") + { + bool v = false; + jsn->get_value(L"default", v); + item.init_val = v ? L"true" : L"false"; + } + else if (item.type == L"int") + { + int v = 0; + jsn->get_value(L"default", v); + swprintf_s(buf, _countof(buf) - 1, L"%d", v); + item.init_val = buf; + } + else if (item.type == L"float") + { + double v = 0; + jsn->get_value(L"default", v); + swprintf_s(buf, _countof(buf) - 1, L"%f", v); + item.init_val = buf; + } + else + { + jsn->get_value(L"default", &val); + if (val) + item.init_val = val; + else + item.init_val = L""; + } + jsn->get_value(L"size", item.bytes); + + jsn->get_value(L"category", &val); + if (val && wcscmp(val, L"advanced") == 0) + item.advanced = true; + if (!jsn->get_value(L"readonly", item.readonly)) + item.readonly = false; + if (!jsn->get_value(L"affect", item.affect)) + item.affect = 0; + //if (!jsn->get_value(L"hwonly", item.deviceonly)) + // item.deviceonly = false; + if (jsn->get_value(L"group", &val) && val) + { + item.group = coding::group_name(coding::group_index(val)); + } + else + item.group = coding::group_name(coding::group_index(grp.c_str()));; + if (!jsn->get_value(L"visible", item.visible)) + item.visible = true; + item.field = 0; + jsn->get_value(L"field", &val); + if (val) + item.field = field_index(val); + item.unit = 0; + jsn->get_value(L"unit", &val); + if(val) + item.unit = unit_index(val); + if (!jsn->get_value(L"pos", item.position)) + item.position = 0; + + + jsn->get_value(L"depend_and", &child); + if (child) + { + item.depend_or = false; + } + else + { + jsn->get_value(L"depend_or", &child); + if (child) + item.depend_or = true; + } + if (child) + { + if (child->members()) + { + known_file_util::JSONMEMW m = child->first_member(known_file_util::JV_STRING); + DEPENDITEM di; + std::wstring parent_item(L""); + int num = 1; + + do + { + if (split(m.str_val, &di)) + { + known_file_util::IJsonW* d = NULL; + if (di.parent.empty()) + di.parent = parent_item; + else + parent_item = di.parent; + root->get_value(di.parent.c_str(), &d); + if (d) + { + d->get_value(L"title", &val); + if (val) + { + di.parent = val; + item.depend.push_back(di); + } + d->release(); + } + } + m = child->next_member(); + } while (num++ < child->members()); + } + child->release(); + } + + jsn->get_value(L"range", &child); + if (child) + { + if (item.type == L"int") + { + int l = 0, u = 0, s = 0; + if (child->get_value(L"min", l)) + { + child->get_value(L"max", u); + item.range.lower = l; + item.range.upper = u; + if (child->get_value(L"step", s)) + item.range.step = s; + else + item.range.step = 1; + item.range.type = RANGE_TYPE_RANGE; + } + else + { + item.range.type = RANGE_TYPE_LIST; + if (child->members()) + { + known_file_util::JSONMEMW m = child->first_member(known_file_util::JV_INT); + swprintf_s(buf, _countof(buf) - 1, L"%d", m.double_val); + item.range.queue.push_back(buf); + for (int i = 1; i < child->members(); ++i) + { + m = child->next_member(); + swprintf_s(buf, _countof(buf) - 1, L"%d", m.double_val); + item.range.queue.push_back(buf); + } + } + } + } + else if (item.type == L"float") + { + if (child->get_value(L"min", item.range.lower)) + { + child->get_value(L"max", item.range.upper); + if (!child->get_value(L"step", item.range.step)) + item.range.step = (item.range.upper - item.range.lower) / 10.0f; + item.range.type = RANGE_TYPE_RANGE; + } + else + { + item.range.type = RANGE_TYPE_LIST; + + if (child->members()) + { + known_file_util::JSONMEMW m = child->first_member(known_file_util::JV_FLOAT); + swprintf_s(buf, _countof(buf) - 1, L"%f", m.double_val); + item.range.queue.push_back(buf); + for (int i = 1; i < child->members(); ++i) + { + m = child->next_member(); + swprintf_s(buf, _countof(buf) - 1, L"%f", m.double_val); + item.range.queue.push_back(buf); + } + } + } + } + else if (item.type == L"string") + { + item.range.type = RANGE_TYPE_LIST; + if (child->members()) + { + known_file_util::JSONMEMW m = child->first_member(known_file_util::JV_STRING); + item.range.queue.push_back(m.str_val); + for (int i = 1; i < child->members(); ++i) + { + m = child->next_member(); + item.range.queue.push_back(m.str_val); + } + } + } + + child->release(); + } + else + item.range.type = RANGE_TYPE_NONE; + + hg_items_.push_back(item); +} +bool ChgjsonDlg::load_from_json_text(const wchar_t* txt, std::wstring* err_msg) +{ + int pos = 0; + known_file_util::IJsonW* jsn = known_file_util::create_jsonW(txt, &pos), * child = NULL; + + if (!jsn) + { + int ep = 10, len = 10; + if (lstrlenW(txt + pos) < 10) + len = lstrlenW(txt + pos); + if (pos < 10) + { + ep = pos; + pos = 10; + } + pos -= 10; + + std::wstring info(txt + pos, len + ep + 1); + wchar_t msg[80] = { 0 }; + + swprintf_s(msg, L"Error at position %d of char '%c'!\r\n\r\n", ep, info[ep]); + if (err_msg) + *err_msg = msg + info; + else + ::MessageBoxW(m_hWnd, (msg + info).c_str(), L"Load Error", MB_OK); + + return false; + } + + hg_items_.clear(); + tree_.DeleteAllItems(); + + const wchar_t* val = NULL; + HTREEITEM root = NULL, son = NULL; + int count = 0; + bool old_ver = false; + + jsn->get_value(L"device_type", &val); + if (val) + { + root = add_tree_item(val, TREE_ITEM_PRODUCT); + jsn->get_value(L"option_count", count); + old_ver = true; + } + else + { + known_file_util::IJsonW* all = nullptr; + jsn->get_value(L"global", &all); + if (all) + { + all->get_value(L"device_type", &val); + if(val) + root = add_tree_item(val, TREE_ITEM_PRODUCT); + all->release(); + } + if (!root) + { + jsn->release(); + return false; + } + } + son = root; + + GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); + GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE); + if (old_ver) + { + for (int i = 1; i < count; ++i) + { + wchar_t key[20] = { 0 }; + + swprintf_s(key, _countof(key) - 1, L"%d", i); + jsn->get_value(key, &child); + if (child) + { + child->get_value(L"type", &val); + if (val) + { + if (wcscmp(val, L"group") == 0) + { + child->get_value(L"title", &val); + if (!val) + { + swprintf_s(key, _countof(key) - 1, L"group-%d", i); + val = key; + } + son = add_tree_item(val, TREE_ITEM_GROUP, root); + } + else + { + add_item(jsn, child, son, old_ver); + } + } + child->release(); + } + } + } + else if (child = jsn->first_child()) + { + int sn = 0; + wchar_t key[20] = { 0 }; + + child->release(); + while ((child = jsn->next_child())) + { + child->get_value(L"type", &val); + if (val) + { + if (wcscmp(val, L"group") == 0) + { + child->get_value(L"title", &val); + if (!val) + { + swprintf_s(key, _countof(key) - 1, L"group-%d", ++sn); + val = key; + } + son = add_tree_item(val, TREE_ITEM_GROUP, root); + } + else + { + add_item(jsn, child, son, old_ver); + } + } + child->release(); + } + } + + jsn->release(); + tree_.Expand(root, TVE_EXPAND); + + return true; +} +bool ChgjsonDlg::load_from_file(const wchar_t* path_file) +{ + std::string cont(""); + std::wstring unic(L""); + bool ret = false; + + file_util::load_file(path_file, coding::get_string, &cont); + coding_util::bom::to_unicode(cont.c_str(), cont.length(), coding::get_wstring, &unic); + if (unic.length()) + { + if (!load_from_json_text(unic.c_str())) + { + unic = path_file; + unic.insert(0, L"Parse json file '"); + unic += L"' failed"; + ::MessageBoxW(m_hWnd, unic.c_str(), L"Error", MB_OK); + } + else + ret = true; + } + + return ret; +} +void ChgjsonDlg::get_all_names(HTREEITEM root, std::vector& names, DWORD mask) +{ + if (((DWORD)tree_.GetItemData(root) & mask) == mask) + names.push_back(get_tree_item_text(&tree_, root)); + + HTREEITEM child = tree_.GetChildItem(root); + while (child) + { + get_all_names(child, names, mask); + + child = tree_.GetNextSiblingItem(child); + } +} +void ChgjsonDlg::on_config_name_changed(const wchar_t* prev, const wchar_t* now) +{ + for (size_t i = 0; i < hg_items_.size(); ++i) + { + if (hg_items_[i].title == prev) + { + hg_items_[i].title = now; + } + else + { + std::vector::iterator it = std::find(hg_items_[i].depend.begin(), hg_items_[i].depend.end(), prev); + while (it != hg_items_[i].depend.end()) + { + it->parent = now; + it = std::find(hg_items_[i].depend.begin(), hg_items_[i].depend.end(), prev); + } + } + } +} +HTREEITEM ChgjsonDlg::add_tree_item(const wchar_t* title, DWORD data, HTREEITEM parent, HTREEITEM after) +{ + HTREEITEM i = tree_.InsertItem(title, parent, after); + TVITEM item; + + item.mask = TVIF_SELECTEDIMAGE; + item.iSelectedImage = 1; + item.hItem = i; + tree_.SetItem(&item); + + tree_.SetItemData(i, (DWORD_PTR)data); + + return i; +} + +void ChgjsonDlg::filter_tree_item(HTREEITEM item, const std::vector& filter) +{ + DWORD_PTR data = NULL; + std::wstring title(get_tree_item_text(&tree_, item, &data)); + + if (data == (DWORD_PTR)TREE_ITEM_GROUP) + { + HTREEITEM child = tree_.GetChildItem(item), + next = NULL; + while (child) + { + next = tree_.GetNextSiblingItem(child); + filter_tree_item(child, filter); + child = next; + } + } + else if (data == (DWORD_PTR)TREE_ITEM_CONFIG) + { + const char* name = title_to_name(title), * filter_name = NULL; + int ind = find_config_item(title.c_str()), fi = -1; + + for (size_t i = 0; i < filter.size(); ++i) + { + std::wstring t(filter[i].title); + + filter_name = title_to_name(t); + if (filter_name == name) + { + fi = i; + break; + } + } + if (filter_name != name) + { + if (strstr(name, "is-rid-hole-") != name && + strstr(name, "search-hole-range-") != name) + delete_tree_item(item); + } + else + { + HGITEM hgi(hg_items_[ind]); + hg_items_[ind] = filter[fi]; + hg_items_[ind].title = hgi.title; + hg_items_[ind].desc = hgi.desc; + for (size_t i = 0; i < hg_items_[ind].depend.size(); ++i) + title_to_name(hg_items_[ind].depend[i].parent); + } + } +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void ChgjsonDlg::OnPaint() +{ + //if (IsIconic()) + //{ + // CPaintDC dc(this); // device context for painting + + // SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); + + // // Center icon in client rectangle + // int cxIcon = GetSystemMetrics(SM_CXICON); + // int cyIcon = GetSystemMetrics(SM_CYICON); + // CRect rect; + // GetClientRect(&rect); + // int x = (rect.Width() - cxIcon + 1) / 2; + // int y = (rect.Height() - cyIcon + 1) / 2; + + // // Draw the icon + // dc.DrawIcon(x, y, m_hIcon); + //} + //else + { + CDialogEx::OnPaint(); + } +} + +// The system calls this function to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR ChgjsonDlg::OnQueryDragIcon() +{ + return NULL;// static_cast(m_hIcon); +} + +void ChgjsonDlg::OnPaste() +{ + coding::CLPD clpb; + + file_util::get_clipboard(coding::get_clipboard_content, &clpb); + if (clpb.cont.empty()) + { + MessageBox(TEXT("clipboard is empty.")); + return; + } + + if (clpb.file) + { + size_t pos = clpb.cont.find(L"\r\n"); + bool loaded = false; + + while (!loaded && pos != std::wstring::npos) + { + loaded = load_from_file(clpb.cont.substr(0, pos).c_str()); + clpb.cont.erase(0, pos + 2); + pos = clpb.cont.find(L"\r\n"); + } + if (!loaded && file_util::is_file_existing(clpb.cont.c_str())) + load_from_file(clpb.cont.c_str()); + } + else + { + std::wstring err(L""); + if (load_from_json_text(clpb.cont.c_str(), &err)) + return; + + // we assum the content from codes ... + std::wstring jsn(L""); + size_t pos = clpb.cont.find(L" std::string"); + + while (pos != std::wstring::npos) + { + clpb.cont.erase(0, pos); + pos = clpb.cont.find(L"\""); + if (pos == std::wstring::npos) + break; + clpb.cont.erase(0, pos + 1); + pos = clpb.cont.find(L"\");"); + if (pos == std::wstring::npos) + { + jsn += clpb.cont; + break; + } + else + jsn += clpb.cont.substr(0, pos); + clpb.cont.erase(0, pos); + pos = clpb.cont.find(L" std::string"); + } + + if (jsn.length()) + { + pos = jsn.find(L"\\\\"); + while (pos != std::wstring::npos) + { + jsn.erase(pos++, 1); + pos = jsn.find(L"\\\\", pos); + } + pos = jsn.find(L"\\\""); + while (pos != std::wstring::npos) + { + jsn.erase(pos++, 1); + pos = jsn.find(L"\\\"", pos); + } + + load_from_json_text(jsn.c_str()); + } + else + ::MessageBoxW(m_hWnd, err.c_str(), L"Load Error", MB_OK); + } +} + + +void ChgjsonDlg::OnTreeAddProduct() +{ + // TODO: Add your command handler code here + CDlgInput input; + + get_all_names(tree_.GetRootItem(), input.used_names_); + if (input.DoModal() == IDOK) + { + add_tree_item(input.value_.GetBuffer(), TREE_ITEM_PRODUCT); + input.value_.ReleaseBuffer(); + } +} +void ChgjsonDlg::OnTreeAddGroup() +{ + // TODO: Add your command handler code here + HTREEITEM parent = tree_.GetSelectedItem(); + + if (parent) + { + CDlgInput input; + + get_all_names(tree_.GetRootItem(), input.used_names_); + if (input.DoModal() == IDOK) + { + HTREEITEM h = add_tree_item(input.value_.GetBuffer(), TREE_ITEM_GROUP, parent); + + tree_.SelectItem(h); + tree_.EnsureVisible(h); + input.value_.ReleaseBuffer(); + OnTvnSelchangedTree1(NULL, NULL); + } + } +} +void ChgjsonDlg::OnTreeAddItem() +{ + // TODO: Add your command handler code here + HTREEITEM parent = tree_.GetSelectedItem(); + + if (parent) + { + CDlgInput input; + + get_all_names(tree_.GetRootItem(), input.used_names_); + if (input.DoModal() == IDOK) + { + HTREEITEM h = add_tree_item(input.value_.GetBuffer(), TREE_ITEM_CONFIG, parent); + + input.value_.ReleaseBuffer(); + if (h) + { + HGITEM i(input.value_.GetBuffer()); + + input.value_.ReleaseBuffer(); + tree_.SelectItem(h); + tree_.EnsureVisible(h); + + hg_items_.push_back(i); + OnTvnSelchangedTree1(NULL, NULL); + } + } + } +} +void ChgjsonDlg::OnTreeDelItem() +{ + // TODO: Add your command handler code here + HTREEITEM parent = tree_.GetSelectedItem(); + if (parent) + { + delete_tree_item(parent); + OnTvnSelchangedTree1(NULL, NULL); + } +} +void ChgjsonDlg::OnTreeRename() +{ + // TODO: Add your command handler code here + DWORD_PTR ptr = NULL; + std::wstring t(get_tree_selected_item_text(&tree_, &ptr)); + CDlgInput input; + + get_all_names(tree_.GetRootItem(), input.used_names_); + std::vector::iterator it = std::find(input.used_names_.begin(), input.used_names_.end(), t); + if (it != input.used_names_.end()) + input.used_names_.erase(it); + + input.value_ = t.c_str(); + if (input.DoModal() == IDOK && input.value_.GetLength()) + { + std::wstring now(input.value_); + TVITEM item; + + item.mask = TVIF_TEXT; + item.pszText = &now[0]; + item.hItem = tree_.GetSelectedItem(); + tree_.SetItem(&item); + if ((DWORD)ptr == TREE_ITEM_CONFIG) + { + on_config_name_changed(t.c_str(), now.c_str()); + } + } +} + + +void ChgjsonDlg::OnBnClickedButton1() +{ + // TODO: Add your control notification handler code here + // export to file + std::string txt(to_json_text()); + + file_util::set_clipboard(txt.c_str(), txt.length()); + MessageBox(TEXT("JSON text has set to clipboard already")); +} +void ChgjsonDlg::OnBnClickedButton2() +{ + // TODO: Add your control notification handler code here + // export to code-text, replace '"' with '\"', '\' with '\\' + std::string txt(to_json_text()); + size_t pos = txt.find("\""); + + while (pos != std::string::npos) + { + txt.insert(pos, "\\"); + pos = txt.find("\"", pos + 2); + } + + pos = txt.find("\\u"); + while (pos != std::string::npos) + { + txt.insert(pos, "\\"); + pos = txt.find("\\u", pos + 3); + } + + // divide into multi-lines with 16KB per line ... + int lines = 1; + char var[80] = { 0 }; + + pos = txt.length(); + while (pos > 16 * 1024) + { + pos -= 12 * 1024; + while (txt[pos - 1] == '\\') + pos++; + lines++; + sprintf_s(var, _countof(var) - 1, "\");\r\nstatic std::string jsontext%d(\"", lines); + txt.insert(pos, var); + } + txt.insert(0, "static std::string jsontext1(\""); + txt += "\");\r\n"; + + file_util::set_clipboard(txt.c_str(), txt.length()); + + TCHAR msg[128] = { 0 }; + _stprintf(msg, TEXT("%d lines"), lines); + MessageBox(TEXT("JSON text has set to clipboard already"), msg); +} + + +void ChgjsonDlg::OnCbnSelchangeDataType() +{ + // TODO: Add your control notification handler code here + // bool;int;float;string; + wchar_t type[40] = { 0 }; + + ::GetWindowTextW(type_.m_hWnd, type, _countof(type) - 1); + constraint_.ResetContent(); + constraint_.AddString(TEXT("none")); + if (wcscmp(type, L"bool") == 0) + { + constraint_.SetCurSel(0); + combo_default_.SetCurSel(1); + } + else + { + constraint_.AddString(TEXT("range")); + constraint_.AddString(TEXT("list")); + + constraint_.SetCurSel(0); + combo_default_.ShowWindow(SW_HIDE); + } + OnCbnSelchangeConstraintType(); +} +void ChgjsonDlg::OnCbnSelchangeConstraintType() +{ + // TODO: Add your control notification handler code here + // none;range;list; + int sel = constraint_.GetCurSel(); + wchar_t type[40] = { 0 }; + + ::GetWindowTextW(type_.m_hWnd, type, _countof(type) - 1); + if (wcscmp(type, L"string") == 0 && sel == 1) + { + MessageBox(TEXT("'string' type cannot be in RANGE constraint.")); + constraint_.SetCurSel(0); + sel = 0; + } + + combo_default_.ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_DEFAULT)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_DEFAULT2)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_FROM)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_TO)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_FROM)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_TO)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_STEP)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC_STEP)->ShowWindow(SW_HIDE); + constraint_list_.ShowWindow(SW_HIDE); + + if (sel == 0) + { + if (wcscmp(type, L"string") == 0) + GetDlgItem(IDC_STATIC_DEFAULT2)->ShowWindow(SW_SHOW); + else + GetDlgItem(IDC_STATIC_DEFAULT)->ShowWindow(SW_SHOW); + if (wcscmp(type, L"bool") == 0) + combo_default_.ShowWindow(SW_SHOW); + else + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_SHOW); + } + else if (sel == 1) + { + GetDlgItem(IDC_STATIC_FROM)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_STATIC_TO)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_FROM)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_TO)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_STATIC_DEFAULT)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_DEFAULT)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_STEP)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_STATIC_STEP)->ShowWindow(SW_SHOW); + } + else // if( sel == 2) + { + constraint_list_.ShowWindow(SW_SHOW); + } +} + + +void ChgjsonDlg::OnCbnSelchangeDependItem() +{ + // TODO: Add your control notification handler code here + int sel = depend_item_.GetCurSel(), d_ind = -1; + wchar_t name[128] = { 0 }, type[128] = { 0 }; + + ::GetWindowTextW(depend_item_.m_hWnd, name, _countof(name) - 1); + ::GetWindowTextW(type_.m_hWnd, type, _countof(type) - 1); + d_ind = find_config_item(name); + if (d_ind < 0) + { + std::wstring info(L"Depend item '"); + info += name; + info += L"' is not found!"; + ::MessageBoxW(m_hWnd, info.c_str(), L"Err", MB_OK); + return; + } + + // ==;!=;>;>=;<;<=;between;out of; + GetDlgItem(IDC_STATIC_AND)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_UPPER)->ShowWindow(SW_HIDE); + + logic_.ResetContent(); + logic_.AddString(L"=="); + logic_.AddString(L"!="); + GetDlgItem(IDC_COMBO_BOOL)->ShowWindow(SW_SHOW); + if (hg_items_[d_ind].type == L"bool") + { + GetDlgItem(IDC_COMBO_BOOL)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_LOWER)->ShowWindow(SW_HIDE); + + CComboBox* val = (CComboBox*)GetDlgItem(IDC_COMBO_BOOL); + val->ResetContent(); + val->AddString(L"false"); + val->AddString(L"true"); + val->SetCurSel(1); + } + else if (hg_items_[d_ind].range.queue.size()) + { + GetDlgItem(IDC_COMBO_BOOL)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_LOWER)->ShowWindow(SW_HIDE); + + CComboBox* val = (CComboBox*)GetDlgItem(IDC_COMBO_BOOL); + val->ResetContent(); + for (int i = 0; i < hg_items_[d_ind].range.queue.size(); ++i) + { + val->AddString(hg_items_[d_ind].range.queue[i].c_str()); + } + val->SetCurSel(0); + } + else + { + if (hg_items_[d_ind].type == L"int" || hg_items_[d_ind].type == L"float") + { + logic_.AddString(L">"); + logic_.AddString(L">="); + logic_.AddString(L"<="); + logic_.AddString(L"<"); + logic_.AddString(L"between"); + logic_.AddString(L"out of"); + } + GetDlgItem(IDC_EDIT_LOWER)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_COMBO_BOOL)->ShowWindow(SW_HIDE); + } + logic_.SetCurSel(0); + OnCbnSelchangeLogic(); +} +void ChgjsonDlg::OnCbnSelchangeLogic() +{ + // TODO: Add your control notification handler code here + int count = logic_.GetCount(), + sel = logic_.GetCurSel(); + wchar_t text[128] = { 0 }; + + GetDlgItem(IDC_STATIC_AND)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_UPPER)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_UPPER)->EnableWindow(FALSE); + + ::GetWindowTextW(logic_.m_hWnd, text, _countof(text) - 1); + if (wcscmp(text, L"between") == 0 || wcscmp(text, L"out of") == 0) + { + GetDlgItem(IDC_STATIC_AND)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_UPPER)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_UPPER)->EnableWindow(); + GetDlgItem(IDC_STATIC_AND)->EnableWindow(); + } +} + + +void ChgjsonDlg::OnLvnEndlabeleditListValues(NMHDR* pNMHDR, LRESULT* pResult) +{ + NMLVDISPINFO* pDispInfo = reinterpret_cast(pNMHDR); + // TODO: Add your control notification handler code here + *pResult = 0; + DWORD_PTR data = constraint_list_.GetItemData(pDispInfo->item.iItem); + + if (!pDispInfo->item.pszText || *pDispInfo->item.pszText == 0) + return; + + constraint_list_.SetItemText(pDispInfo->item.iItem, pDispInfo->item.iSubItem, pDispInfo->item.pszText); + constraint_list_.SetItemData(pDispInfo->item.iItem, 0); + if (constraint_list_.GetItemCount() == 1) + constraint_list_.SetItemText(pDispInfo->item.iItem, 1, TEXT("yes")); + + if (data) + { + int count = constraint_list_.GetItemCount(); + count = constraint_list_.InsertItem(count, TEXT("click me to add value ...")); + constraint_list_.SetItemData(count, 1); + } +} + + +void ChgjsonDlg::OnBnClickedDepend() +{ + // TODO: Add your control notification handler code here + // ---G100 + // | + // ---base + // | + // ---color-mode + // | + // ---scan-count + // + // ---advance + // | + // --- + HTREEITEM root = tree_.GetSelectedItem(); + BOOL enable = ((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck() == BST_CHECKED; + + if (root) + { + if (enable) + { + if ((DWORD)tree_.GetItemData(root) != TREE_ITEM_CONFIG) + { + ((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(BST_UNCHECKED); + MessageBox(TEXT("You must select a configuration item in the left tree first!"), NULL, MB_OK); + return; + } + + std::wstring name(get_tree_item_text(&tree_, root)); + std::vector confs; + + get_all_names(tree_.GetRootItem(), confs, TREE_ITEM_CONFIG); + depends_.ResetContent(); + depend_item_.ResetContent(); + for (size_t i = 0; i < confs.size(); ++i) + { + if (confs[i] == name) + break; + + depend_item_.AddString(confs[i].c_str()); + } + } + + GetDlgItem(IDC_RADIO_ANY)->EnableWindow(enable); + GetDlgItem(IDC_RADIO_ALL)->EnableWindow(enable); + ((CButton*)GetDlgItem(IDC_RADIO_ANY))->SetCheck(BST_CHECKED); + depend_item_.EnableWindow(enable); + logic_.EnableWindow(enable); + GetDlgItem(IDC_EDIT_LOWER)->EnableWindow(enable); + GetDlgItem(IDC_BUTTON3)->EnableWindow(enable); + GetDlgItem(IDC_LIST3)->EnableWindow(enable); + } + else if (enable) + { + ((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(BST_UNCHECKED); + MessageBox(TEXT("You must select a configuration item in the left tree!"), NULL, MB_OK); + } +} + + +void ChgjsonDlg::OnBnClickedButton3() +{ + // TODO: Add your control notification handler code here + // add depend items + DEPENDITEM di; + wchar_t oper[128] = { 0 }; + bool or = ((CButton*)GetDlgItem(IDC_RADIO_ANY))->GetCheck() == BST_CHECKED; + DWORD_PTR data = NULL; + std::wstring name(get_tree_selected_item_text(&tree_, &data)); + std::vector::iterator it = std::find(hg_items_.begin(), hg_items_.end(), name.c_str()); + + if (it == hg_items_.end()) + { + name.insert(0, L"Not found the configuration named: "); + ::MessageBoxW(m_hWnd, name.c_str(), L"Error", MB_OK); + + return; + } + ::GetWindowTextW(depend_item_.m_hWnd, oper, _countof(oper) - 1); + di.parent = oper; + + // check recycle depend ... + std::vector::iterator dpn = std::find(hg_items_.begin(), hg_items_.end(), oper); + if (dpn != hg_items_.end()) + { + std::vector::iterator dpnd = std::find(dpn->depend.begin(), dpn->depend.end(), di.parent.c_str()); + if (dpnd != dpn->depend.end()) + { + name.insert(0, L" is already DEPEND on me("); + name.insert(0, oper); + name += L")! Delete me from it's depend queue first."; + ::MessageBoxW(m_hWnd, name.c_str(), L"Recycle Depending", MB_ICONSTOP | MB_OK); + return; + } + } + + ::GetWindowTextW(logic_.m_hWnd, oper, _countof(oper) - 1); + if (wcscmp(oper, L"between") == 0) + { + di.logic_values = L"==["; + ::GetWindowTextW(GetDlgItem(IDC_EDIT_LOWER)->m_hWnd, oper, _countof(oper) - 1); + di.logic_values += oper; + di.logic_values += L", "; + ::GetWindowTextW(GetDlgItem(IDC_EDIT_UPPER)->m_hWnd, oper, _countof(oper) - 1); + di.logic_values += oper; + di.logic_values += L"]"; + } + else if (wcscmp(oper, L"out of") == 0) + { + di.logic_values = L"!=["; + ::GetWindowTextW(GetDlgItem(IDC_EDIT_LOWER)->m_hWnd, oper, _countof(oper) - 1); + di.logic_values += oper; + di.logic_values += L", "; + ::GetWindowTextW(GetDlgItem(IDC_EDIT_UPPER)->m_hWnd, oper, _countof(oper) - 1); + di.logic_values += oper; + di.logic_values += L"]"; + } + else + { + di.logic_values = oper; + if (::IsWindowVisible(GetDlgItem(IDC_EDIT_LOWER)->m_hWnd)) + ::GetWindowTextW(GetDlgItem(IDC_EDIT_LOWER)->m_hWnd, oper, _countof(oper) - 1); + else + ::GetWindowTextW(GetDlgItem(IDC_COMBO_BOOL)->m_hWnd, oper, _countof(oper) - 1); + di.logic_values += oper; + } + + it->depend.push_back(di); + it->depend_or = or ; + // if (depends_.FindString(-1, (di.parent + di.logic_values).c_str()) == -1) + depends_.AddString((di.parent + di.logic_values).c_str()); +} +void ChgjsonDlg::OnBnClickedButton4() +{ + // TODO: Add your control notification handler code here + // modify item attributes + DWORD_PTR data = NULL; + std::wstring name(get_tree_selected_item_text(&tree_, &data)); + + if ((DWORD)data != TREE_ITEM_CONFIG) + { + name += L" is not a configuration item."; + ::MessageBoxW(m_hWnd, name.c_str(), L"Err", MB_OK); + + return; + } + + std::vector::iterator it = std::find(hg_items_.begin(), hg_items_.end(), name.c_str()); + if (it == hg_items_.end()) + { + name += L" is not found."; + ::MessageBoxW(m_hWnd, name.c_str(), L"Err", MB_OK); + + return; + } + + wchar_t str[128] = { 0 }; + bool is_str = false; + + ::GetDlgItemTextW(m_hWnd, IDC_EDIT_DESC, str, _countof(str) - 1); + it->desc = str; + it->title = name; + + ::GetWindowTextW(type_.m_hWnd, str, _countof(str) - 1); + it->type = str; + it->advanced = ((CButton*)GetDlgItem(IDC_CHECK_ADVANCED))->GetCheck() == BST_CHECKED; + it->readonly = ((CButton*)GetDlgItem(IDC_CHECK_READONLY))->GetCheck() == BST_CHECKED; + //it->deviceonly = ((CButton*)GetDlgItem(IDC_CHECK_DEVICEONLY))->GetCheck() == BST_CHECKED; + //::GetDlgItemTextW(m_hWnd, IDC_COMBO7, str, _countof(str) - 1); + it->group = coding::group_name(group_.GetCurSel()); + it->affect = affect_.GetCurSel() << 1; + it->visible = ((CButton*)GetDlgItem(IDC_CHECK_VISIBLE))->GetCheck() == BST_CHECKED; + it->range.type = constraint_.GetCurSel(); + it->field = field_.GetCurSel(); + it->unit = unit_.GetCurSel(); + it->position = GetDlgItemInt(IDC_EDIT_POS); + if (it->type == L"bool") + it->bytes = sizeof(SANE_Bool); + else if (it->type == L"int") + it->bytes = sizeof(SANE_Int); + else if (it->type == L"float") + it->bytes = sizeof(SANE_Fixed); + else // if (wcscmp(str, L"string") == 0) + { + it->bytes = GetDlgItemInt(IDC_EDIT_DEFAULT); + if (it->bytes <= 1 && it->range.type != RANGE_TYPE_LIST) + { + MessageBox(TEXT("Input max length in bytes of 'string' type")); + GotoDlgCtrl(GetDlgItem(IDC_EDIT_DEFAULT)); + return; + } + is_str = true; + } + + // constraints ... + it->range.queue.clear(); + if (it->range.type == RANGE_TYPE_LIST) + { + for (int i = 0; i < constraint_list_.GetItemCount(); ++i) + { + if (constraint_list_.GetItemData(i)) + continue; + + constraint_list_.GetItemText(i, 0, str, _countof(str) - 1); + it->range.queue.push_back(str); + if (is_str && it->bytes < coding::string_need_bytes(str)) // utf-8 need 3 bytes to present one char + it->bytes = coding::string_need_bytes(str); + constraint_list_.GetItemText(i, 1, str, _countof(str) - 1); + if (wcscmp(str, L"yes") == 0) + it->init_val = it->range.queue[it->range.queue.size() - 1]; + } + } + else + { + ::GetDlgItemTextW(m_hWnd, it->type == L"bool" ? IDC_COMBO_DEFAULT : IDC_EDIT_DEFAULT, str, _countof(str) - 1); + it->init_val = str; + + if (it->range.type == RANGE_TYPE_RANGE) + { + ::GetDlgItemTextW(m_hWnd, IDC_EDIT_FROM, str, _countof(str) - 1); + it->range.lower = _wtof(str); + ::GetDlgItemTextW(m_hWnd, IDC_EDIT_TO, str, _countof(str) - 1); + it->range.upper = _wtof(str); + ::GetDlgItemTextW(m_hWnd, IDC_EDIT_STEP, str, _countof(str) - 1); + it->range.step = _wtof(str); + if (fabs(it->range.step) < .000001f) + it->range.step = (it->range.upper - it->range.lower) / 10.0f; + } + } + + // depend ... + it->depend.clear(); + if (((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck() == BST_CHECKED) + { + it->depend_or = ((CButton*)GetDlgItem(IDC_RADIO_ANY))->GetCheck() == BST_CHECKED; + for (int i = 0; i < depends_.GetCount(); ++i) + { + DEPENDITEM di; + + depends_.GetText(i, str); + split(str, &di); + it->depend.push_back(di); + } + } +} + + +void ChgjsonDlg::OnNMRClickMfcshelltree1(NMHDR* pNMHDR, LRESULT* pResult) +{ + // TODO: Add your control notification handler code here + *pResult = 0; + POINT pt = { 0 }; + HTREEITEM hsel = tree_.GetSelectedItem(); + + tree_menu_.EnableMenuItem(ID_TREE_ADDGROUP, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_ADDITEM, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_ADDPRODUCT, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_DELITEM, MF_DISABLED); + tree_menu_.EnableMenuItem(ID_TREE_RENAME, MF_DISABLED); + tree_menu_.CheckMenuItem(ID_TREE_TOOLTIPS, show_tree_tooltips_ ? MF_CHECKED : MF_UNCHECKED); + if (hsel) + { + DWORD data = (DWORD)tree_.GetItemData(hsel); + if (data == TREE_ITEM_PRODUCT) + { + tree_menu_.EnableMenuItem(ID_TREE_ADDGROUP, MF_ENABLED); + } + else if (data == TREE_ITEM_GROUP) + { + tree_menu_.EnableMenuItem(ID_TREE_ADDITEM, MF_ENABLED); + } + tree_menu_.EnableMenuItem(ID_TREE_DELITEM, MF_ENABLED); + tree_menu_.EnableMenuItem(ID_TREE_RENAME, MF_ENABLED); + } + else + tree_menu_.EnableMenuItem(ID_TREE_ADDPRODUCT, MF_ENABLED); + + GetCursorPos(&pt); + tree_menu_.GetSubMenu(0)->TrackPopupMenu(0, pt.x, pt.y, this); +} + + +void ChgjsonDlg::OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); + // TODO: Add your control notification handler code here + if (pResult) + *pResult = 0; + + init_control_statu(); +} + + +void ChgjsonDlg::OnListmenuSetdefault() +{ + // TODO: Add your command handler code here + int sel = get_cur_sel(&constraint_list_); + std::wstring text(get_tree_item_text(&tree_, tree_.GetSelectedItem())); + int item = find_config_item(text.c_str()); + + if (item == -1) + return; + + + if (sel >= 0 && sel < constraint_list_.GetItemCount()) + { + wchar_t cur[128] = { 0 }; + constraint_list_.GetItemText(sel, 0, cur, _countof(cur) - 1); + hg_items_[item].init_val = cur; + for (int i = 0; i < constraint_list_.GetItemCount(); ++i) + { + if (constraint_list_.GetItemData(i)) + continue; + + constraint_list_.SetItemText(i, 1, i == sel ? TEXT("yes") : TEXT("")); + } + } +} + + +void ChgjsonDlg::OnListmenuDelete() +{ + // TODO: Add your command handler code here + int sel = get_cur_sel(&constraint_list_); + + if (sel >= 0 && sel < constraint_list_.GetItemCount()) + { + TCHAR buf[20] = { 0 }; + constraint_list_.GetItemText(sel, 1, buf, _countof(buf) - 1); + constraint_list_.DeleteItem(sel); + if (_tcscmp(buf, TEXT("yes")) == 0) + { + if (constraint_list_.GetItemCount() > 1) + constraint_list_.SetItemText(0, 1, TEXT("yes")); + } + } +} + + +void ChgjsonDlg::OnNMRClickListValues(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); + // TODO: Add your control notification handler code here + *pResult = 0; + POINT pt = { 0 }; + int sel = get_cur_sel(&constraint_list_); + + func_menu_.CheckMenuItem(ID_LISTMENU_TOOLTIPS, show_list_tooltips_ ? MF_CHECKED : MF_UNCHECKED); + if (sel >= 0 && sel < constraint_list_.GetItemCount()) + { + if (constraint_list_.GetItemData(sel) == 0) + { + GetCursorPos(&pt); + func_menu_.GetSubMenu(0)->TrackPopupMenu(0, pt.x, pt.y, this); + } + } +} + + +void ChgjsonDlg::OnLbnDblclkList3() +{ + // TODO: Add your control notification handler code here + int sel = depends_.GetCurSel(); + + if (sel >= 0 && sel < depends_.GetCount()) + { + TCHAR text[128] = { 0 }; + + depends_.GetText(sel, text); + if (MessageBox(text, TEXT("Delete ?"), MB_YESNO) == IDYES) + depends_.DeleteString(sel); + } +} + + +void ChgjsonDlg::OnDropFiles(HDROP hDropInfo) +{ + // TODO: Add your message handler code here and/or call default + wchar_t path[MAX_PATH] = { 0 }; + + DragQueryFileW(hDropInfo, 0, path, _countof(path) - 1); + load_from_file(path); + + CDialogEx::OnDropFiles(hDropInfo); +} + +void ChgjsonDlg::OnTreeLoadfile() +{ + // TODO: Add your command handler code here + file_util::PATHFILE path = { 0 }; + + if (file_util::browser_file(m_hWnd, &path)) + { + load_from_file(path.path); + } +} + +void ChgjsonDlg::OnTreeLoadClipboard() +{ + // TODO: ڴ + OnPaste(); +} + + +void ChgjsonDlg::OnTreeUnifySequence() +{ + // TODO: ڴ + file_util::PATHFILE path = { 0 }; + + if (!file_util::browser_file(m_hWnd, &path)) + return; + + std::vector me(hg_items_); + HTREEITEM root = tree_.GetRootItem(), + child = NULL, + next = NULL; + std::wstring model(get_tree_item_text(&tree_, root)); + + if (!load_from_file(path.path)) + return; + + root = tree_.GetRootItem(); + child = tree_.GetChildItem(root); + while (child) + { + DWORD_PTR data = NULL; + std::wstring title(get_tree_item_text(&tree_, child, &data)); + + next = tree_.GetNextSiblingItem(child); + filter_tree_item(child, me); + + child = next; + } + tree_.SetItemText(root, model.c_str()); +} + +void ChgjsonDlg::OnLvnKeydownListValues(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast(pNMHDR); + // TODO: Add your control notification handler code here + *pResult = 0; + + if (GetKeyState(VK_CONTROL) < 0) + { + int sel = get_cur_sel(&constraint_list_), dir = 0; + TCHAR t0[200] = { 0 }, t1[20] = { 0 }; + + if (constraint_list_.GetItemData(sel) == 0) + { + if (pLVKeyDow->wVKey == VK_UP) + { + if (sel > 0) + dir = -1; + } + else if (pLVKeyDow->wVKey == VK_DOWN) + { + if (sel < constraint_list_.GetItemCount() - 1) + dir = 1; + } + } + if (dir) + { + constraint_list_.GetItemText(sel, 0, t0, _countof(t0) - 1); + constraint_list_.GetItemText(sel, 1, t1, _countof(t1) - 1); + constraint_list_.DeleteItem(sel); + sel += dir; + + sel = constraint_list_.InsertItem(sel, t0); + constraint_list_.SetItemText(sel, 1, t1); + + constraint_list_.SetItemState(sel - dir, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); + constraint_list_.SetSelectionMark(sel - dir); + } + } +} + + +void ChgjsonDlg::OnTvnKeydownTree1(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMTVKEYDOWN pTVKeyDown = reinterpret_cast(pNMHDR); + // TODO: Add your control notification handler code here + if (pResult) + *pResult = 0; + + if (pTVKeyDown->wVKey != VK_UP && pTVKeyDown->wVKey != VK_DOWN) + return; + if (GetKeyState(VK_CONTROL) >= 0) + return; + + HTREEITEM sel = tree_.GetSelectedItem(), next = NULL, parent = tree_.GetParentItem(sel); + DWORD_PTR data = NULL; + std::wstring name(get_tree_selected_item_text(&tree_, &data)); + + if ((DWORD)data != TREE_ITEM_CONFIG) + return; + + if (pTVKeyDown->wVKey == VK_DOWN) + { + next = tree_.GetNextSiblingItem(sel); + if (!next) + { + parent = tree_.GetNextSiblingItem(parent); + if (parent) + { + next = TVI_FIRST; + tree_.Expand(parent, TVIS_EXPANDED); + } + } + else + { + if ((DWORD)tree_.GetItemData(next) == TREE_ITEM_GROUP) + { + parent = next; + next = TVI_FIRST; + } + else if (check_depend(name.c_str(), get_tree_item_text(&tree_, next).c_str()) == 1) + next = NULL; + } + } + else if (pTVKeyDown->wVKey == VK_UP) + { + next = tree_.GetPrevSiblingItem(sel); + if (!next) + { + if (parent != tree_.GetRootItem()) + { + parent = tree_.GetPrevSiblingItem(parent); + if (parent) + { + if ((DWORD)tree_.GetItemData(parent) == TREE_ITEM_CONFIG) + { + next = parent; + parent = tree_.GetParentItem(parent); + } + else + { + next = TVI_LAST; + tree_.Expand(parent, TVIS_EXPANDED); + } + } + else + { + parent = tree_.GetParentItem(tree_.GetParentItem(sel)); + next = TVI_FIRST; + } + } + } + else + { + if (check_depend(name.c_str(), get_tree_item_text(&tree_, next).c_str()) == -1) + next = NULL; + else + { + next = tree_.GetPrevSiblingItem(next); + if (!next) + next = TVI_FIRST; + } + } + } + + if (next) + { + tree_.DeleteItem(sel); + sel = add_tree_item(name.c_str(), data, parent, next); + tree_.SelectItem(sel); + } +} + + +void ChgjsonDlg::OnTvnGetInfoTipTree1(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMTVGETINFOTIP pGetInfoTip = reinterpret_cast(pNMHDR); + // TODO: Add your control notification handler code here + *pResult = 0; + + if (show_tree_tooltips_) + _tcscpy(pGetInfoTip->pszText, TEXT("Ctrl + or can change the configuration item position.")); +} + + +void ChgjsonDlg::OnLvnGetInfoTipListValues(NMHDR* pNMHDR, LRESULT* pResult) +{ + LPNMLVGETINFOTIP pGetInfoTip = reinterpret_cast(pNMHDR); + // TODO: Add your control notification handler code here + *pResult = 0; + + if (show_list_tooltips_) + _tcscpy(pGetInfoTip->pszText, TEXT("Ctrl + or can change the option position.")); +} + + +void ChgjsonDlg::OnTreeTooltips() +{ + // TODO: Add your command handler code here + show_tree_tooltips_ ^= true; +} + + +void ChgjsonDlg::OnListmenuTooltips() +{ + // TODO: Add your command handler code here + show_list_tooltips_ ^= true; +} + + +void ChgjsonDlg::OnTreeExportCharConstants() +{ + // TODO: ڴ + std::string bom(to_json_text(true)); + if (bom.empty()) + MessageBox(TEXT("No char constant")); + else + MessageBox(TEXT("const string has set to clipboard already")); +} + + +void ChgjsonDlg::OnBnClickedToFile() +{ + // TODO: ڴӿؼ֪ͨ + std::wstring name(L""); + std::string txt(to_json_text(false, &name)), ansi(""); + wchar_t path[MAX_PATH] = { 0 }; + + GetModuleFileNameW(NULL, path, _countof(path) - 1); + wcsrchr(path, L'\\')[1] = 0; + name.insert(0, path); + name += L".hsc"; + ansi = coding::u2a(name.c_str()); + if (save_scanner_setting(ansi.c_str(), txt) == 0) + file_util::display_file_in_explorer(name.c_str()); +} + + diff --git a/pc/code_twain/sln/hgjson/hgjsonDlg.h b/pc/code_twain/sln/hgjson/hgjsonDlg.h new file mode 100644 index 0000000..a1599dc --- /dev/null +++ b/pc/code_twain/sln/hgjson/hgjsonDlg.h @@ -0,0 +1,190 @@ + +// hgjsonDlg.h : header file +// + +#pragma once +#include "afxshelltreectrl.h" +#include "afxwin.h" +#include "afxcmn.h" +#include +#include +#include + + +// ChgjsonDlg dialog +class ChgjsonDlg : public CDialogEx +{ +// Construction +public: + ChgjsonDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + enum { IDD = IDD_HGJSON_DIALOG }; + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + +public: + typedef struct _depend_item + { + std::wstring parent; + std::wstring logic_values; // include logic operator: "==2" + + bool operator==(const wchar_t* name) + { + return wcscmp(name, parent.c_str()) == 0; + } + bool operator<(const struct _depend_item& r) + { + return parent < r.parent; + } + }DEPENDITEM; + enum range_type + { + RANGE_TYPE_NONE = 0, + RANGE_TYPE_RANGE, + RANGE_TYPE_LIST, + }; + typedef struct _range + { + int type; + double lower; + double upper; + double step; + std::vector queue; + }RANGE; + typedef struct _hg_item + { + std::wstring title; + std::wstring desc; + std::wstring type; + std::wstring init_val; + std::wstring group; + int index; + int bytes; + bool advanced; + bool readonly; + //bool deviceonly; // ֻ豸ϲ - use readonly + bool visible; + int affect; + int position; + int field; + int unit; + bool depend_or; // or or and + std::vector depend; + RANGE range; + + bool operator==(const wchar_t* name) + { + return wcscmp(name, title.c_str()) == 0; + } + struct _hg_item(const wchar_t* ti= L"") + { + title = ti ? ti : L""; + desc = L""; + type = L"bool"; + init_val = L"true"; + group = L"base"; + bytes = 4; + advanced = readonly = /*deviceonly =*/ false; + visible = depend_or = true; + affect = position = field = unit = 0; + range.type = RANGE_TYPE_NONE; + } + }HGITEM; + typedef struct _def_h + { + std::wstring name; + std::wstring value; + std::wstring utf8_in_oct; + bool operator==(const std::wstring& n) + { + return name == n; + } + }DEFH; + std::vector hg_items_; + bool show_tree_tooltips_; + bool show_list_tooltips_; + +// Implementation +protected: + CMenu tree_menu_; + CMenu func_menu_; + CImageList tree_img_; + + // Generated message map functions + virtual BOOL OnInitDialog(); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + afx_msg void OnPaste(); + DECLARE_MESSAGE_MAP() + + static void to_define_header(std::vector& defs, const wchar_t* str, const wchar_t* parent = NULL); + static std::string save_define_header_2_file(std::vector& defs, const wchar_t* file); // return BOM string + + void init_control_statu(void); + void delete_tree_item(HTREEITEM root); + int find_config_item(const wchar_t* item_name); + int check_depend(const wchar_t* l, const wchar_t* r); // -1: l depends on r; 0: no depend; 1: r depends on l + void set_control_status(const HGITEM& item); + + void* create_json(int item, std::vector *def_h = NULL, std::wstring* name = NULL); + std::string to_json_text(bool for_const = false, std::wstring *dev = NULL); + void add_item(void* jsn_root, void* jsn_obj, HTREEITEM parent, bool old_ver); + bool load_from_json_text(const wchar_t* txt, std::wstring* err_msg = NULL); + bool load_from_file(const wchar_t* path_file); + void get_all_names(HTREEITEM root, std::vector& names, DWORD mask = 0); + void on_config_name_changed(const wchar_t* prev, const wchar_t* now); + HTREEITEM add_tree_item(const wchar_t* title, DWORD data, HTREEITEM parent = TVI_ROOT, HTREEITEM after = TVI_LAST); + void filter_tree_item(HTREEITEM item, const std::vector& filter); + +public: + afx_msg void OnTreeAddGroup(); + afx_msg void OnTreeAddItem(); + afx_msg void OnTreeDelItem(); + CTreeCtrl tree_; + afx_msg void OnTreeAddProduct(); + afx_msg void OnBnClickedButton3(); + afx_msg void OnBnClickedButton1(); + afx_msg void OnBnClickedButton2(); + CListBox depends_; + CListCtrl constraint_list_; + afx_msg void OnCbnSelchangeDataType(); + afx_msg void OnCbnSelchangeConstraintType(); + afx_msg void OnCbnSelchangeDependItem(); + afx_msg void OnCbnSelchangeLogic(); + afx_msg void OnLvnEndlabeleditListValues(NMHDR *pNMHDR, LRESULT *pResult); + CComboBox type_; + CComboBox constraint_; + afx_msg void OnBnClickedDepend(); + CComboBox logic_; + CComboBox depend_item_; + afx_msg void OnBnClickedButton4(); + afx_msg void OnNMRClickMfcshelltree1(NMHDR *pNMHDR, LRESULT *pResult); + CComboBox combo_default_; + afx_msg void OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnListmenuSetdefault(); + afx_msg void OnListmenuDelete(); + afx_msg void OnNMRClickListValues(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLbnDblclkList3(); + afx_msg void OnDropFiles(HDROP hDropInfo); + afx_msg void OnTreeRename(); + afx_msg void OnTreeLoadfile(); + afx_msg void OnLvnKeydownListValues(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnTvnKeydownTree1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnTvnGetInfoTipTree1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLvnGetInfoTipListValues(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnTreeTooltips(); + afx_msg void OnListmenuTooltips(); + afx_msg void OnTreeExportCharConstants(); + afx_msg void OnBnClickedToFile(); + afx_msg void OnTreeLoadClipboard(); + afx_msg void OnTreeUnifySequence(); + CComboBox field_; + CComboBox unit_; + CComboBox group_; + CComboBox affect_; +}; + + + diff --git a/pc/code_twain/sln/hgjson/res/bitmap1.bmp b/pc/code_twain/sln/hgjson/res/bitmap1.bmp new file mode 100644 index 0000000..792cd46 Binary files /dev/null and b/pc/code_twain/sln/hgjson/res/bitmap1.bmp differ diff --git a/pc/code_twain/sln/hgjson/res/hgjson.ico b/pc/code_twain/sln/hgjson/res/hgjson.ico new file mode 100644 index 0000000..d9c7466 Binary files /dev/null and b/pc/code_twain/sln/hgjson/res/hgjson.ico differ diff --git a/pc/code_twain/sln/hgjson/res/hgjson.rc2 b/pc/code_twain/sln/hgjson/res/hgjson.rc2 new file mode 100644 index 0000000..3fecfc5 Binary files /dev/null and b/pc/code_twain/sln/hgjson/res/hgjson.rc2 differ diff --git a/pc/code_twain/sln/hgjson/resource.h b/pc/code_twain/sln/hgjson/resource.h new file mode 100644 index 0000000..0342706 Binary files /dev/null and b/pc/code_twain/sln/hgjson/resource.h differ diff --git a/pc/code_twain/sln/hgjson/stdafx.cpp b/pc/code_twain/sln/hgjson/stdafx.cpp new file mode 100644 index 0000000..c77c320 --- /dev/null +++ b/pc/code_twain/sln/hgjson/stdafx.cpp @@ -0,0 +1,8 @@ + +// stdafx.cpp : source file that includes just the standard includes +// hgjson.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + diff --git a/pc/code_twain/sln/hgjson/stdafx.h b/pc/code_twain/sln/hgjson/stdafx.h new file mode 100644 index 0000000..3ace893 --- /dev/null +++ b/pc/code_twain/sln/hgjson/stdafx.h @@ -0,0 +1,54 @@ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#endif + +#include "targetver.h" + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +// turns off MFC's hiding of some common and often safely ignored warning messages +#define _AFX_ALL_WARNINGS + +#include // MFC core and standard components +#include // MFC extensions + + +#include // MFC Automation classes + + + +#ifndef _AFX_NO_OLE_SUPPORT +#include // MFC support for Internet Explorer 4 Common Controls +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include // MFC support for ribbons and control bars + + + + + + + + + +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif + + diff --git a/pc/code_twain/sln/hgjson/targetver.h b/pc/code_twain/sln/hgjson/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/pc/code_twain/sln/hgjson/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/pc/code_twain/sln/usb_tools/Debug/hgjson.exe b/pc/code_twain/sln/usb_tools/Debug/hgjson.exe new file mode 100644 index 0000000..357169a Binary files /dev/null and b/pc/code_twain/sln/usb_tools/Debug/hgjson.exe differ