I’ve been using OS X for a long time and got used to its convenient language switching system. The difference from switching to Windows is that on a poppy, language switching occurs between the last two used. As long as there are two languages in Windows, this does not create problems, but personally I know people who have 4 languages is the norm and for them switching languages causes some inconvenience because of which it’s necessary to choose the necessary language by clicking the mouse and not by a combination of buttons . And so, after the next removal / installation of the third language, it was decided to write a simple keyboard layout switch for myself, and at the same time get a useful experience.
Sources of the program are available at
https://bitbucket.org/Ezbar/languageswitcher/overview . For those who want to try the program and do not compile, they will find the binary in the Downloads section.
What tasks had to be solved:
- interception of pressing a combination of Win + Space
- change the layout for the active program
- loss of focus of the active program, after changing the layout
')
Consider each case separately. To intercept clicks, we will use API functions and set the hook for WH_KEYBOARD_LL. The value of the constants and the whole binding of the hook call can be viewed in the code.
The function of checking the combination of press to switch languagestatic IntPtr IgnoreWin_Space(int nCode, IntPtr wParam, IntPtr lParam) { Boolean spacePressed = false; var keyInfo = (KbHookParam)Marshal.PtrToStructure(lParam, typeof(KbHookParam)); if (nCode == HC_ACTION) { if ((int)wParam == WM_KEYDOWN) { if (keyInfo.VkCode == (int)Keys.Space) { spacePressed = true; kSpace = true; } else kSpace = false;
Changing the layout for the active program is also done through an API call by the PostMessage function. To do this, we receive the active application form and send it a message to change the layout. The hexadecimal code for language encoding is obtained from the function responsible for getting all installed languages into the system and their switching order.
Change the layout for the active program string HEX = Bar.getHex(); uint WM_INPUTLANGCHANGEREQUEST = 0x0050; uint KLF_ACTIVATE = 1; PostMessage(GetForegroundWindow(), WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, LoadKeyboardLayout(HEX, KLF_ACTIVATE));
The loss of the focus of the active program could be observed when entering text, for example, in the address bar of the browser. After switching the language, the focus disappeared in the text field where the set occurred. It turned out that this is very easily corrected in the constructor.
As a result, I got a good experience and a small, but useful program that makes life easier if you have more than two keyboard layouts installed. I would be grateful for any comments and advice and I apologize for the spelling mistakes I made, as well as for the possible confusion of thoughts. The author is self-taught and, perhaps, calls some things not by their proper names. Thank you all for your attention. I hope the publication will be useful to someone, for example someone who has OSX + Windows on the same computer or who simply learns programming.