以下是 Windows SDK 10.0.19041.0 (2020-05-12) 中 winnt.h 的摘录,说明了该问题:
//
// ** DEPRECATED ** DEPRECATED ** DEPRECATED ** DEPRECATED ** DEPRECATED **
//
// DEPRECATED: The LCID/LANGID/SORTID concept is deprecated, please use
// Locale Names instead, eg: "en-US" instead of an LCID like 0x0409.
// See the documentation for GetLocaleInfoEx.
//
// A language ID is a 16 bit value which is the combination of a
// primary language ID and a secondary language ID. The bits are
// allocated as follows:
//
// +-----------------------+-------------------------+
// | Sublanguage ID | Primary Language ID |
// +-----------------------+-------------------------+
// 15 10 9 0 bit
//
// WARNING: This pattern is broken and not followed for all languages.
// Serbian, Bosnian & Croatian are a few examples.
//
// WARNING: There are > 6000 human languages. The PRIMARYLANGID construct
// cannot support all languages your application may encounter.
// Please use Language Names, such as "en".
//
// WARNING: There are > 200 country-regions. The SUBLANGID construct cannot
// represent all valid dialects of languages such as English.
// Please use Locale Names, such as "en-US".
//
// WARNING: Some languages may have more than one PRIMARYLANGID. Please
// use Locale Names, such as "en-FJ".
//
// WARNING: Some languages do not have assigned LANGIDs. Please use
// Locale Names, such as "tlh-Piqd".
//
// It is recommended that applications test for locale names rather than
// attempting to construct/deconstruct LANGID/PRIMARYLANGID/SUBLANGID
//
// Language ID creation/extraction macros:
//
// MAKELANGID - construct language id from a primary language id and
// a sublanguage id.
// PRIMARYLANGID - extract primary language id from a language id.
// SUBLANGID - extract sublanguage id from a language id.
//
// Note that the LANG, SUBLANG construction is not always consistent.
// The named locale APIs (eg GetLocaleInfoEx) are recommended.
//
// DEPRECATED: Language IDs do not exist for all locales
//
// ** DEPRECATED ** DEPRECATED ** DEPRECATED ** DEPRECATED ** DEPRECATED **
//
解决方案
这是我使用 std::string/wstring 的最小 C++ 示例。
但是它没有任何错误检查,如果找不到指定的错误,它只会返回一个空字符串。如果愿意,您可以实现自己的错误检查。
为什么要浪费时间编写大量代码,而很少有代码会欺骗?
附加信息(您可以跳过此)
我为 dwLanguageId 传递了 0,因为它是正确的方法,因为其他答案没有注意到 MAKELANGID 宏已被弃用, 不应使用,因为它不一致并且对于某些语言根本不起作用。
以下是 Windows SDK 10.0.19041.0 (2020-05-12) 中 winnt.h 的摘录,说明了该问题:
似乎这些信息还没有进入 MAKELANGID 的官方 MSDN 文档。
即使它确实工作正常,它也是一个更糟糕的选择,因为它试图在指定的 LangID 上找到错误字符串,并且只有一个 ID,如果它不存在则失败。改用 0 很可能至少会返回 something ,即使该错误未本地化为用户的语言。
引用 MSDN FormatMessageW :