Nano Hash - криптовалюты, майнинг, программирование

Изменить язык встроенного диалогового окна «Выбрать значок»?

В приложении (с открытым исходным кодом) на снимке экрана ниже я вызываю PickIconDlg для отображения диалогового окна для просмотра и выбора значка:

Я просто хотел бы знать, существует ли возможность изменить язык, на котором отображается это диалоговое окно для текущего запущенного процесса.

Я проверил, что SetProcessPreferredUILanguages ​​ работает нормально для изменения языка общих диалоговых окон файлов и папок, но не влияет на диалоговое окно «Выбрать значок».

05.06.2019

  • Почему бы не создать свой собственный диалог, загрузить свои собственные логотипы, использовать предпочитаемый вами язык? 06.06.2019
  • @Aousaf rashid Спасибо за комментарий. Причина проста: если Windows уже реализована и предоставляет способ показать диалоговое окно, чтобы конечный пользователь мог видеть и выбирать значки, содержащиеся в файле ресурсов, почему бы не использовать его ?. Я не хочу изобретать велосипед. Кроме того, если вы поищете в Интернете, вы заметите, что существующие алгоритмы / библиотеки с открытым исходным кодом для .NET для управления значками в файле ресурсов (таким образом) очень утомительны и несовершенны (с ошибками). Я думаю, что гораздо более целесообразно позволить Windows сделать это с помощью простого вызова функции PickIconDlg. 06.06.2019
  • Вы можете изменить язык потока, см. Это сообщение stackoverflow.com/questions/14426609/ 06.06.2019
  • @nbk Спасибо за комментарий, но я знал о свойствах CurrentCulture и CurrentUICulture. Это не влияет на язык диалогового окна «Выбрать значок». 06.06.2019
  • string newText = "New Caption"; SendMessage([Handle], WM_SETTEXT, 0, newText);. Единственная проблема в том, что все эти окна имеют #32770 имя класса. Вы можете поймать его, когда он открывается с помощью UI Automation с AutomationEventHandler, установите значение WindowPattern.WindowOpenedEvent. 06.06.2019
  • Или, поскольку вы можете решить, какой путь показан в элементе управления Edit, перехватите событие WindowOpened, а затем проверьте первый Edit дочерний элемент в поддереве, текст которого совпадает с только что установленным путем. Метод AutomationElement.FindFirst может использоваться для этого, 06.06.2019
  • @Jimi еще раз спасибо, но вы предлагаете мне перечислить окна с функциями, связанными с Win32, или использовать автоматизацию пользовательского интерфейса вместо этого, чтобы найти диалоговое окно, а затем отправить WM_SETTEXT на каждую метку / элемент управления в диалоговом окне, чтобы заменить его текст на пользовательский (английский ) текст. Такое решение мне действительно не помогает, просто попытаться улучшить небольшое визуальное несовершенство приложения (язык диалогов) - это слишком много усилий. 06.06.2019
  • Это самое простое, что пришло в голову. С UI Automation вы можете сделать это легко (достаточно). В противном случае вам придется подключить его или создать его . Я не знаю другого способа изменить системный язык по умолчанию. Это не управляемый класс .Net. 06.06.2019

Ответы:


1

Я могу изменить язык диалогового окна «Выбрать значок» с помощью простого кода ниже:

#include <windows.h>
#include <Shlobj.h>
#pragma comment(lib, "Shell32.lib")
int main(void)
{
    ULONG n;
    WCHAR s[] = L"C:\\Windows\\Explorer.exe"; 
    int i = 1;
    n = 1;
    WCHAR langs[] = L"zh-CN\0";
    BOOL ret = SetProcessPreferredUILanguages(MUI_LANGUAGE_NAME, langs, &n);
    PickIconDlg(NULL,s, wcslen(s)+1,&i);
}

Результат: (Обратите внимание, что язык по умолчанию в Моей среде - "en-US") введите описание изображения здесь

Похоже, вам сначала нужно установить языковой пакет. Настройки> Время и язык> Язык> Добавить предпочтительный язык, затем выберите язык, который вы добавили, и перейдите в Параметры, установите языковой пакет.

Версия C #:

public enum MUIFlags : uint
{
    MUI_LANGUAGE_ID = 0x4,
    MUI_LANGUAGE_NAME = 0x8,
}

[SuppressUnmanagedCodeSecurity, SecurityCritical]
internal static class NativeMethods
{
    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    internal static extern bool SetProcessPreferredUILanguages(MUIFlags dwFlags, 
        string pwszLanguagesBuffer, ref uint pulNumLanguages);

    [DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    internal static extern int PickIconDlg(IntPtr hwnd, string pszIconPath, 
        uint cchIconPath, ref int piIconIndex);
}

Языки могут быть заданы как массив имен ISO:
(Первый язык, доступный в Системе в указанном порядке, будет использоваться как язык диалога).

string[] languages = new[] { "de-DE", "en-US", "it-IT", "es-ES", "fr-FR" };

Или используя Thread.CurrentThread.CurrentCulture (или CurrentUICulture):

string[] languages = new[] { Thread.CurrentThread.CurrentUICulture.Name };

Или используя определенную культуру (используя CultureInfo.CreateSpecificCulture()):

string[] languages = new[] { CultureInfo.CreateSpecificCulture("en-US").Name };

uint numLangs = 0;
string langs = string.Join("\u0000", languages);
bool result = NativeMethods.SetProcessPreferredUILanguages(MUIFlags.MUI_LANGUAGE_NAME, 
    languages, ref numLangs);

string iconsPath = Path.Combine(Environment.SystemDirectory, "shell32.dll");
int selIcon = -1;
if (PickIconDlg(IntPtr.Zero, iconsPath, (uint)iconsPath.Length, ref selIcon) > 0)
{
    // selIcon is set to the selected Icon's index
}

Версия VB.Net:

Public Enum MUIFlags As UInteger
    MUI_LANGUAGE_ID = &H4
    MUI_LANGUAGE_NAME = &H8
End Enum

<SuppressUnmanagedCodeSecurity, SecurityCritical>
Friend Class NativeMethods
    <DllImport("Kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
    Friend Shared Function SetProcessPreferredUILanguages(dwFlags As MUIFlags,
        pwszLanguagesBuffer As String, ByRef pulNumLanguages As UInteger) As Boolean
    End Function

    <DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Friend Shared Function PickIconDlg(hwnd As IntPtr, pszIconPath As String, cchIconPath As UInteger, ByRef piIconIndex As Integer) As Integer
    End Function
End Class

Dim languages As String() = {"es-ES", "fr-FR", "en-US"}
Dim langs As String = String.Join(vbNullChar, langNames)

Dim numLangs As UInteger = 0
Dim result As Boolean = NativeMethods.SetProcessPreferredUILanguages(MUIFlags.MUI_LANGUAGE_NAME, 
    langs, numLangs)

Dim iconsPath As String = Path.Combine(Environment.SystemDirectory, "shell32.dll")
Dim selIcon As Integer = -1
If PickIconDlg(IntPtr.Zero, iconsPath, CUInt(iconsPath.Length), selIcon) > 0 Then
    ' selIcon is set to the selected Icon's index
End If

A full implementation of SetProcessPreferredUILanguages, GetProcessPreferredUILanguages, including declarations and wrapper methods, is available here:

Не удается прочитать все имена языков, возвращаемые функцией GetProcessPreferredUILanguages ​​

06.06.2019
  • Да, это работает (в комментариях я предположил, что OP это проверил). Язык выбирается из предоставленных языков в том же порядке, в зависимости от языков, фактически доступных в Системе. Не возражаете ли вы опубликовать эквивалентные версии C # и VB.Net (или я мог бы отредактировать ваш ответ, если вы не возражаете)? 06.06.2019
  • SetProcessPreferredUILanguages ​​ отлично работает, как я указал в основном сообщении этого вопроса, он меняет, например, язык OpenFileDialog, но, как я также указал, он не влияет на 'Выбор Язык диалога иконок для меня. Возможно, это могло быть связано с тем, что, как вы упомянули, пользователю, вероятно, нужно установить языковой пакет, а я его не устанавливал. Я приму ответ, предполагая, что этот факт будет правдой, и после установки пакета lang он правильно заменит язык для диалогового окна «Выбрать значок» при вызове SetProcessPreferredUILanguages ​​. Спасибо за вашу помощь. 06.06.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..