diff --git a/ScreenCapture/Lang.cpp b/ScreenCapture/Lang.cpp index 4e6f284..c0afaeb 100644 --- a/ScreenCapture/Lang.cpp +++ b/ScreenCapture/Lang.cpp @@ -1,17 +1,20 @@ #include "pch.h" #include "Lang.h" #include "Setting.h" +#include "Util.h" std::unique_ptr lang; +std::map Lang::externalFiles; namespace { // 所有支持的语言(code + 自身语言名称);新增语言只需在此追加并补全对应字典 - const std::map supportedLangs = { + std::map supportedLangs = { { L"zh-CN", L"中文" }, { L"en-US", L"English" }, { L"id-ID", L"Bahasa Indonesia" }, { L"ru-RU", L"Русский" }, }; + } Lang::Lang() @@ -27,6 +30,7 @@ void Lang::init() if (!lang) { lang = std::make_unique(); } + scanLangDir(); lang->setLang(Setting::getLanguage()); } @@ -62,6 +66,62 @@ void Lang::setLang(const std::wstring& l) } lang->langCode = supported ? l : L"zh-CN"; lang->load(lang->langCode); + lang->loadExternal(lang->langCode); +} + +std::filesystem::path Lang::getLangDir() +{ + std::vector buf(MAX_PATH); + GetModuleFileName(nullptr, buf.data(), MAX_PATH); + return std::filesystem::path(buf.data()).parent_path() / L"lang"; +} + +void Lang::scanLangDir() +{ + auto langDir = getLangDir(); + if (!std::filesystem::exists(langDir)) return; + + for (auto& entry : std::filesystem::directory_iterator(langDir)) { + if (entry.path().extension() != L".json") continue; + + auto content = Util::readFile(entry.path().wstring()); + if (content.empty()) continue; + + try { + auto obj = JsonObject::Parse(content.data()); + if (!obj.HasKey(L"language") || !obj.HasKey(L"name")) continue; + auto code = std::wstring(obj.GetNamedString(L"language")); + auto name = std::wstring(obj.GetNamedString(L"name")); + if (code.empty() || name.empty()) continue; + + supportedLangs[code] = name; + externalFiles[code] = entry.path(); + } + catch (winrt::hresult_error const&) { + continue; + } + } +} + +void Lang::loadExternal(const std::wstring& l) +{ + auto it = externalFiles.find(l); + if (it == externalFiles.end()) return; + + auto content = Util::readFile(it->second.wstring()); + if (content.empty()) return; + + try { + auto obj = JsonObject::Parse(content.data()); + if (!obj.HasKey(L"translations")) return; + auto translations = obj.GetNamedObject(L"translations"); + for (const auto& [key, value] : translations) { + dic[std::wstring(key)] = std::wstring(value.GetString()); + } + } + catch (winrt::hresult_error const&) { + return; + } } void Lang::load(const std::wstring& l) diff --git a/ScreenCapture/Lang.h b/ScreenCapture/Lang.h index a85f212..8afe3c1 100644 --- a/ScreenCapture/Lang.h +++ b/ScreenCapture/Lang.h @@ -1,5 +1,7 @@ #pragma once +#include + /// /// 多语言管理(单例),与 Setting 同一套模式。 /// 字典直接硬编码在代码中(保持“单文件、零外部依赖”的定位)。 @@ -23,6 +25,10 @@ class Lang static const std::map& getLangs(); private: void load(const std::wstring& lang); + void loadExternal(const std::wstring& l); + static void scanLangDir(); + static std::filesystem::path getLangDir(); std::map dic; std::wstring langCode{ L"zh-CN" }; + static std::map externalFiles; }; diff --git a/ScreenCapture/lang/de-DE.json b/ScreenCapture/lang/de-DE.json new file mode 100644 index 0000000..71e35ff Binary files /dev/null and b/ScreenCapture/lang/de-DE.json differ