На дворе 2022 год, и, казалось бы, всё, что касается такой воспомогательной функции, как переключение языков ввода, уже должно быть давным-давно написано… Но, нет предела стремлению к совершенству. Началось с мелочи: у меня в системе установлены три языка – русский, английский и китайский. Переключались они всегда в цикле по сочетанию Alt+Shift и нужны были все три постоянно. Всё было хорошо, пока в какой-то момент (примерно полгода назад), китайский не “выпал” – стал требоваться редко и начал мешать при переключении Ru-En. А отключать его насовсем в мои планы не входило…
И тому была причина: “китаизация” ввода под Windows – это вообще отдельная история и отдельный мир. В этом мире по-прежнему используются разные программы а-ля “русификаторы”, точно, как у нас было когда-то. Встроенный в систему китайский ввод настолько плох, что им не пользуется никто, все сразу ставят свою программу. А поскольку встроенным вводом никто не пользуется, он и не эволюционирует – существует чисто для галочки, а не для практического применения… Вот. И я установил себе прекрасный (на мой взгляд) Thunisoft Huayu Pinyin и ломать настроенное совсем не хотелось.
А хотелось совсем немного: чтобы по привычному мне сочетанию Alt+Shift переключались русский и английский, а китайский, оставаясь в системе, пропускался и включался отдельной кнопочкой. Вроде, ничего сверхъестественного я не желал, правда? Однако, оказалось, что средствами Windows такое настроить нельзя. Можно на каждый язык сделать отдельную кнопку, а вот циклическое переключение будет перебирать их все… Да, в "десятке" это точно так же, как и во всех предыдущих версиях. Ну, ладно, нет так нет, думаю – найду сторонний переключатель. И не нашел. Всевозможные свитчеры предлагали что угодно, но только не нужную мне функцию. Это было настолько неожиданно, ведь задача кажется такой простой, очевидной и востребованной. Лично знаком с человеком, у которого шесть языков установлено, он их переключает мышкой в панели задач...
Ни сходу, ни специально засев в интернете для поиска, готового решения найти не смог. В сети находились только вопросы, о том, как сделать такое переключение, с пропуском какого-то языка. Ответов было не слишком много, но кое-какие всё же были. Самым подходящим мне показался совет написать скрипт на AutoHotkey. Это довольно известная и мощная программа со встроенным скриптовым языком для создания различных макрокоманд . Более того, скрипт можно скомпилировать в exe-файл и далее он будет жить уже самостоятельно, без AutoHotkey в системе. Мой скрипт перехватывает нажатие Alt+Shift и эмулирует нажатие сочетаний Ctrl+9 и Ctrl+0, к которым я привязал русский и английский, соответственно. Исходный код скрипта:
ru := DllCall("LoadKeyboardLayout", "Str", "00000419", "Int", 1)
SwitchLang()
{
global ru
w := DllCall("GetForegroundWindow")
pid := DllCall("GetWindowThreadProcessId", "UInt", w, "Ptr", 0)
l := DllCall("GetKeyboardLayout", "UInt", pid)
if (l = ru)
{
Send {LCtrl Down}{0 Down}{0 Up}{LCtrl Up}
}
else
{
Send {LCtrl Down}{9 Down}{9 Up}{LCtrl Up}
}
}
!~LShift UP::
{
if GetKeyState("Alt")
{
SwitchLang()
}
Exit
}
~LAlt UP::
{
if GetKeyState("Shift")
{
SwitchLang()
}
Exit
}
Своей цели я добился, но, всё же, полоноценным это решение назвать было нельзя. Оно больше походит на заплатку или "взлом системы" исключительно под мою задачу. И так же оно не работает в консольном окне. Так что, поиск продолжился.
Через некоторое время, где-то в обсуждениях встретил упоминание о программе ReCaps. В этой программе наконец-то нашлась нужная функция – можно было настроить циклическое переключение избранных языков, но, правда, только на клавишу CapsLock. Конечно, хотелось бы сохранить привычное сочетание Alt+Shift… Написал автору письмо с вопросом, можно ли так сделать? Автор программы, Siaržuk Žarski, ответил и прислал тестовую версию, где сочетание клавиш уже можно было менять. Программа понравилась, с удовольствием принял участие в beta-тестировании. В конце декабря вышел релиз, ReCaps v.0.9.0.3480. Обновил исходную бету до текущей версии и продолжил пользоваться. В ней так же нет поддержки переключения языка в консоли, но зато, это уже полнофункциональный менеджер языков ввода с возможностью собирать их в группы и настраивать циклическое переключение для каждой группы отдельно. Для изменения настроек не требуется программирование, можно просто дать человеку-не программисту ссылку на программу и сказать: "Установи вот это и настрой переключение как тебе удобно"
Вот такие два способа, как управлять переключением языков, если их в системе больше двух, мне удалось найти. Надеюсь, кому-то это окажется полезным.
Комментарии (48)
aborouhin
07.01.2022 10:15+1Я в своё время решал более простую задачу - просто переключение между двумя языками через CapsLock. Пробовал и скрипты AutoHotkey, и ReCaps, и lswitch, и какой-то caps-min-shift (это имя exe'шника, не помню, где его добыл). У всех этих вариантов был один недостаток - в один прекрасный момент они переставали работать, что лечилось только выгрузкой (убийством процесса) свитчера и его повторным запуском. Возможно, это связано с тем, что дело было на ноуте, который часто отправлялся в гибернацию/сон, но бесило жутко.
В итоге решилось ремаппингом CapsLock на Win+Space через PowerToys - это железобетонный вариант, который пока ни разу не подводил.
Интересно, сейчас у ReCaps уже нет этой проблемы? А то решение с PowerToys имеет свои ограничения.
Yko2007 Автор
07.01.2022 10:30+1Тьфу-тьфу за полгода ReCaps не слетал. Несколько раз за это время переключение заклинивало, но расклинивалось системным переключателем Win+Space и дальше продолжало работать без перезапуска программы. С чем было связано - не отследил.
iClo
07.01.2022 10:38+1PowerToys тоже костыль костыльный. Win+Space при переключении показывает свитчер языков, что в случае с двумя языками совсем ненужная вещь. И при активной печати это часто сбоит. То CapsLock чуть передержишь и дважды язык меняется, то интерфейс windows подтормозит и переключится с задержкой. Есть возможность переключать без свитчера по shift+ctrl(именно в таком порядке), но PowerToys отказывается так мапить кнопки.
PS Проверил рекапс, работает прекрасно!
aborouhin
07.01.2022 10:45Ну вот как раз всплывающее окошко как раз и бесит, да, когда быстро набираешь русский текст с английскими терминами, например, оно в углу мелькает как ненормальное :( Других проблем не замечал, так что для меня сейчас это лучший вариант.
Fodin
07.01.2022 14:14В ту же коллекцию keyla. Просто в произвольные моменты перестает переключать. Комп стационарный, в сон вгоняю постоянно вместо выключения.
orcy
08.01.2022 08:24Тоже пользовался keyla и когда она перестала работать у меня думал починить (яжпрограммист), но вместо этого настроил autohotkey.
perfect_genius
07.01.2022 22:35+1А чем не нравится kbdxenru от хабровчанина?
aborouhin
07.01.2022 23:56Ну, наверное, тем, что когда я эти все варианты перебирал, его не нашёл :) Насколько подсказывает быстрое гугление, это раскладка, сделанная с помощью MS Keyboard Layout Creator. Точно помню, что эту софтину я ставил, ковырялся с ней, но удовлетворительного результата не достиг. Но уже не помню, почему именно.
Надо посмотреть как-нибудь на досуге и на этот вариант, спасибо.
perfect_genius
08.01.2022 11:09Единственное, что мне неприятно в ней — что диод горит на русскую раскладку, когда хотелось бы наоборот.
p07a1330
08.01.2022 19:15Поставить в планировщике задач их перезапуск каждые сутки - не решило бы проблему?
dzmitry_li
07.01.2022 10:49+3А я пользуюсь группами переключения: по Alt+Shift переключаю "En" и "Be/Ru"; в группе "Be/Ru" по Ctrl+Shift переключаю "Be" и "Ru".
И это стандартная функция в Windows 10 (в Windows 7 тоже есть, но в группе переключается только мышкой)
cepera_ang
07.01.2022 11:34Разве это не то, что вам нужно?
Просто запихать популярные раскладки в один "язык" (т.е. в "языке" англиский будет и русская и английская раскладка), а оставшийся — в отдельный. Правда только сейчас понял, что там нельзя добавить сильно отличающуюся раскладку (т.е. кириллицу в "английский"), но можно наверное сделать свою раскладку как бы для английского, но с русскими буквами в layout creator'e.
У меня другая проблема — пользуюсь колемаком, но грёбаная винда зачем-то автоматически добавляет раскладки всех используемых языков (English US — язык системы, English UK — язык всяких форматов даты и т.д.).
Yko2007 Автор
07.01.2022 17:28Вот о том и речь, что системными настройками "чисто" это не делается... Я посмотрел-посмотрел на возможные варианты и отправился искать стороннюю программу
boulder
07.01.2022 13:08+1Послушайте, ну есть же стандартный способ переключения — вешаем разные языки на Alt+Shift+1, Alt+Shift+2 и так далее. Или даже используя Ctrl-Shift, если неохота пальцы "корячить".
Yko2007 Автор
07.01.2022 17:30Конечно так можно. Но у меня задача была сохранить привычное переключение на Alt+Shift. Ну, вот, нравится мне оно. И при этом чтоб третий язык не мешал. Но и чтоб не удалять его из системы насовсем - изредка бывает нужет
ten-thousandth
07.01.2022 16:01Спасибо!
Чем Thunisoft Huayu Pinyin лучше 搜狗输入, какие преимущества?Yko2007 Автор
07.01.2022 17:35Рекламу и новости не показывает. (У меня версия 7.1.3.154). После того, как Google Pinin приказал долго жить, тоже пользовался 搜狗, но там удалял модуль показа рекламы, который был отдельным экзешником. В итоге, оно изредка ругалось, но это было меньшее зло чем постоянно всплывающие баннеры... Возможно, была возможность их просто отключить в настройках, но что-то тогда не нашёл где...
Nibi
07.01.2022 16:01Под Win7 пользуюсь Mahou. Между двумя раскладками переключаюсь Ctrl+Shift, третью включаю Alt+Shift. Заодно решается вопрос с переключением раскладок во ВСЕХ окнах, как в десятке. Т.е. если в одном окне включил EN, то при переходе к другому тоже будет EN (автоматом быстро переключается).
stalinets
07.01.2022 17:23Пользуюсь MKey, но программка уже заброшена и не развивается. Также бывают некоторые глюки с ней:
1) Иногда она подвисает и перестаёт работать, надо через интерфейс в трее выключить и включить.
2) Через несколько тысяч нажатий она выкидывает окно с просьбой доната, в норме активный пользователь ПК должен видеть такое окно 1-2 раза в год, но у меня есть USB-устройство, которое постоянно передаёт данные, воспринимаемые этой программкой как нажатия на клавиатуру, и окошко выскакивает несколько раз в день, что бесит.
3) Иногда фактический язык и отображаемый в трее не совпадают.
4) В некоторых текстбоксах (консоли, переименования файлов и папок в некоторых случаях) она не работает.
Надо будет попробовать Recaps.
А ещё лучше было бы, если б производители клавиатур стали с обратной стороны клавиатуры прикручивать маленький ползунковый переключатель, меняющий функцию CapsLock со стандартной на переключение языка (при этом Shift+CapsLock работало бы как стандартный CapsLock)...
cepera_ang
07.01.2022 17:49А ещё лучше было бы, если б производители клавиатур
Соберите сами на базе QMK :) Тем более, что есть практически готовые варианты и в прошивку можно хоть 20 функций на любую кнопку повесить.
dikey_0ficial
07.01.2022 20:13Недавно задумался, зачем современному пользователю компьютеров/телефонов нужен капслок. В голову приходят лишь идеи о sql-запросах и кликбейтных заголовках
yurybx
07.01.2022 17:52Устал от этих костылей. Хочу клавиатуру, на которой будет три кнопки: укр, рус, англ.
cepera_ang
07.01.2022 17:53Так сделайте :) Три свитча, 3д печатный корпус, ардуинка, QMK :)
И готовые продаются: https://aliexpress.ru/item/1005001708911988.html?sku_id=12000017242086277
toxicdream
08.01.2022 18:55AutoHotkey-ем сделал перехват клавиш CapsLock, SrollLock и Pause/Break и "конвертацию" в "стандартные" Ctrl+Shift+1/2/3 на которых висят нужные мне En/Ru/Kk
toxicdream
08.01.2022 20:46В Вин10 работает везде железобетонно!
#Persistent #SingleInstance #KeyHistory 0 #NoEnv #HotkeyModifierTimeout 100 SetNumLockState, AlwaysOn SetCapsLockState, AlwaysOff SetScrollLockState, AlwaysOff CapsLock::^+1 Pause::^+2 ScrollLock::^+3 return
mvalery
07.01.2022 17:58+1Я мечтаю подсоединить вспомогательную клавиатуру на которую назначены все языки которыми я пользуюсь. Чтобы переключать одним нажатием.
К сожалению, готового решения нет. Либо исполнять танец с бубнами, устанавливая и самостоятельно приспосабливая софт для второй клавиатуры, либо покупать специальную клавиатуру, к которой прилагается готовый софт.Alexeyslav
09.01.2022 12:16Вообще-то есть. и давно. Есть программируемые клавиатуры, как для кассовых аппаратов там на каждую кнопку можно назначить любую последовательность нажатий кнопок. Но тогда это было длвольно специализированное изделие и дорогое. Сейчас же их можно самому сделать, на ардуине, например.
shavluk
07.01.2022 18:00Ппоблема трех раскладок решается двумя языками ввода, и для одного из них две раскладки клавиатуры. Язык ввода переключается ctrl-shift, а раскладка в пределах языка alt-shift. En, Ru, Ua. Английский (En)и украинский языки (две раскладки Ukr Ua и Ukr Ru).
Я настроил себе переключение тоже через AutoHotKey. Но я поборол проблемы с консолью.
Язык ввода меняю через длинное нажатие на LShift / RShift, предыдущую раскладку сохраняю.
shavluk
07.01.2022 18:39+1Вот пример моего скрипта:
; Переключение языков по Shift, с сохранением раскладки для языка ; Левый - Английский ; Правый - Украинский, текущая клавиатура (на язык повешено 2 раскладки) #NoEnv #SingleInstance force Process Priority,, High layouts := GetLayoutList() ~LShift Up:: if (A_PriorKey = "LShift") SwtichLang(layouts, 1033) ; English return ~RShift Up:: if (A_PriorKey = "RShift") SwtichLang(layouts, 1058) ; Ukraine return ;~LShift Up:: ; if (A_PriorKey = "LShift") ; SwtichLang(layouts, 0) ;return SwtichLang(ByRef layouts, LangId) { InputLocaleID := GetKeyboardLayout() lang := InputLocaleID & 0x0000FFFF if (LangId == 0) { prev := 0 for index, element in layouts { if (index == lang && prev != 0) { SwtichLang(layouts, prev) return } else prev := index } if (prev != 0) { SwtichLang(layouts, prev) return } } else if (lang != LangId) { layouts[lang] := InputLocaleID ; Сохраняем раскладку текущего языка newLocale := layouts[LangId] kbd_msg(Format("{:U}", GetLangName(LangId))) ; Send, {Ctrl Down}{Shift Down}{Shift Up}{Ctrl Up} ControlGetFocus, ctl PostMessage 0x50, 3, %newLocale%, %ctl%, A } } GetKeyboardLayout() { hWnd := WinExist("A") WinGetClass, winClass if ((winClass != "ConsoleWindowClass") || (b := SubStr(A_OSVersion, 1, 2) = "10")) { if b { dhw_prev := A_DetectHiddenWindows DetectHiddenWindows, On hWnd := WinExist("ahk_exe conhost.exe") DetectHiddenWindows, % dhw_prev } threadId := DllCall("GetWindowThreadProcessId", Ptr, hWnd, UInt, 0) lyt := DllCall("GetKeyboardLayout", Ptr, threadId, UInt) return lyt } else { WinGet, consolePID, PID DllCall("AttachConsole", Ptr, consolePID) VarSetCapacity(lyt, 16) DllCall("GetConsoleKeyboardLayoutName", Str, lyt) DllCall("FreeConsole") return lyt } } GetLayoutList() { aLayouts := [] size := DllCall("GetKeyboardLayoutList", "UInt", 0, "Ptr", 0) VarSetCapacity(list, A_PtrSize*size) size := DllCall("GetKeyboardLayoutList", Int, size, Str, list) Loop % size { ; для каждого языка сохраняем одну раскладку aLayout := NumGet(list, A_PtrSize*(A_Index - 1)) lang := aLayout & 0x0000FFFF if (aLayouts[lang] == null) aLayouts[lang] := aLayout } Return aLayouts } GetLangName(LocID, FullName = false) { static SISO639LANGNAME := 0x0059 ; ISO abbreviated language name, eg "EN" static LOCALE_SENGLANGUAGE := 0x1001 ; Full language name, eg "English" LCType := FullName ? LOCALE_SENGLANGUAGE : SISO639LANGNAME Size := (DllCall("GetLocaleInfo", UInt, LocID, UInt, LCType, UInt, 0, UInt, 0) * 2) VarSetCapacity(localeSig, Size, 0) DllCall("GetLocaleInfo", UInt, LocID, UInt, LCType, Str, localeSig, UInt, Size) Return localeSig } kbd_msg(text) { no_detect_window := -1 ToolTip, %text%, A_CaretX + 10, A_CaretY - 20 SetTimer, KbdRemoveToolTip, -1000 return KbdRemoveToolTip: ToolTip no_detect_window := 1 return }
xaosxaos2
08.01.2022 17:01Что-то слишком тяжеловато что-ли. У меня попроще, только на контралах левая английская правая русская, ну и системное ctrl+shift switch.
ControlGetFocus, ctl
PostMessage 0x50, 3, %newLocale%, %ctl%, A
ммм зачем? прекрасно работает простоPostMessage 0x50, 0x0, %newLocale%,, A
rg_software
08.01.2022 01:17+1Автор, понимаю вашу боль, сам замучился с аналогичной задачей. На сегодняшний день нашёл таки хороший софт Keymanager, который вроде как все решает.
GlebZki
08.01.2022 23:57После многих лет поиска решения, нашёл удобный вариант прямого переключения раскладки клавитуры с помощью двух-кнопчного сочетания Alt+1, Alt+2, Alt-3, ...
Имплементация - на AutoHotkey, скрипт долщен быть запущен с повышенными привилегиями для тех у кого включен UAC. Работает везде, включая RDP, VNC, консоль и т.д.
Список кодов для нужного языка - здесь: Default Input Profiles (Input Locales) in Windows | Microsoft Docs.#Persistent ; Do not get killed by errors #InstallKeybdHook ; Install keyboard hook for extended hotkeys #UseHook ; Do not open Windws Start Menu on Win-kepress en := DllCall("LoadKeyboardLayout", "Str", "00000409", "Int", 1) ru := DllCall("LoadKeyboardLayout", "Str", "00000419", "Int", 1) he := DllCall("LoadKeyboardLayout", "Str", "0000040D", "Int", 1) !1:: ; Alt+1 : US keyboard WinWait, A WinWaitActive, A ControlGetFocus, ctl, A PostMessage, 0x50, 0, %en%, %ctl%, A PostMessage, 0x50, 0, %en%,, A Return !2:: ; Alt+1 : Hebrew keyboard WinWait, A WinWaitActive, A ControlGetFocus, ctl, A PostMessage, 0x50, 0, %he%, %ctl%, A PostMessage, 0x50, 0, %he%,, A Return !3:: ; Alt+1 : Russian keyboard WinWait, A WinWaitActive, A ControlGetFocus, ctl, A PostMessage, 0x50, 0, %ru%, %ctl%, A PostMessage, 0x51, 0, %ru%,, A Return
rrrad
А в консоли что работает? Системное переключение по тем же клавишам? Или как-то по другому?
Yko2007 Автор
В консоли работает только системное переключение. А перехват Alt+Shift ни в скрипте, ни в программе ReCaps не работает. Естественно, Alt+Shift при этом уже не является системным, оно освобождается в настройках, чтоб его можно было перехватывать...
sukhe
Как это не работает? Только-что проверил
Alt & Shift::
MsgBox Hello!
return
Выскакивает окошко с сообщением, языки не переключаются.
А вообще, языки можно пропускать, чтобы их не было в цикле переключения.
Только их нужно не прямо в языки добавлять, а зайти в настройки одного или всех языков и там уже добавить нужную клавиатуру.
То есть, языки "первого уровня" будут переключаться по Alt+Shift. А внутри каждого языка раскладки клавиатур будут переключаться по Ctr+Shift (или какую вы там настроите комбинацию).
Может это и не совсем то, что вы хотели, но это готовые системные средства без сторонних программ.
Yko2007 Автор
Я начал было смотреть в сторону раскладок, но бросил. Помня, как иногда переклинивает переключатель в Windows, решил оставить всё максимально стандартно и просто и обойтись сторонней программой. Мне просто нужно было добиться пропускания китайского при переключении по Alt+Shift... В Windows в эти настройки ещё ведь и не попадешь одним кликом ))
Yko2007 Автор
Да, спасибо за поправку! Именно, что нажатие клавиш перехватывает, не работает именно переключение