1

Тема: AHK: Переключение раскладки в зависимости от активной программы

Добрый день.

Написал такой скрипт для переключения языка в зависимости от активного окна:

Loop
{
	#IfWinActive ahk_class Notepad or ahk_exe firefox.exe
		SetInputLang(0x0409) ; English (USA)
		return
	#IfWinActive
}

SetInputLang(Lang)
{
    WinExist("A")
    PostMessage 0x50,,%Lang%
}

но в Notepad переключает, а в Firefox нет. В чем может быть дело?

2

Re: AHK: Переключение раскладки в зависимости от активной программы

Директивы (команды, начинающиеся со знака #) применяются только для изменения поведения горячих клавиш, в вашем коде #IfWinActive не делает ничего. Лучше всего начинать разработку со внимательного чтения справки.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Переключение раскладки в зависимости от активной программы

Не легче ли использовать группы? Добавить в одну группу окна где нужен русский а во вторую английский язык ввода. По одной клавише запустить реакцию смены на желаемый язык ввода? Зачем вечный цикл? Только процессор грузить лишний раз. Вечный цикл = ЗЛО! Тем более судя по логике кода, функция будет постоянно применять необходимый язык, что ещё один косяк.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

4 (изменено: stuermer, 2021-12-07 20:11:01)

Re: AHK: Переключение раскладки в зависимости от активной программы

__Михаил__ пишет:

Добавить в одну группу окна где нужен русский а во вторую английский язык ввода. По одной клавише запустить реакцию смены на желаемый язык ввода?

Если по клавише запускать смену языка, то какой смысл писать скрипт? Можно и без не скрипта нажать на клавишу переключения языка. В том то и смысл, чтоб автоматически язык изменился и случайно не начать набирать текст в другой раскладке.

функция будет постоянно применять необходимый язык, что ещё один косяк.

Как раз и надо постоянно применять другой (англ.) язык потому, что система по умолчанию устанавливает русский для всех программ. Проверка текущего языка с запуском DllCall() будет грузить процессор и не нужна по вышеуказанной причине.

5

Re: AHK: Переключение раскладки в зависимости от активной программы

Как вариант хук на смену окна. Автоматически переключит язык ввода без цикла.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

6

Re: AHK: Переключение раскладки в зависимости от активной программы

Вот переделал:

Loop
{
	if WinActive("ahk_class Notepad") or WinActive("ahk_exe firefox.exe")	
	{
		PostMessage 0x50,,0x0407 ; English (USA)
		return
	}
	Sleep 100
}

Все равно не меняет язык.

7

Re: AHK: Переключение раскладки в зависимости от активной программы

stuermer пишет:

Как раз и надо постоянно применять другой (англ.) язык потому, что система по умолчанию устанавливает русский для всех программ.

Нет, нужно только в момент активации окна. Можно отслеживать активацию нужных окон в цикле, если добавить их в группу (ahk_group) и использовать команды WinWaitActive/WinWaitNotActive.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8

Re: AHK: Переключение раскладки в зависимости от активной программы

Loop
{
	WinWaitActive("ahk_group WinEnglish")
	PostMessage 0x50,,0x0409 ; English (USA)
	return
	Sleep 100
}

9

Re: AHK: Переключение раскладки в зависимости от активной программы

Так не будет работать, код завершится, как только дойдёт до Return.
Кроме того, я не зря упоминал команду WinWaitNotActive.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10

Re: AHK: Переключение раскладки в зависимости от активной программы

Неверно, цикл с одной итерацией. Вы логику не понимаете или не тестируете скрипт перед отправкой на форум?

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

11

Re: AHK: Переключение раскладки в зависимости от активной программы

teadrinker пишет:

Кроме того, я не зря упоминал команду WinWaitNotActive.

Отличная загадка.

12

Re: AHK: Переключение раскладки в зависимости от активной программы

__Михаил__ пишет:

Вы логику не понимаете или не тестируете скрипт перед отправкой на форум?

Протестировал, не работало.

13

Re: AHK: Переключение раскладки в зависимости от активной программы

Тогда наверно стоило бы написать что-то кроме кода?

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

14 (изменено: stuermer, 2021-12-07 21:30:10)

Re: AHK: Переключение раскладки в зависимости от активной программы

Loop
{
WinWaitActive("ahk_group WinEnglish")
PostMessage 0x50,,0x0409
Sleep 100
}

Так не должно завершиться, но такое чувство, что чего-то не хватает.
Зачем WinWaitNotActive не понимаю, на какую группу его ставить. Я для русского группу не определял, для всех остальных приложений система установит русский сама.
Еще не понятно, как делается инициализация группы. Этот код должен исполняться 1 раз?

15

Re: AHK: Переключение раскладки в зависимости от активной программы

В группу окна добавляются через GroupAdd.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16 (изменено: stuermer, 2021-12-08 19:28:56)

Re: AHK: Переключение раскладки в зависимости от активной программы

teadrinker
Это понятно, но делается это один раз? Значит нужно делать state machine и на первом шаге создавать группу? На остальных state проверять смену окна как условие перехода на другой state и только при смене state 1 раз посылать месседж в активное окно. Цикл будет проходить через соответствующий state (Сase). Это практика из PLC-программирования, есть такая практика в AHK?

17

Re: AHK: Переключение раскладки в зависимости от активной программы

Да, в начале скрипта создаёте группу, затем в цикле ожидаете активности любого окна из группы через WinWaitActive (загляните в справку, неправильно используете), посылаете окну сообщение, затем ожидаете его неактивности с помощью WinWaitNotActive (можно без параметров, применится к ранее активному окну).

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

18 (изменено: stuermer, 2021-12-09 23:31:34)

Re: AHK: Переключение раскладки в зависимости от активной программы

; autoexecute begin
GroupAdd, WinRus, ahk_exe Viber.exe
return
; autoexecute end

Loop
{
	WinWaitActive ahk_group WinRus
	PostMessage 0x50,0,0x0419
	if ErrorLevel
		MsgBox Window doesn't exist!
		
	WinWaitNotActive
	Sleep 300
}

Скрипт запускается и сразу выгружается. Язык по умолчанию англ. и нужно установить русский для активных окон из группы WinRus.

19

Re: AHK: Переключение раскладки в зависимости от активной программы

'Return' для чего нужен? В целом?

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

20 (изменено: stuermer, 2021-12-09 23:09:03)

Re: AHK: Переключение раскладки в зависимости от активной программы

__Михаил__ пишет:

'Return' для чего нужен? В целом?

В справке после инициализации групп стоит return. Это конец секции автоисполнения. Если нет горячих клавиш получается, что у скрипт выгружается. Если убрать return не выгружается, но непонятно где конец секции автоисполнения.

21

Re: AHK: Переключение раскладки в зависимости от активной программы

stuermer
Код секции автовыполнения начинается с начала скрипта и идёт до первого Return либо до объявления первой горячей клавиши. Если нет ни того, ни другого, то до конца скрипта. В вашем коде выполнение доходит до Return и останавливается.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

22

Re: AHK: Переключение раскладки в зависимости от активной программы

teadrinker
Ок, убрал Return. Теперь стоит в бесконечном цикле.

23

Re: AHK: Переключение раскладки в зависимости от активной программы

Так и должно быть. Sleep не нужен, ErrorLevel тоже. Сообщение посылать лучше не окну, а контролу, который в фокусе. Ищите примеры отправки этого сообщения на нашем форуме.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

24 (изменено: stuermer, 2021-12-10 14:41:11)

Re: AHK: Переключение раскладки в зависимости от активной программы

teadrinker
Почему Errorlevel не нужен? Мало ли какие глюки могут быть в системе, контроль ошибок. По поводу контрола, работает и так, зачем усложнять, главное, что приложение активно, это касается всех контролов и любого окна приложения (у Winamp например, много окон, когда любое из них активно, то и весь процесс активен). Спасибо.

25

Re: AHK: Переключение раскладки в зависимости от активной программы

stuermer пишет:

контроль ошибок

PostMessage —> ErrorLevel пишет:

ErrorLevel is set to 1 if there was a problem such as the target window or control not existing. Otherwise, it is set to 0.

А как окно может не существовать, если мы только что дождались его активности? ErrorLevel здесь никогда не появится.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

26 (изменено: stuermer, 2021-12-10 19:21:31)

Re: AHK: Переключение раскладки в зависимости от активной программы

teadrinker пишет:

А как окно может не существовать, если мы только что дождались его активности? ErrorLevel здесь никогда не появится.

Ну во первых в Windows возможно все;
2. "a problem such as the target window or control not existing." - тут могли о чем то умолчать и в будущих версиях вариантов может быть больше;
3. я уже встречал ошибки в этой документации.

Поэтому лучше сделать так:

	if ErrorLevel
		MsgBox ErrorLevel: %ErrorLevel%!

тогда любая ошибка сразу будет видна. Одна проверка кушать много не просит и "лучше перебдеть, чем недобдеть".

27

Re: AHK: Переключение раскладки в зависимости от активной программы

А что это даст, если выскочит сообщение ErrorLevel: 1?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

28

Re: AHK: Переключение раскладки в зависимости от активной программы

Значит нужно проверить функционал, если не работает, искать, устранять ошибку. Либо вообще менять стратегию.

29

Re: AHK: Переключение раскладки в зависимости от активной программы

И как бы вы всё это стали делать? Я не хочу сказать, что проверка ErrorLevel всегда бесполезна, но не в данном конкретном случае. На некотором уровне подготовки иногда нужно просто поверить.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder