【问题标题】:Internationalization in MFCMFC 中的国际化
【发布时间】:2011-05-22 20:30:58
【问题描述】:

终于(经过多年的推迟)将我的应用本地化为英语以外的其他几种语言了。

第一个挑战是设计集成到我的 C++/MFC 应用程序中,该应用程序具有数十个对话框和无数字符串。我遇到了两种可能的替代实现:

  1. 将本地化的资源文件编译并部署为 DLL
  2. 提取所有字符串并将其替换为本地化版本。对于每个 语言会有一个 XML(或简单文本)文件。

我个人选择第二种选择,因为在我看来它更灵活。更改很多但并不难,而且非常重要的是,XML 文件对于翻译人员来说非常容易修改。

非常感谢任何建议。

问候,
Cosmin Unguru
http://www.batchphoto.com/

【问题讨论】:

    标签: c++ unicode mfc localization internationalization


    【解决方案1】:

    DLL 选项通常用于此目的,因为资源加载过程(例如 LoadLibrary)已经编写好 - 这意味着您不必编写任何解析/加载代码。虽然 XML 更易于编辑,但 DLL 具有更高的安全性(用户将无法轻松编辑它们),并将允许开发人员(即您)有更多时间处理应用程序逻辑,而不是编写语言加载系统。

    HMODULE hLangDLL = LoadLibrary("text_en.dll");
    // more stuff
    TCHAR mybuffer[1024] = {0};
    LoadString(hLangDLL, IDS_MYSTRING, mybuffer, 1023);
    

    【讨论】:

    • 虽然在这个实现中你必须实现每个字符串?
    • 无论哪种情况,您都必须翻译每个字符串。 XML 选项允许您快速编辑包含字符串的文件,但您必须将字符串加载到自定义数据结构中才能访问。 DLL 选项允许您使用内置的资源加载函数,因此唯一改变的是您为语言字符串加载的 DLL。每个 DLL 必须为翻译后的字符串分配相同的 ID - 因此在示例中,如果我更改为 text_de.dll,IDS_MYSTRING 将是该资源中任何内容的丹麦语翻译。
    • 酷,感谢您的澄清。我认为这是正确的方法,虽然也是最难的(更多代码);)
    • “意味着您不必编写任何解析/加载代码” - 您的意思是加载 XML 文件吗?这很容易做到,甚至不算数。
    • 你是说它是 DLL 方法的更多代码吗?如果是这样,那是不准确的。要通过 DLL 进行本地化(不包括您要创建的设置 GUI,以允许用户在运行时切换语言 - 这两种方法都是一致的),只需一行代码即可更改语言(LoadLibrary 调用) .使用 XML 方法,您必须创建自己的资源缓存来保存从 XML 加载的字符串。即使您使用支持 XPath 的第三方(例如 Xerces)XML 解析器,您仍然需要使用 100-200 行代码来加载和管理字符串。
    【解决方案2】:

    如果只是字符串发生变化,那么我同意 XML 是前进的方向,原因与您概述的确切原因相同。易于其他人编辑,易于在运行时更改语言等。

    您选择选项 1 的唯一原因(在我看来)是字符串以外的内容是否需要本地化,例如需要不同的图标。

    如果只是文本?我说使用 XML。

    【讨论】:

    • @Cosmin,那么我肯定会使用 XML。加载并放入某种地图很简单。
    【解决方案3】:

    在我们的案例中,每种语言都有不同的对话。资源文件与开发时实现的多个语言相同。您基本上可以在现有资源文件上附加不同的语言。我希望它有助于找到你的方式。

    【讨论】:

    • 这相当浪费,因为您正在加载从未使用过的语言。如果用户只想查看翻译 Y,则无需将翻译 X、Y 和 Z 加载到内存中。
    • 我知道,虽然架构不是我的 :)
    【解决方案4】:

    我用不同的语言做了一些长期存在的 MFC 项目。 我强烈推荐使用纯资源 DLL 的第一种方法。

    原因:

    (1) 如果用户执行 XCOPY 安装,他在主可执行文件中始终使用默认语言(英语)。

    (2) 如果您没有翻译所有内容(例如,您发布迟到或忘记了某些字符串),如果使用得当,Windows 资源函数会自动以默认语言返回资源 - 您不必自行实施。

    (3) 我个人的看法:(a) XML 文件中的换行符、制表符、空格对你来说是个痛点。 (b) 合并 XML 文件更糟糕...

    (4) 不要忘记编码。在 XML 中没问题,但您的翻译人员可能会使用不合适的编辑器并损坏文件。

    现在的主要原因是:

    (5) 您将不得不重新排列许多对话框,因为许多字符串在例如法语或德语比英语。并且让所有静态元素、按钮……更大“以防万一”看起来很糟糕。

    另一个提示:花一些钱购买一个翻译工具,它可以导入您的项目/二进制文件并建立翻译数据库。这将在第一次发布后摊销。

    另一个提示 (2):如果可能,发布不包含任何更改但仅包含多语言功能的版本。将来,如果可能的话:用英语发布你的产品。然后一步完成翻译(每种语言)并发布其他语言。

    【讨论】:

    • 您会推荐哪些 C++/MFC 翻译工具?
    • @Cosmin:抱歉,不能推荐任何东西,因为我后来将它们用于 Windows 窗体,而不是 MFC。对于 WinForms,我们使用 VisLoc (visloc.com/index.php?id=6&L=2)。我对此很满意,但在我离开公司后,他们改为 Catalyst (alchemysoftware.ie/index.html)。这些工具并不便宜,但物有所值(如果它们支持 MFC/您的应用程序)。
    【解决方案5】:

    使用 DLL 资源库是一个相对简单的操作,它不仅可以让您管理字符串,还可以管理其他资源。这是它的主要优势,因为 i18n is not only about string translation

    但是,根据您的需要,基于文本的解决方案可能是一个更好的决定,因为它更易于处理 - 资源脚本比 xml 文件更复杂,尤其是对于普通翻译人员而言。

    我建议创建自己的抽象层,例如“LoadLocalizedString”等;通过这种方式,您可以开始仅使用文本文件来实现它,然后在需要时以透明的方式更改为更复杂的东西 - 使您的软件具有 i18n 意识的所有努力仍然有效。

    【讨论】:

      【解决方案6】:

      我从本地化工作很多的人那里得到的友好的建议:

      1. 获取 GNU Gettext,
      2. 将所有字符串标记为 _("English")。
      3. 使用gettext工具xgettext提取所有字符串并编译字典
      4. 使用 poedit 等出色工具翻译字符串。
      5. 在您的项目中使用 gettext,让您的本地化生活更简单!

      您也可以将boost::locale 用于相同目的 - 它使用 GNU Gettext 字典和方法,但提供了不同且更强大的运行时,并且对于 Windows 开发人员,它具有非常好的插件 - 它支持 MFC 需要用于普通 Unicode 的宽字符串支持。

      不要使用从语言角度(以及开发人员角度)完全是垃圾的资源和其他“翻译”工具。

      延伸阅读:http://cppcms.sourceforge.net/boost_locale/html/tutorial.html

      【讨论】:

      • 我没有投反对票,但我可以猜到。 GNU Gettext 有一个有问题的属性:许可证。是 GPL。不是 L-GPL,而是 GPL(至少在 Windows 上)。这仅仅意味着您还必须使用兼容的许可证发布您的应用程序(换句话说,将其开源)。
      • @Paweł Dyda 阅读了许可证,工具是 GPL 但运行时本身是 LGPL,boost::locale 也使用不需要与 GNU 代码链接的 gettext 字典。所以你没有任何问题。
      猜你喜欢
      • 1970-01-01
      • 2010-10-30
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多