语言栏更改c#.NET

时间:2016-05-19 05:22:39

标签: c# .net windows winapi globalization

TL; DR :尝试解决InputLanguage更改输入布局但不更新语言栏显示的问题。

我正在为Trados Studio编写一个自定义插件。部分内容是与应用程序本身和Word中的语言连接,如此问题:List of all available languages for Windows .NET framework

我似乎无法解决的最后一个问题是,在我使用InputLanguage将键盘输入设置为en-US的部分代码中。

为了澄清,有一个有限的API,所以我必须在某些方面的自动化方面真正具有创造性。最好的可行方法是使用应用程序中的默认快捷方式:

  1. 首先,我将输入语言更改为en-US。

  2. 然后我将一些密钥发送到应用程序。

  3. 然后我将输入语言改回原来的状态。

  4. 然后我会出示一个表格。

  5. 以下是代码:

    //change input language to English
    InputLanguage currentLang = InputLanguage.CurrentInputLanguage;
    InputLanguage newLang = InputLanguage.FromCulture(System.Globalization.CultureInfo.GetCultureInfo("en-US"));
    if (newLang == null)
    {
        MessageBox.Show("The Upload Project function requires the En-US keyboard installed.", "Missing keyboard", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        return;
    }
    else
    {
        InputLanguage.CurrentInputLanguage = newLang;
    }
    
    //Save the document
    SendKeys.SendWait("^s");
    
    InputLanguage.CurrentInputLanguage = currentLang;
    
    //get url and credentials from a custom input form
    string[] psw = UploadData.GetPassword(
        Settings.GetValue("Upload", "Uri", "https://www.scntranslations.org/ws/services"),
        Vars.wsUsername == null ? Settings.GetValue("Upload", "User", "") : Vars.wsUsername,
        Vars.wsPassword == null ? "" : Vars.wsPassword
        );
    Application.DoEvents();
    

    我的表现是语言栏的变化会延迟到 EN ,但到表单显示时它应该 HU 但它仍然 EN 即可。

    但是,如果我用Debug.WriteLine(InputLanguage.CurrentInputLanguage.LayoutName)测试它,那么输出是正确的语言(在我的情况下" Hungarian")。

    即使隐藏了表单,语言仍然是 EN ,但匈牙利语中的键盘类型和Debug.WriteLine(InputLanguage.CurrentInputLanguage.LayoutName)返回"匈牙利语"。

    我查看了SO和网络上的几十页,我尝试了所有我能想到的内容,包括System.Threading.Thread.Sleep(1000);Application.DoEvents()以及Sendkeys.Flush(),但没有任何内容触发Windows更新语言栏,我找不到任何解决这个问题的方法。

    此问题中给出的此问题的早期版本:Change keyboard layout from C# code with .NET 4.5.2
    我现在已经完成了这项工作,完成了InputLanguage栏的上述实施。

    任何人都可以提供帮助:

    1. 对此行为作出解释?
    2. 建议一个触发C#代码更新语言栏的解决方案?
    3. 更新:代码现在完全有效。我实现了BlockInput WinAPI。

      [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "BlockInput")]
      [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
      public static extern bool BlockInput([System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool fBlockIt);
      

      并使用Win API关闭Caps Lock:

      [DllImport("user32.dll")]
      public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
      
      private void TurnOffCapsLock()
      {
          if (Control.IsKeyLocked(Keys.CapsLock)) // Checks Capslock is on
          {
              const int KEYEVENTF_EXTENDEDKEY = 0x1;
              const int KEYEVENTF_KEYUP = 0x2;
              NativeMethods.keybd_event(0x14, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
              NativeMethods.keybd_event(0x14, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
              (UIntPtr)0);
          }
      }
      

      所以剩下的就是让语言栏正确显示实际的当前输入语言。

      我可以选择发送Alt + Shifts,但我真的不想这样做。

0 个答案:

没有答案