Справочник по C#

    Исходники по языку программирования CSharp

    Переключение языка ввода. Разбираем класс InputLanguage: Справочник по C#

    /
    /
    /
    122 Views


          В библиотеке .NET для работы с языком ввода существует класс InputLanguage. Ранее, при разработке программ под Win32 для переключения, загрузки и определения языка ввода использовались WINAPI-функции типа GetKeyboardLayout, LoadKeyboardLayout и ActivateKeyboardLayout, а также некоторые другие. На сегодняшний день разработчики под .NET могут не заморачиваться с использованием функций WINAPI. Давайте подробнее рассмотрим класс InputLanguage и определим чего в нем все таки не хватает для полного боекомплекта.


    Класс InputLanguage
          Итак, описываемый класс находится в сборке System.Windows.Forms, не поддерживает наследование (описан с модификатором sealed). Поля, которые необходимы для установки, определения и переключения языка ввода, статические. В самом объекте, основанного на классе InputLanguage, хранится характеристика какого-либо языка.


    Основные поля:
    статическое поле CurrentInputLanguage — задает или возвращает язык ввода для текущего потока.

       Содержит: Culture — хранится полная характеристика текущего языка ввода; Handle — числовой код языка, который можно подставлять в функцию WINAPI ActivateKeyboardLayout, для переключения на нужную локаль; LayoutName — содержит имя текущей раскладки клавиатуры;

    статическое поле DefaultInputLanguage — содержит информацию об установленным по умолчанию в системе языке ввода. 

       Содержит все то же, что и предыдущее поле;


    статическое поле InstalledInputLanguages — возвращает коллекцию объектов InputLanguage. Коллекцию можно перебрать таким вот образом:

    string info = string.Empty;
    InputLanguageCollection installedLangs = InputLanguage.InstalledInputLanguages;
    foreach (InputLanguage lang in installedLangs)
    {
    info = lang.Culture.Name + " " + lang.LayoutName;
    }
    

          С помощью статического метода FromCulture можно получить язык ввода ассоциирующийся с заданной культурой. Используется следующим образом:

    //Вот так можно получить информацию о любом языке ввода
    InputLanguage lang = InputLanguage.FromCulture(new CultureInfo("ru-RU"));
    //а вот так можно задать русский язык ввода для текущего потока
    InputLanguage.CurrentInputLanguage = InputLanguage.FromCulture(new CultureInfo("ru-RU"));
    

          Работать с классом InputLanguage удобно, но в нем отсутствуют некоторые возможности. К примеру, нельзя переключить на следующий или предыдущий язык. А так, как класс рассчитан только для работы с текущим потоком (т.е. текущим приложением), то нельзя переключить язык ввода для чужого приложения. Как решаются эти две задачи:
    1. Для переключения на следующий или предыдущий язык ввода используется WINAPI-функция ActivateKeyboardLayout следующим образом:

    const int HLK_NEXT = 1; //для переключения на следующий язык
    const int HLK_PREV = 0; //для переключения на предыдущий язык
    
    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr ActivateKeyboardLayout(int hkl, uint uFlags);
    
    //Далее где-то глубоко в коде
    ...
    ActivateKeyboardLayout(HLK_PREV, 0);
    ...
    ActivateKeyboardLayout(HLK_NEXT, 0);
    

    2.       Для переключения языка для чужого приложения нужно знать его хэндл и отправить ему сообщение, что было переключение языка ввода (а как он был переключен, с помощью кнопок или трея — не важно). Хэндл окна можно получить разными способами, один из них — GetForegroundWindow. Смотрим код:

    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    
    //Где-то в коде
    //0x0050 - код сообщения WM_INPUTLANGCHANGEREQUEST
    PostMessage(GetForegroundWindow(), 0x0050, 2, 0);
    

          Что можно сделать чтобы ваше приложение перехватывала, что был переключен язык ввода? При переключении система отправляет вашему приложению сообщение WM_INPUTLANGCHANGEREQUEST. Вам нужно его перехватить и обработать. Обрабатывать это и все остальные сообщения можно, прописав в коде нужно формы вашей программы следующий код:

    protected override void WndProc(ref Message m)
    {
    const int WM_INPUTLANGCHANGEREQUEST = 0x0050;
    
    if (m.Msg == WM_INPUTLANGCHANGEREQUEST)
    {
    MessageBox.Show("Переключился язык ввода");
    }
    base.WndProc(ref m);
    }
    

    Когда я писал код выше, в моем приложении он не работал. Хотя должен. Попробуйте, может у вас получится.
    Как альтернатива этому коду я в конструкторе класса формы подписался на событие InputLanguageChanged:

    public frmMain()
    {
    InitializeComponent();
    this.InputLanguageChanged += new InputLanguageChangedEventHandler(languageChange);
    }
    
    private void languageChange(Object sender, InputLanguageChangedEventArgs e)
    {
    MessageBox.Show("Переключился язык ввода");
    }
    

    Переключение языка ввода. Разбираем класс InputLanguage: Справочник по C#

    0.00 (0%) 0 votes

    moyadcode13
    • Facebook
    • Twitter
    • Google+
    • Linkedin
    • Pinterest
    moyadcode10
    moyadcode11
    moyadcode9