grepWin 多语言支持的完整解析:国际化与本地化实现原理
【免费下载链接】grepWinA powerful and fast search tool using regular expressions项目地址: https://gitcode.com/gh_mirrors/gr/grepWin
grepWin 是一款基于正则表达式的快速搜索工具,内置完整的国际化与本地化能力,支持 28 种语言。本文带你跟一个字符串走完全程:语言文件如何组织、启动时如何加载、如何落到窗口、菜单和工具提示上,最后用三步给项目加一门新语言。
- 所有语言资源集中在
translations/目录,每个语言一个.lang文件 CLanguage单例负责加载,LoadFile是唯一的加载入口- 翻译分三种粒度:单字符串、整窗口批量、菜单
- 设置里切换语言即时生效,无需重启应用
语言文件怎么组织:一份"原文-译文"对照表
打开 translations/ 语言文件目录,你会看到 28 个.lang文件。每个文件的结构都是msgid(英文原文)配一行msgstr(译文),就像一本对照字典。以简体中文为例:
#. Resource IDs: (149) msgid "%ld more matches" msgstr "还有 %ld 个匹配"语言清单按地区大致可以这样分组:
| 分组 | 语言文件 |
|---|---|
| 中文 | Chinese Simplified.lang、Chinese Traditional.lang |
| 亚洲 | Japanese.lang、Korean.lang、Vietnamese.lang、Indonesian.lang、Hindi.lang、Tamil.lang |
| 欧洲 | German.lang、French.lang、Russian.lang、Dutch.lang、Finnish.lang、Greek.lang、Hungarian.lang、Italian.lang、Polish.lang、Slovak.lang、Swedish.lang、Turkish.lang、Belarusian.lang |
| 美洲与其他 | Spanish.lang、Spanish Mexican.lang、Portuguese.lang、Portuguese Brazilian.lang、English.lang、English British.lang、Afrikaans.lang |
新增一种语言,只需要在目录里多放一个这样的文件,代码侧不需要任何改动。
启动那一刻:LoadFile 加载链路
程序启动时,CLanguage单例会去读"用户上次选的是哪个语言文件"。这里有个小细节:grepWin 同时支持便携版(配置存 ini)和安装版(配置存注册表),两处的键名都叫languagefile:
// src/grepWin.cpp 启动时确定语言文件 CLanguage::Instance().LoadFile(bPortable ? g_iniFile.GetValue(L"global", L"languagefile", L"") : std::wstring(CRegStdString(L"Software\\grepWin\\languagefile")));白话讲:先从配置里拿到语言文件路径,再把它整本"字典"读进内存。之后所有翻译查询都走内存,不会反复读盘。
在 src/Settings.cpp 语言切换逻辑 中,你在设置对话框选中新语言并点确定后,走的是同一条链路:先LoadFile换成新字典,再对主窗口做一遍批量翻译——这就是"运行时切换语言、无需重启"的来源:
CLanguage::Instance().LoadFile(langPath); CLanguage::Instance().TranslateWindow(::GetParent(*this));三种翻译粒度:单串、整窗、菜单
grepWin 把翻译接口拆成了三档,按"覆盖面积"从小到大排:
TranslatedString:翻译单条字符串,最基础的翻译单元。菜单项、按钮文本这类逐个插入的地方都用它TranslateWindow:遍历窗口内所有控件,按控件 ID 自动匹配译文。对话框写完就调一次,省事TranslateMenu:针对弹出菜单的批量翻译,书签对话框里就有使用
单串翻译的典型现场是右键菜单,见 src/ShellContextMenu.cpp 右键菜单翻译:
// 逐项插入菜单,每项单独翻译 ::InsertMenu(m_menu, 1, MF_BYPOSITION | MF_STRING, 1, TranslatedString(g_hInst, IDS_OPENCONTAININGFOLDER).c_str());整窗批量则简单得多,各对话框初始化时一行搞定:
// 对话框初始化时翻译所有控件 CLanguage::Instance().TranslateWindow(*this);界面现场:主界面、菜单与工具提示
三种粒度组合起来,就覆盖了用户能看到的所有文字:
- 主搜索界面:标签、按钮、提示区全部由
TranslateWindow批量处理,换成日文或韩文后整体自动切换 - 右键菜单:"打开所在文件夹""复制路径"等项逐个走
TranslatedString - 设置对话框:静态文本之外,连动态生成的说明和工具提示也做了本地化,比如深色模式提示
IDS_DARKMODE_TT、备份目录提示IDS_BACKUPINFOLDER_TT
工具提示这类"看不太显眼"的文本同样走了翻译接口,本地化做得比较彻底。
📝 给项目加一门新语言:三步走
整个流程不需要碰任何 C++ 源码:
- 复制模板:把
translations/English.lang复制一份,改名为目标语言(如Thai.lang) - 翻译内容:保持每个
msgid原样不动,只填写对应的msgstr;文件头注释也提醒了"ONLY change the msgstr field" - 验证效果:重新构建后在设置的 Language 下拉框中选择新语言,检查主界面、菜单、工具提示是否全部生效
由于设置对话框是扫描目录动态生成语言列表的,新文件放对位置就会自动出现在选项里。
收束
这套架构的好处可以浓缩成三点:语言资源与业务逻辑彻底分离,译者可以独立维护;加载与翻译走内存,运行时随时切换;新增语言零改核心代码。对任何想做好本地化的桌面应用来说,grepWin 的多语言支持实现原理都是一个值得参考的开源软件国际化架构范例。
【免费下载链接】grepWinA powerful and fast search tool using regular expressions项目地址: https://gitcode.com/gh_mirrors/gr/grepWin
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考