我对WindowsForms使用Vista TaskDialog Wrapper and Emulator。
它工作得很好,但是我怎样才能改变按钮的语言?
发布于 2013-09-18 20:40:24
我有理由认为改变常用按钮的语言是不可能的。(普通按钮有特殊处理,也会返回特殊结果,请参考TASKDIALOGCONFIG structure。不提供更改语言的选项。)
因此,如果您谈论的是常用按钮Yes、No、OK、Cancel、Retry、Close的语言更改,那么它们标签上的文本就是从活动Windows UI语言的资源中获取的。这与MsgBox()对话框的按钮是相同的情况,从窗口开始就在那里。(按钮有Yes、No、OK、Cancel、Abort、Retry、Ignore、Help。)我相信在同一台机器上的所有基本对话框中,通用按钮的措辞不会改变,以保持一定程度的一致性。
并不是只有您的应用程序存在这个问题,大多数已经安装了不同语言的应用程序的用户都简单地接受了这个行为,并不认为它是一个bug。您可以随时解释这是使用Windows提供的模板制作的对话框的标准行为。您很清楚,标签的更改不是唯一的,而是TaskDialog的众多约束之一。
解决方法是创建自定义按钮,但同时您将失去创建链接的能力。如果您正在编写大型应用程序,请考虑为此类对话框编写自己基础,因为许多应用程序也已经实现了。
发布于 2018-08-31 02:32:56
来自未来的问候!
实际上你可以,正如我从阅读InitMUILanguage() vs MessageBox()中学到的那样,因为我也想改变语言。对我来说,InitMUILanguage不起作用(而且它使用了不鼓励的语言ID概念,请参阅winnt.h中LANG_NEUTRAL上面的“rant”)。但SetProcessPreferredUILanguages和SetThreadPreferredUILanguages都有。
下面是如何使用它(调整链接的示例):
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static TaskDialog.NativeMethods;
namespace TaskDialog
{
internal static class Program
{
[STAThread]
static void Main()
{
//Remove the check if you know your parameters are in the correct format
CheckResult(SetProcessPreferredUILanguages(MUI_LANGUAGE_NAME, MakeMultiString("ab-CD", "zh-cn"), out _));
//Or SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, MakeMultiString("ab-CD", "zh-cn"), out _);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
internal static class NativeMethods
{
public static void CheckResult(bool success)
{
if (!success)
{
var ex = new Win32Exception();
Debug.WriteLine($"Error 0x{ex.NativeErrorCode:X}");
throw ex;
}
}
//Generates a double null-terminated multi-string buffer (PCZZWSTR)
public static string MakeMultiString(params string[] items) => string.Join("\0", items) + "\0";
//WinNls.h
public const uint MUI_LANGUAGE_NAME = 0x8; // Use ISO language (culture) name convention
//Omitting CharSet sets it to Ansi which is not what we want
// Even after typing this I changed this to Ansi to test it again and forgot to change it back;
// took me quite some time to figure out what was going on
//https://docs.microsoft.com/windows/desktop/api/winnls/nf-winnls-setprocesspreferreduilanguages
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool SetProcessPreferredUILanguages(
uint dwFlags,
string pwszLanguagesBuffer,
out uint pulNumLanguages
);
//https://docs.microsoft.com/windows/desktop/api/winnls/nf-winnls-setthreadpreferreduilanguages#c#-signature
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool SetThreadPreferredUILanguages(
uint dwFlags,
string pwszLanguagesBuffer,
out uint pulNumLanguages
);
}
}pwszLanguagesBuffer接收一个区域设置列表,该列表由两个字母的ISO 639-1语言名称和一个由连字符分隔的两个字母的ISO 3166-1 alpha-2区域代码组成,按优先顺序递减。在本例中,ab-CD不是现有的语言环境,因此选择了zh-CN (中文的变体)。只考虑前5种有效语言。
请注意,pwszLanguagesBuffer列表中的每一项都必须以空字符(\0或\u0000)结尾。额外的+ '\0'是因为string.Join只在项目之间插入分隔符。然后用一个额外的空终止符结束这个列表,该结束符由.NET自动插入(因为它是一个字符串参数)。
结果是:

相关:How do I set the UI language for a multi-threaded .NET process, independent of the OS language?
https://stackoverflow.com/questions/17060447
复制相似问题