当前位置: 首页 > news >正文

grepWin 多语言支持原理拆解:28 种语言是怎么做到的

grepWin 多语言支持原理拆解:28 种语言是怎么做到的

【免费下载链接】grepWinA powerful and fast search tool using regular expressions项目地址: https://gitcode.com/gh_mirrors/gr/grepWin

grepWin 是一款用正则表达式做全文搜索的桌面工具,它的国际化做得相当扎实:内置 28 种语言,启动时界面自动跟随你的习惯语言显示,随时可以在设置里切换。本文以"用户操作 → 系统行为"的方式,拆解 grepWin 国际化的实现思路,顺带看看新增一种语言要动几个文件。

为什么打开 grepWin,界面就是你的语言?

你会注意到一个细节:很多小工具装完打开就是英文,而 grepWin 如果你系统语言是中文,它第一次启动大概率已经是中文界面了。

这个效果并不神秘。启动流程里有一句关键代码(位于src/grepWin.cpp):

CLanguage::Instance().LoadFile(bPortable ? g_iniFile.GetValue(L"global", L"languagefile", L"") : std::wstring(CRegStdString(L"Software\\grepWin\\languagefile")));

翻译一下:程序启动时读取"你上次选择的语言文件路径"(便携版从 ini 读,安装版从注册表读),交给CLanguage这个单例类加载。之后界面上所有文本都从这份语言文件里查表显示。语言文件全部集中在项目根目录的translations/文件夹下,一个.lang文件对应一种语言,共 28 个,从Chinese Simplified.langVietnamese.lang一应俱全。

一次语言切换,系统里发生了什么?

换个角度,从"你在设置里换了个语言"这个动作开始跟踪。整个链路只有四步:

步骤发生了什么位置
1用户在设置对话框选定语言,点确定src/Settings.cpp
2调用LoadFile(langPath)重新加载语言文件src/Settings.cpp
3调用TranslateWindow把主窗口所有控件文本重刷一遍同上
4新语言路径被记住,下次启动直接生效注册表 / 便携版 ini

注意第 3 步:不是重启程序,而是把已经创建好的控件文字逐一替换掉。这就是为什么 grepWin 换语言是"秒切"的——窗口结构没变,变的是文本内容。

CLanguage 单例到底做了什么

🔧 所有翻译动作最终都收敛到CLanguage这一个类上,它对外暴露的能力可以按"界面元素 → 接口"来记:

  • 整窗翻译TranslateWindow。对话框初始化时调一次(如CLanguage::Instance().TranslateWindow(*this);),窗口里所有静态文本、按钮、标签批量换文。关于对话框、书签对话框等十几个窗口都是这么干的。
  • 菜单翻译TranslateMenu。右键菜单是运行时动态插入的项,没法走控件翻译,所以单独提供菜单接口,传入菜单句柄即可整体换文。
  • 单条字符串TranslatedString(hResource, IDS_XXX)。用于工具提示、动态拼接的提示语这类"散落在代码里"的文本,查表返回译文,例如给按钮挂 tooltip 时:
AddToolTip(IDC_PATTERN, TranslatedString(hResource, IDS_PATTERN_TT).c_str());

三个接口的粒度正好覆盖了三种 UI 载体:控件、菜单、字符串,用哪个查表都由CLanguage内部那份"原文 → 译文"映射决定。

新增一种语言只需三步

语言文件的格式很简单,本质是msgid(英文原文)+msgstr(译文)的键值对,以translations/English.lang为例:

msgid "&About grepWin..." msgstr ""

给 grepWin 加一门新语言的流程:

  1. 复制模板:把translations/English.lang复制一份,命名为新语言名,如Nepali.lang
  2. 只改译文:文件头部注释写得很清楚——ONLY change the msgstr field,只翻译msgstr后面的内容,msgid原样保留;
  3. 生效验证:在设置里选中新语言,LoadFile会自动加载它,检查界面、菜单、工具提示是否全部替换。

整个过程中没有改任何一行 C++ 代码,翻译资源和程序逻辑是完全解耦的。

小结

  • 28 份.lang文件集中在translations/目录,程序与文本互不依赖,加语言零代码改动;
  • CLanguage单例提供LoadFileTranslateWindowTranslateMenuTranslatedString四个入口,分别负责加载、整窗、菜单和单条文本;
  • 语言选择在设置里即时生效,无需重启,启动时则自动恢复上次的选择。

【免费下载链接】grepWinA powerful and fast search tool using regular expressions项目地址: https://gitcode.com/gh_mirrors/gr/grepWin

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.cnnetsun.cn/news/4143562.html

相关文章:

  • 3D打印磁吸模块化移动电源:基于32140电池的DIY设计与实现
  • 第一次见这么漂亮的出入库登记表!被领导夸了无数次
  • hactool 完整指南:快速解析、解密并提取 Switch 游戏文件
  • OpenClaw AI代理框架从零部署指南:解决Node.js版本与LLM配置难题
  • 5分钟搭好WebDAV文件服务器:一份完整的入门到生产指南
  • 秋招实战指南:从准备到offer选择的完整复盘
  • 常见电路设计——(1)超级电容充电电路
  • AI研究智能体安全:深度解析FORGE轨迹劫持攻击与四层防御体系
  • 如何快速上手 FakeLocation:安卓应用级虚拟定位完整指南
  • 华为S系列园区交换机维护宝典:设备环境检查
  • 智能体对抗范式下 Phishing3.0 威胁演化与企业防御体系研究
  • 抗钓鱼多因素认证机理与企业无扰动部署策略研究
  • 投保前患病,保单生效或复效180天后确诊,保险公司能以非初次拒赔吗
  • 探索min函数的强大功能
  • 怎样做好GEO推广?让AI主动推荐你品牌的5个核心策略
  • 基于声明式策略实现Git推送动态权限控制:从SQL-Like规则到执行引擎
  • 构建高可用机场服务系统:Spring Cloud微服务架构与韧性设计实践
  • MusicPlayer2 四问实测:免费开源本地音乐播放器值不值得用
  • HubPort 和 SCADA / MES 是什么关系?是替代还是增强
  • 水电表采集协议不统一?HubPort 如何实现一平台多协议接入
  • 树莓派没有公网 IP,用 webrpc 做 24 小时在线节点
  • Yi.Abp.Admin 完整指南:.NET 8 + ABP 框架管理后台快速上手
  • NVIDIA显卡驱动安全回退指南:彻底卸载与纯净安装
  • 049、表维护生成器
  • 048、锁对象与锁机制
  • Windows系统文件umpoext.dll丢失找不到问题解决
  • Python如何实现蚁群算法
  • nginx-rtmp-module:从编译到推流成功,一篇就够
  • 基于RFC协议与Qt框架的跨平台C++客户端开发实践
  • ComfyUI高级工作流构建:从LoRA集成到ControlNet与双采样放大实战