设计字符串本地化的最佳方法

2022-01-11 00:00:00 windows localization c++ mfc

这是一个笼统的问题,欢迎发表意见.我一直在尝试想出一种好方法来设计用于 Windows MFC 应用程序和相关实用程序的字符串资源本地化.我的愿望清单是:

This is kinda a general question, open for opinions. I've been trying to come up with a good way to design for localization of string resources for a Windows MFC application and related utilities. My wishlist is:

  • 必须在代码中保留字符串字面量(而不是用宏 #define 资源 ID 替换),以便消息仍然可以内联读取
  • 必须允许本地化字符串资源 (duh)
  • 不得施加额外的运行时环境限制(例如:对 .NET 的依赖等)
  • 应尽量减少对现有代码的干扰(修改越少越好)
  • 应该是可调试的
  • 应生成可用常用工具编辑的资源文件(即:常用格式)
  • 不应使用复制/粘贴注释块来保留代码中的文字字符串或任何其他可能导致去同步的内容
  • 允许静态(编译时)检查每个注释"字符串是否在资源文件中会很好
  • 允许跨语言资源字符串池会很好(适用于各种语言的组件,例如:本机 C++ 和 .NET)

除了静态检查之外,我有一种方法可以在某种程度上满足我的所有愿望,但我不得不开发一些自定义代码来实现它(并且它有局限性).我想知道是否有人以特别好的方式解决了这个问题.

I have a way which fulfills all my wishlist to some extent except for static checking, but I have had to develop a bit of custom code to achieve it (and it has limitations). I'm wondering if anyone has solved this problem in a particularly good way.

我目前的解决方案是这样的:

The solution I currently have looks like this:

ShowMessage( RESTRING( _T("Some string") ) );
ShowMessage( RESTRING( _T("Some string with variable %1"), sNonTranslatedStringVariable ) );

然后我有一个自定义实用程序来解析RESTRING"块中的字符串并将它们放入一个 .resx 文件中以进行本地化,并使用一个单独的 C# COM 对象从本地化资源文件中加载它们并返回.如果 C# 对象不可用(或无法加载),我会回退到代码中的字符串.该宏扩展为一个模板类,该类调用 COM 对象并进行格式化等.

I then have a custom utility to parse out the strings from within the 'RESTRING' blocks and put them into a .resx file for localization, and a separate C# COM object to load them from localized resource files with fallback. If the C# object is not available (or cannot load), I fallback to the string in the code. The macro expands to a template class which calls the COM object and does the formatting, etc.

无论如何,我认为添加我现在的参考资料会很有用.

Anyway, I thought it would be useful to add what I have now for reference.

推荐答案

我们使用英文字符串作为ID.

We use the English string as the ID.

如果从国际资源对象(从安装的 I18N dll 加载)查找失败,那么我们默认使用 ID 字符串.

If it fails the look up from the international resource object (loaded from the I18N dll installed) then we default to the ID string.

代码如下:

doAction(I18N.get("Press OK to continue"));

作为构建过程的一部分,我们有一个 perl 脚本来解析所有源代码中的字符串常量.它构建应用程序中所有字符串的临时文件,然后将它们与每个本地的资源字符串进行比较,以查看它们是否存在.任何缺失的字符串都会向相应的翻译团队发送电子邮件.

As part of the build processes we have a perl script that parses all source for string constants. It builds a temp file of all strings in the application and then compares these against the resource strings in each local to see if they exists. Any missing strings generates an e-mail to the appropriate translation team.

我们可以为每个本地设置多个 dll.dll 的名称基于 RFC 3066
语言[_territory][.codeset][@modifier]

We can have multiple dll for each local. The name of the dll is based on RFC 3066
language[_territory][.codeset][@modifier]

我们尝试从机器中提取语言环境,并在加载 I18N dll 时尽可能具体,但如果不存在更具体的版本,则回退到不太具体的本地变体.

We try and extract the locale from the machine and be as specific as possible when loading the I18N dll but fallback to less specific local variations if the more specific version is not present.

例子:

在英国:如果本地是 en_GB.UTF-8
(我在特定的 Windows 意义上松散地使用术语 dll).

In the UK: If the local was en_GB.UTF-8
(I use the term dll loosely not in the specific windows sense).

首先查找 I18N.en_GB.UTF-8 dll.如果此 dll 不存在,则回退到 I18N.en_GB.如果此 dll 不存在则回退到 I18N.en 如果此 dll 不存在则回退到 I18N.default

First look for the I18N.en_GB.UTF-8 dll. If this dll does not exist fall back to I18N.en_GB. If this dll does not exist fall back to I18N.en If this dll does not exist fall beck to I18N.default

此规则的唯一例外是:简体中文 (zh_CN),其中备用是美国英语 (en_US).如果机器不支持简体中文,则不太可能支持全中文.

The only exception to this rule is: Simplified Chinese (zh_CN) where the fallback is US English (en_US). If the machine does not support simplified Chinese then it is unlikely to support full Chinese.

相关文章