【问题标题】:Multi-byte character set in MFC applicationMFC 应用程序中的多字节字符集
【发布时间】:2008-11-27 20:45:09
【问题描述】:

我有一个 MFC 应用程序,我想在其中添加国际化支持。该项目配置为使用“多字节字符集”(在我的情况下,“unicode 字符集”不是一个选项)。

现在,如果我将键盘设置为某种外语,我希望 CWnd::OnChar() 函数会向我发送多字节字符,但它似乎并没有那样工作。 OnChar() 函数总是在其 nChar 变量中向我发送一个 1 字节字符。

我以为 _getmbcp() 函数会给我应用程序的当前代码页,但这个函数总是返回 0。

任何建议将不胜感激。

【问题讨论】:

  • 出于兴趣,马丁,为什么 Unicode 不是一个选项?政治还是技术?我曾经使用 UnicoWS 库让 Unicode 为 Win9x FWIW 工作。
  • 该工具依赖于许多其他甚至不支持 Unicode 的库。更新一切都是可能的,但时间很长。如果有使用多字节的解决方案,我会接受。
  • “多字节字符集”有点像“语言”。哪一个是“那个”?如果应用程序使用多字节字符集,则应用程序将使用运行时有效的任何代码页。 Unicode 避免了这个问题。

标签: c++ unicode mfc


【解决方案1】:

【讨论】:

  • 嗯,我希望更改本地键盘会自动更改我的应用程序中的代码页。我的假设是错误的吗?我们真的必须总是手动设置代码页吗?如果是这样,我们如何使代码页适合键盘布局?
  • 更改键盘布局会更改从键盘发送的值或值的含义(即哪些字符是哪些字符)。每个字节都是一个数值。应用程序根据应用程序的代码页解释值。
  • 好吧,这就是我害怕的。
  • 网站暂时不可用
【解决方案2】:

至于更改默认代码页:

用户的默认代码页(对于 WinXP - 不确定在 Vista 上如何)在“高级”选项卡上的“区域和语言选项”控制面板小程序中设置。

“非 Unicode 程序的语言”设置当前用户的默认代码页。不幸的是,它实际上并没有告诉你它正在配置的代码页号——它只是给出了语言(可能会用区域变体进一步指定)。从最终用户的角度来看,这很有意义,因为我认为代码页编号对 99.999% 的最终用户没有意义。您需要重新启动才能使更改生效。如果您使用 regmon 来确定哪些更改,您可能会想出一些更容易指定默认代码页的东西。

Microsoft 还有一个不受支持的实用程序 AppLocale,用于测试更改特定应用程序代码页的本地化:http://www.microsoft.com/globaldev/tools/apploc.mspx

您还可以通过调用 SetThreadLocale() 更改线程的代码页 - 但您还必须调用 C 运行时的 setlocale() 函数,因为某些 CRT 函数不与 Win API 语言环境函数对话(反之亦然)。有关详细信息,请参阅 Chris Grimes 的"Windows SetThreadLocale and CRT setlocale"

【讨论】:

    【解决方案3】:

    在非 Unicode 场景中,只有相应地设置了系统区域设置(在控制面板中也称为“非 Unicode 应用程序的语言”),您才能获得可靠的结果。如果没有,不要指望有什么好处。

    例如,如果系统区域设置为繁体中文,您将收到 2 个连续的 WM_CHAR 消息(每个字节一个,假设用户编写了一个 2 字符字符)。

    isleadbyte() 应该可以帮助您确定第二个字节是否即将到来。

    如果您的系统区域设置未设置为中文,即使使用中文键盘/IME,也不要期望收到正确的消息。误导部分是某些场景有效。例如使用希腊语键盘,您将收到基于希腊语代码页的 WM_CHAR 字符值,即使您的系统区域设置是基于拉丁语的。但是您真的应该远离尝试应对此类情况:不能保证成功,并且可能会因 Windows 版本和区域设置而异。

    正如 MikeB 所写,MS AppLocale 是您进行基本测试的好朋友。

    [ad] 和 appTranslator 是你的朋友,如果你需要翻译你的 UI [/ad]

    【讨论】:

      【解决方案4】:

      对于 _getmbcp,MSDN 说“返回值 0 表示正在使用单个字节代码页。”这肯定使它不是很有用。请尝试以下方法之一:GetUserDefaultLCID GetSystemDefaultLCID GetACP。 (现在为什么没有 GetACP 的“用户”等价物?)

      无论如何,如果您希望 _getmbcp 返回一个实际值,请将您的系统默认语言设置为中文、日文或韩文。

      【讨论】:

        【解决方案5】:

        实际上有一种非常简单(但很奇怪)的方法可以强制 OnChar 函数将 unicode 字符发送到应用程序,即使它配置为多字节字符集:

        SetWindowLongW( m_hWnd, GWL_WNDPROC, GetWindowLong( m_hWnd, GWL_WNDPROC ) );
        

        只需调用“SetWindowLong”的unicode版本,它就会强制应用程序接收unicode字符。

        【讨论】:

          猜你喜欢
          • 2019-06-26
          • 2021-07-25
          • 2014-11-05
          • 1970-01-01
          • 2019-10-04
          • 2010-10-17
          • 1970-01-01
          • 2023-04-04
          • 1970-01-01
          相关资源
          最近更新 更多