Начав изучать китайский язык, я столкнулся с довольно неприятнейшей проблемой, связанной с невероятной косностью разработчиков Windows. При использовании только одного языка в системе никаких проблем не возникает. Раскладку клавиатуры переключать не нужно. Если применяется два языка, то всё немного сложнее. Например, если пользователь русскоязычный, то он в основном пишет на русском языке, но периодически вынужден переключаться на английский, так как большинство команд в системе на английском языке, плюс всякие термины, наподобие IPv6, тоже пишутся на английском языке. Тут всё прозаично, типовая комбинация переключения между двумя языками Shift+Alt работает отлично. Но ровно до тех пор, пока в системе всего два языка. А вот когда их становится больше, начинаются проблемы, связанные с докучающим пользовательским неудобством.
При изучении китайского языка, разумеется, в систему был установлен дополнительный язык — китайский. Более того, для того чтобы писать на pīnyīn (английскими буквами по-китайски с тонами), мне пришлось установить еще один язык — японский, для которого была сделана соответствующая Пиньину раскладка. Итого в системе образовалось целых 4 полноценных языка.
Циклически переключаться между ними по Shift+Alt — занятие довольно скучное, никогда точно не знаешь, на каком из языков остановился. Да и переключиться с текущего языка на предыдущий можно, только перещелкнув все остальные языки по очереди. Очень неудобно. Настолько неудобно, что хочется завести отдельный компьютер только для китайского. А что будет, когда к китайскому присоединится арабский? Нужно же мозги тренировать и развивать.
Альтернативно циклическому переключению можно использовать переключение путем выбора конкретного языка по уникальной комбинации клавиш, например Alt+Shift+0 для русского языка, а Alt+Shift+9 для английского. Однако выбор в стандартном приложении для переключения раскладки клавиатуры и языка в Windows не такой богатый. Наиболее удобные комбинации, при которых не нужно выворачивать пальцы, обычно выглядят как Ctrl+1, Ctrl+2 и так далее. И такое переключение отлично работает, за исключением некоторых приложений, активно использующих вкладки, например браузеры, многовкладочные текстовые редакторы и тому подобное. В них подобная комбинация выполняет функцию переключения между вкладками. И совсем не хочется, переключая язык, переключаться еще и между вкладками.
Казалось, что подобная чехарда с языками довольно легко исправляется указанием основных языков, между которыми и происходит циклическое переключение (в моем случае это русский и английский языки), а уже при необходимости можно переключиться на дополнительные языки при помощи более сложной процедуры. Такой механизм реализован в большинстве Linux-дистрибутивов и в MacOS. Но в Windows ожидать подобного не стоит. Всё потому, что закостенелые владельцы продукта даже и мысль не могут допустить, что такое может кому-то понадобиться.
Попытаться исправить проблему с переключением можно сторонними переключателями клавиатуры для Windows. Я перепробовал их несколько, в основном те, что до сих пор поддерживаются авторами. Но только PuntoSwitcher более-менее адекватно справился с задачей переключения основной пары языков. PuntoSwitcher изначально разрабатывался как средство для автоматического переключения языка в зависимости от набираемого текста. Русский и английский тексты имеют свои особенности, благодаря которым можно программным способом попытаться понять, на каком языке пользователь хотел ввести текст, а не по факту ввел. Более того, в PuntoSwitcher есть возможность настроить свое переключение между языками и даже ограничить языки, между которыми будет происходить переключение. Но выбрать традиционную комбинацию в виде Shift+Alt для переключения языков в PuntoSwitcher нельзя, так как она зарезервирована системой именно для переключения языков. Зато можно использовать другую удобную комбинацию в виде Ctrl+Space. Кстати, комбинация Ctrl+Space — довольно удобна, привыкание к ней происходит очень быстро.
И всё бы хорошо, можно было бы пользоваться PuntoSwitcher, даже отключив автоматическое переключение, если бы не Word из пакета Microsoft Office. Word — единственная программа, в которой комбинация Ctrl+Space приводит к полной невозможности использования этого приложения. Изначально в Word данная комбинация задействована для функции отмены примененных стилей выбранного текста. Её можно отключить, если найти нужную комбинацию в настройках Word. Но даже отключение функции не решает полностью проблему при переключении по Ctrl+Space в PuntoSwitcher. Word начинает залипать, даже если попробовать переключиться на другой язык просто в системном диалоге сохранения файла. И единственным способом, как можно победить подобную несовместимость между Word и PuntoSwitcher — внести Word в исключения PuntoSwitcher (там раскладка не будет переключаться при помощи PuntoSwitcher). Работает, но жутко неудобно. Word подвержен этой напасти даже в самой последней на данный момент версии — 2024.
Поскольку все остальные переключатели были сделаны разработчиками для решения своих конкретных нужд и сейчас уже не поддерживаются, то и использовать их особого смысла нет. Что-то поменяется или что-то перестает работать, и всё, придется еще раз искать, как же переключаться между основными языками, а не по всему установленному набору. Остается только выдохнуть и использовать другие средства, как можно более штатные или как можно более универсальные. Одним из таких вариантов является переключение языка посредством встроенных средств Windows, а именно скриптом на языке PowerShell.
# Коды языков $ruLang = "0419" # Русский $enLang = "0409" # Английский # Получаем текущий язык $currentLanguage = Get-WinUserLanguageList # Если текущий язык русский, переключаем на английский if ($currentLanguage.LanguageTag -eq "ru-RU") { Set-WinUserLanguageList -LanguageList $enLang -Force } # Если текущий язык английский, переключаем на русский else { Set-WinUserLanguageList -LanguageList $ruLang -Force }
Скрипт на PowerShell (расширение .ps1
) лаконичен и выполняет свои функции на все 100%. Единственное, что скрипт нужно как-то вызывать при нажатии нужной комбинации кнопок. В Windows единственным способом вызвать скрипт или программу без привлечения внешних средств является способ создания ярлыка для скрипта и назначение ему комбинации клавиш. В качестве вызываемой программы используем примерно следующую строку: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "C:\Users\xxx\ks.ps1"
. Второй параметр как раз и указывает местоположение скрипта.
Всё работает, за исключением двух моментов:
- Для запуска скрипта каждый раз вызывается его интерпретатор, ему передается на выполнение скрипт. Скрипт выполняется. На все эти операции тратятся ресурсы компьютера, могут быть подтормаживания просто из-за того, что скрипт давно не вызывался и он уже выгружен из кэша.
- Для вызова скрипта через ярлык нельзя назначить нашу любимую комбинацию Shift+Alt (или Alt+Shift, кому как удобнее). Она зарезервирована для переключения языков, поэтому штатными средствами никак ее не вызвать.
Хорошо, что есть средства поинтереснее. Программисты — народ до невозможности ленивый и изобретают многочисленные способы, как можно упростить себе жизнь за компьютером. Так и был придуман пакет AutoHotKey, сокращенно AHK. Пакет предназначен для выполнения скриптов по автоматизации различных действий с клавиатурой с очень большим набором функций. На основе AHK можно решить искомую задачу по переключению языков нужной комбинацией клавиш на клавиатуре. Например, для своих целей я разработал следующий скрипт для версии 2, а скрипты для 1 и второй версий не совместимы по синтаксису, AHK:
#Requires AutoHotkey v2.0 #SingleInstance Force eng := 1033 ; Английский rus := 1049 ; Русский !LShift:: { ; Получаем идентификатор текущей раскладки клавиатуры hkl := DllCall("GetKeyboardLayout", "UInt", DllCall("GetWindowThreadProcessId", "UInt", WinExist("A"), "UInt", 0)) ; Извлекаем язык из идентификатора раскладки langID := hkl & 0xFFFF ; Младшие 16 бит содержат идентификатор языка ;MsgBox ("Текущий язык:" . langID) ; Выводим идентификатор языка если надо посмотреть его if (langID = eng) { SendInput "!+0" ; переключаемся на русский через нажатие клавиш переключения Cntrl+Shift+0 PostMessage(0x50, 1, 0x04190419, , "A") ; переключаемся через отправку команды с кодом RU через WM_INPUTLANGCHANGEREQUEST (не работает в окнах типа SaveAs) } else { SendInput "!+9" ; переключаемся на английский через нажатие клавиш переключения Cntrl+Shift+9 PostMessage(0x50, 1, 0x04090409, , "A") ; переключаемся через отправку команды с кодом EN через WM_INPUTLANGCHANGEREQUEST (не работает в окнах типа SaveAs) } ; Исправляем проблему с непечатанием большой буквы, если отжать Alt KeyWait( 'Alt' ), Send('{Shift down}') KeyWait('Shift'), Send( '{Shift up}' ) }
В скрипте язык можно переключить двумя способами (и все по нажатию левого Shift и Alt):
- Через вызов специального системного сообщения посредством команды
PostMessage
, в примере скрипта эта возможность включена. - Через эмуляцию нажатия клавиш Alt+Shift+0 и Alt+Shift+9. Эти комбинации используются для включения русского и английского языков в языковой панели Windows, а комбинация Alt+Shift для переключения языков в языковой панели, наоборот, отключена. И эта возможность тоже включена.
Возможны и другие варианты переключения, например, через вызов системной DLL с передачей информации о необходимости смены языка туда, либо через вызов функции PowerShell. Но я остановился именно на эмуляции нажатия и отправкой системного сообщения, так как эта комбинация работает в том числе и в диалогах сохранения файлов, на рабочем столе и прочих неочевидных местах (в отличие от только одного варианта с PostMessage или SendInput). Если с таким задвоенным способом переключения возникают проблемы, то достаточно закомментировать лишний и перезапустить скрипт. При необходимости переключения на другие языки я использую опять же штатную функцию переключения через WinKey+Space, языки переключаются циклически, что мне и требуется.
Скрипт AHK можно запускать как скрипт, передавая его самому интерпретатору AutoHotKey, а он регистрируется как исполняющая программа для файлов с расширением .ahk
. Либо скомпилировать скрипт в исполняемый файл и запускать его как обычную программу. Запуск в автоматическом режиме можно осуществлять либо через папку автозапуска Windows, либо через планировщик. Я запускаю его через планировщик по событию начала сессии в системе (Log on).

Настройка языковой панели для корректного выполнения скрипта при переключении через эмуляцию нажатия кнопок
При работе скрипта (как скомпилированного, так и запускаемого через интерпретатор) есть нюанс. Если он запущен не с административными привилегиями, то он не сможет переключать язык в программе, запущенной в режиме администратора. Для исправления ситуации необходимо запустить скрипт (или его скомпилированную версию) с административными правами. Тут важно доверять разработчикам AHK, так как программа с административными правами может натворить много интересного в системе. Но все исходные коды AHK доступны в открытом доступе на GitHub, поэтому любой специалист может с ними ознакомиться и убедиться, что никаких «закладок» в программе нет (или, наоборот, есть). Либо просто использовать WinKey+Space для переключения языка в тех случаях, когда AHK не срабатывает.
И тут есть нюанс. Я печатаю на клавиатуре довольно быстро и «слепым» методом, спасибо Шахиджаняну. Поэтому после переключения языка, если мне требуется набрать следующее слово с большой буквы, то я не отжимаю клавишу Shift, а только отпускаю Alt.
; Исправляем проблему с непечатанием большой буквы, если отжать Alt KeyWait( 'Alt' ), Send('{Shift down}') KeyWait('Shift'), Send( '{Shift up}' )
Поэтому вот этот кусочек кода в скрипте позволяет именно так и поступить. После отпускания Alt, если все еще нажат Shift, я могу вводить текст большими буквами.
; Замена стрелок в Obsidian #HotIf WinActive("ahk_exe Obsidian.exe") :B*:-Ю::→ :B*:Б-::← #HotIf
В качестве небольшого бонуса привожу крошечный кусочек кода, который позволяет, не переключая раскладку, заменять набранные в русском языке последовательности ‘-Ю’ и ‘Б-’ на ‘→’ и ‘←’ соответственно. Прямо на лету. Код можно добавить в скрипт переключателя клавиатуры. Срабатывает он только в приложении Obsidian.
Дополнительные материалы для самостоятельного изучения:
- Официальный сайт AutoHotKey.
- GitHub-репозиторий AutoHotKey.
- Форум для помощи по 2 версии AutoHotKey.
- Список кодов языков в Windows.
- Раскладка для китайского Пиньина в японском.
- Punto Switcher.
- Клавиатурный тренажёр Шахиджаняна.
- Wiki по AHK 1.x на русском языке.