TaskDialog更改按钮语言

时间:2013-06-12 07:59:38

标签: winforms comctl32 taskdialog

我对WindowsForms使用Vista TaskDialog Wrapper and Emulator

它工作正常,但我怎样才能更改按钮的语言?

2 个答案:

答案 0 :(得分:1)

我有理由认为改变普通按钮的语言是不可能的。 (常用按钮以特殊方式处理并返回特殊结果,请参阅TASKDIALOGCONFIG structure。没有为语言更改提供选项。)

因此,如果您正在谈论常见按钮YesNoOKCancelRetryClose的语言更改,然后标签上的文本取自活动Windows UI语言的资源。这与从Windows开头就有MsgBox()对话框的按钮的情况相同。 (按钮为YesNoOKCancelAbortRetryIgnoreHelp 。)我认为普通按钮上的措辞不能改变,以保持同一台机器上所有基本对话框的一致性。

您的应用程序并不是唯一的问题,并且已经使用不同语言安装应用程序的大多数用户只是接受此行为,并且不会将其视为错误。您始终可以解释这是使用Windows提供的模板制作的对话框的标准行为。您非常清楚标签 的更改不是唯一的,而是 TaskDialog 的许多 约束之一。

解决方法是创建自定义按钮,尽管如此,您仍然无法创建链接。如果您正在编写大型应用程序,请考虑为此类对话框编写自己的基础,因为许多应用程序也已实现。

答案 1 :(得分:0)

未来的问候!

实际上,正如我从阅读InitMUILanguage() vs MessageBox()中学到的,您可以,因为我也想更改语言。对我来说,InitMUILanguage不起作用(它使用了不鼓励使用的语言ID概念,请参见LANG_NEUTRALwinnt.h上方的'rant')。但是SetProcessPreferredUILanguagesSetThreadPreferredUILanguages都可以。

这里是使用方法(调整您链接的示例):

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自动插入(因为它是字符串参数)。

结果:
Chinese buttons

相关:How do I set the UI language for a multi-threaded .NET process, independent of the OS language?