首页 > 解决方案 > Building application with different language specified in resource.rc

问题描述

I never done something like this, so this is my first attempt. From reading online different information and tutorials, I can confidently say that I got very confused so I went on my own with this.

What I am trying to achieve is have different build configurations with different languages for the GUI.

My application is Win32 built using Visual Studio 2019.

Steps I tried:

However the result is nothing. The menu and dialogs are still in English.

Is there something else I must do to specify which set of resources to use to obtain a different language build ?

Or am I over complicating this and going all wrong...

Any advice/examples are much appreciated.

标签: c++winapivisual-c++

解决方案


看来我会回答我自己的问题,因为我相信其他人也遇到了这个问题。

更改 Windows GUI 应用程序语言的正确官方方法是:

SetThreadUILanguage

使用此功能,以及我在问题中所做的确切事情;该函数将在运行时应用该语言的资源。(菜单,对话框,一切)

我的情况很简单:

SetThreadUILanguage(MAKELANGID(LANG_VIETNAMESE, SUBLANG_VIETNAMESE_VIETNAM));

但是在我的情况下,我正在为每种语言创建构建,所以如果您想允许用户在运行时更改语言,请参阅注释和这篇文章

这样做的非官方方式需要更多的工作,但非常稳定且不易出错。

  • 您必须用该语言翻译和重建您的菜单
  • 您必须翻译和重命名每种语言的每个对话 ID,并显示每种语言的对话 ID

对于社区和其他开发人员,我将分享重建菜单的代码:

// Find our Menu resource based on desired language
HRSRC hRes = FindResourceExW(hInstance, RT_MENU, MAKEINTRESOURCE(IDC_APPLICATION), MAKELANGID(LANG_VIETNAMESE, SUBLANG_VIETNAMESE_VIETNAM));

if (!hRes) {
    wchar_t buf[MAX_PATH] = { 0 };
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(wchar_t)), NULL);
    MessageBoxW(0, buf, _TEXT(L"FindResourceExW Error"), MB_OK | MB_ICONERROR);
    return FALSE;
}

// Load our Menu resource based on desired language
HGLOBAL hGlo = LoadResource(hInstance, hRes);

if (!hGlo) {
    wchar_t buf[MAX_PATH] = { 0 };
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(wchar_t)), NULL);
    MessageBoxW(0, buf, _TEXT(L"LoadResource Error"), MB_OK | MB_ICONERROR);
    return FALSE;
}

// Lock the resource
LPVOID pData = LockResource(hGlo);

if (pData == NULL) {
    wchar_t buf[MAX_PATH] = { 0 };
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(wchar_t)), NULL);
    MessageBoxW(0, buf, _TEXT(L"LockResource Error"), MB_OK | MB_ICONERROR);
    return FALSE;
}

// Load the new Menu into memory
HMENU hMenu = LoadMenuIndirectW((MENUTEMPLATE*)pData);

if (!hMenu) {
    wchar_t buf[MAX_PATH] = { 0 };
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(wchar_t)), NULL);
    MessageBoxW(0, buf, _TEXT(L"LoadMenuIndirectW Error"), MB_OK | MB_ICONERROR);
    return FALSE;
}

// Get our default Menu
HMENU hMenu_old = GetMenu(g_Hwnd);

// Set no Menu
SetMenu(g_Hwnd, NULL);

// Erase default Menu
DestroyMenu(hMenu_old);

// Set our new Menu
SetMenu(g_Hwnd, hMenu);

// Draw our new Menu
DrawMenuBar(g_Hwnd);

注意:如果您想使用FindResourceEx搜索字符串,由于RT_STRING会更复杂,因此请在浪费时间之前先查看此内容。

享受!


推荐阅读