TL;DR: Trying to solve the issue that InputLanguage
changes the input layout but does not update the Language Bar display.
I am writing a custom plugin for Trados Studio. Part of this is interfacing with languages both in the app itself and in Word, as in this question: List of all available languages for Windows .NET framework
The last problem I seem to cannot solve is that in a part of the code I am using InputLanguage
to set the keyboard input to en-US.
To clarify, there is a limited API, so I have to be really inventive in automating certain aspects. The best workable approach was to use the default shortcuts in the application:
First I change the input language to en-US.
Then I send some keys to the application.
Then I change the input language back to what it was before.
Then I show a form.
Here is the code:
//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();
The manifestation that I have is that the Language Bar changes with a delay to EN but by the time the form shows up it should be HU yet it stays EN.
However if I test it with Debug.WriteLine(InputLanguage.CurrentInputLanguage.LayoutName)
then the output is the correct language (in my case "Hungarian").
Even after the form is hidden, the language remains EN, yet the keyboard types in Hungarian and the Debug.WriteLine(InputLanguage.CurrentInputLanguage.LayoutName)
returns "Hungarian".
I looked at dozens of pages on SO and the web and I tried everything I could think of including System.Threading.Thread.Sleep(1000);
and Application.DoEvents()
and Sendkeys.Flush()
, but nothing triggers Windows to update the Language Bar, and I could not find any solution to this issue.
The earlier version of this problem as given in this question: Change keyboard layout from C# code with .NET 4.5.2
I have made this work now fully with the above implementation of the InputLanguage
bar this last hick-up.
Can anybody help in:
- giving an explanation for this behavior?
- suggesting a solution that triggers the update of the Language Bar from C# code?
UPDATE: The code now fully works. I implemented the 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);
And also turning off the Caps Lock using Win API:
[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);
}
}
So what's left really is getting the Language Bar to correctly show the actual current input language.
I do have the option of sending Alt+Shifts, but I really don't want to do that.