// CDlgLang.cpp: 实现文件 // #include "stdafx.h" #include "hgjson.h" #include "afxdialogex.h" #include "CDlgLang.h" #include "DlgInput.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); } 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<(struct _lang_id& r) { return id < r.id; } }LANGIDW; 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 = 936) { 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 }; if (file_util::browser_file(owner, &file, L"Language pack(*.pak)\0\0", false)) { file_util::save_2_file(cont.c_str(), cont.length(), file.path); } return 0; } 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 = NULL) { 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; } } // 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) 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"纯文本翻译对照,请以中文(简体)语言在第一列(如有空格请加英文双引号),其它语言为空格以后的第二列。", L"提示", 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()); } } 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; } sdk_util::save_2_lang_pak(m_hWnd, items, cp); } 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); } }