我对WindowsForms使用Vista TaskDialog Wrapper and Emulator。
它工作正常,但我怎样才能更改按钮的语言?
答案 0 :(得分:1)
我有理由认为改变普通按钮的语言是不可能的。 (常用按钮以特殊方式处理并返回特殊结果,请参阅TASKDIALOGCONFIG structure。没有为语言更改提供选项。)
因此,如果您正在谈论常见按钮Yes
,No
,OK
,Cancel
,Retry
,Close
的语言更改,然后标签上的文本取自活动Windows UI语言的资源。这与从Windows开头就有MsgBox()
对话框的按钮的情况相同。 (按钮为Yes
,No
,OK
,Cancel
,Abort
,Retry
,Ignore
,Help
。)我认为普通按钮上的措辞不能改变,以保持同一台机器上所有基本对话框的一致性。
您的应用程序并不是唯一的问题,并且已经使用不同语言安装应用程序的大多数用户只是接受此行为,并且不会将其视为错误。您始终可以解释这是使用Windows提供的模板制作的对话框的标准行为。您非常清楚标签 的更改不是唯一的,而是 TaskDialog 的许多 约束之一。
解决方法是创建自定义按钮,尽管如此,您仍然无法创建链接。如果您正在编写大型应用程序,请考虑为此类对话框编写自己的基础,因为许多应用程序也已实现。
答案 1 :(得分:0)
未来的问候!
实际上,正如我从阅读InitMUILanguage() vs MessageBox()中学到的,您可以,因为我也想更改语言。对我来说,InitMUILanguage
不起作用(它使用了不鼓励使用的语言ID概念,请参见LANG_NEUTRAL
中winnt.h
上方的'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
列表中的每个项目都必须以NULL字符(\0
或\u0000
)结尾。额外的+ '\0'
是因为string.Join
仅在项目之间插入分隔符。然后,使用额外的NULL终止符关闭此列表,该终止符由.NET自动插入(因为它是字符串参数)。
相关:How do I set the UI language for a multi-threaded .NET process, independent of the OS language?