1

Тема: AHK: При переключении раскладки клавиатуры пропустить ненужную

Доброго времени суток.
Возникла такая задача. В Windows 10 добавил язык Italiano к имеющимся Русский и English. Теперь имею 3 раскладки клавиатуры, в том числе итальянскую. А она мне не нужна, нужен только языковой пакет для синтеза итальянской речи. Убрать третью раскладу без удаления всего языкового пакета не удалость (в MS подтвердили, что это невозможно).

Решил попытаться сделать с помощью AHK так, чтобы при переключении РУС-ENG-ITA-РУС... раскладка перескакивала  с ENG на РУС, минуя ITA. Получилась программка (см. ниже), но она работает нестабильно. Эксперты, что посоветуете?

;---пытаюсь пропустить итальянскую раскладку клавиатуры
~LCtrl & LShift:: ;Ctrl+Shift - так у меня переключаются раскладки клавиатуры
Lang := Lang_In_Window() ;вызываем функцию определения языка раскладки активного окна — см. ниже
; 0x4190419 — русская раскладка, 0x4090409 —  английская раскладка, 0x4100410 — итальянская раскладка
If (Lang= "0x4090409") ; если была английская раскладка, то следующая итальянская раскладка, ее нужно пропустить, и сразу переключиться на русскую
{
	Send, !+1 ; Alt+Shift + 1 - Переключение раскладки клавиатуры на русский язык (у меня назначено такое сочетание)
}

Return

Lang_In_Window()
{  
;27.11.10 Выясняем язык раскладки активного окна
;http://www.script-coding.com/AutoHotkey/AhkRussian.html
;Вызвать функцию можно так: Lang := Lang_In_Window()
; 0x4190419 — русская раскладка, 0x4090409 —  английская раскладка, 0x4100410 — итальянская раскладка
	; запоминаем текущий режим определения/нет скрытых окон
    DetectHiddenWindows_Before := A_DetectHiddenWindows
    DetectHiddenWindows, On ; переключаемся на работу со скрытыми окнами
    ; запоминаем текущий режим поиска окон по заголовкам
    TitleMatchMode_Before := A_TitleMatchMode
    ; переключаемся на режим "искать в любой части заголовка окна"
    SetTitleMatchMode, 2
    FormatInteger_Before := A_FormatInteger ; запоминаем текущий числовой формат
    SetFormat, integer, H ; переключаемся на шестнадцатеричный формат
    WinGet, Active_Window_ID, ID, A ; получаем ID активного окна
    Active_Window_Thread := DllCall("GetWindowThreadProcessId"
        , "UInt", Active_Window_ID, "UInt", 0)
    ; получаем для активного окна ID его потока через Win API
    Lang := DllCall("GetKeyboardLayout", "UInt", Active_Window_Thread) ; получаем текущую раскладку для найденного потока активного окна через Win API
 	;MsgBox Lang: %Lang% 
	; 0x4190419 — русская раскладка, 0x4090409 —  английская раскладка, 0x4100410 — итальянская раскладка
    ; возвращаем режим определения/нет скрытых окон
    DetectHiddenWindows, %DetectHiddenWindows_Before%
    ; возвращаем режим поиска окон по заголовкам
    SetTitleMatchMode, %TitleMatchMode_Before%
    ; возвращаем числовой формат
    SetFormat, integer, %FormatInteger_Before%
	
	return Lang ;задаем значение функции
	
} ; конец функции

2 (изменено: svoboden, 2017-08-05 10:51:22)

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

#MaxThreadsPerHotkey 2 
 
~LCtrl & LShift::
 T := !T
 While T {
SendMessage, 0x50,, 0x4090409,, A ; английский
 sleep 10
 }
 SendMessage, 0x50,, 0x4190419,, A ; русский
 return

3 (изменено: Vadus, 2017-08-05 11:38:59)

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

Спасибо.
Работает, только к сожалению Punto Switcher сходит с ума — автокорректировка с русского на английский туда-сюда переключает при вводе каждой буквы.
И еще заметил: Ctrl+Shift+Right - не выделяет слово в текстовых редакторах
Можно что-нибудь предпринять?

4 (изменено: teadrinker, 2017-08-05 12:26:21)

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

<^LShift::
   ControlGetFocus, CtrlFocus, A
   PostMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, GetInputLangID("A") != 0x409 ? 0x409 : 0x419, %CtrlFocus%, A
   return


GetInputLangID(window)  {
   If !(hWnd := WinExist(window))
      return

   WinGetClass, winClass

   if (winClass != "ConsoleWindowClass")  {
      threadId := DllCall("GetWindowThreadProcessId", Ptr, hWnd, UInt, 0, Ptr)
      lyt := DllCall("GetKeyboardLayout", Ptr, threadId, UInt)
      langID := lyt & 0x3FFF
   }
   else  {
      WinGet, consolePID, PID
      DllCall("AttachConsole", Ptr, consolePID)
      VarSetCapacity(lyt, 16)
      DllCall("GetConsoleKeyboardLayoutName", Str, lyt)
      DllCall("FreeConsole")
      langID := "0x" . SubStr(lyt, -4)
   }
   return langID
}
Vadus пишет:

И еще заметил: Ctrl+Shift+Right - не выделяет слово в текстовых редакторах

Лучше всего заменить <^LShift (LControl + LShift) на !Shift (Alt + Shift).

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

5

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

Спасибо, teadrinker. К сожалению, вылетает даже без объявления причин. Возможно потому, что у меня старый AHK 1.0.48

6

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

Вот сделал вариант, не глючит в Punto и по Ctrl+Shift+Right выделяет слово. Тестирую дальше, спасибо за подсказки!

+LCtrl::

Lang := Lang_In_Window() ;вызываем функцию определения языка раскладки активного окна — см. ниже
; 0x4190419 — русская раскладка, 0x4090409 —  английская раскладка, 0x4100410 — итальянская раскладка
If (Lang= "0x4090409") ; если была английская раскладка, то следующая итальянская раскладка, ее нужно пропустить, и сразу переключиться на русскую
{
	 SendMessage, 0x50,, 0x4190419,, A ; русский
	
}
else If (Lang= "0x4190419") ; если была русская раскладка, то переключиться на английскую
{
	SendMessage, 0x50,, 0x4090409,, A ; английский
}
Return

Lang_In_Window()
{  
;27.11.10 Выясняем язык раскладки активного окна
;http://www.script-coding.com/AutoHotkey/AhkRussian.html
;Вызвать функцию можно так: Lang := Lang_In_Window()
; 0x4190419 — русская раскладка, 0x4090409 —  английская раскладка, 0x4100410 — итальянская раскладка
	; запоминаем текущий режим определения/нет скрытых окон
    DetectHiddenWindows_Before := A_DetectHiddenWindows
    DetectHiddenWindows, On ; переключаемся на работу со скрытыми окнами
    ; запоминаем текущий режим поиска окон по заголовкам
    TitleMatchMode_Before := A_TitleMatchMode
    ; переключаемся на режим "искать в любой части заголовка окна"
    SetTitleMatchMode, 2
    FormatInteger_Before := A_FormatInteger ; запоминаем текущий числовой формат
    SetFormat, integer, H ; переключаемся на шестнадцатеричный формат
    WinGet, Active_Window_ID, ID, A ; получаем ID активного окна
    Active_Window_Thread := DllCall("GetWindowThreadProcessId"
        , "UInt", Active_Window_ID, "UInt", 0)
    ; получаем для активного окна ID его потока через Win API
    Lang := DllCall("GetKeyboardLayout", "UInt", Active_Window_Thread) ; получаем текущую раскладку для найденного потока активного окна через Win API
 	;MsgBox Lang: %Lang% 
	; 0x4190419 — русская раскладка, 0x4090409 —  английская раскладка, 0x4100410 — итальянская раскладка
    ; возвращаем режим определения/нет скрытых окон
    DetectHiddenWindows, %DetectHiddenWindows_Before%
    ; возвращаем режим поиска окон по заголовкам
    SetTitleMatchMode, %TitleMatchMode_Before%
    ; возвращаем числовой формат
    SetFormat, integer, %FormatInteger_Before%
	
	return Lang ;задаем значение функции
	
} ; конец функции

7 (изменено: teadrinker, 2017-08-05 12:35:05)

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

Vadus пишет:

Возможно потому, что у меня старый AHK 1.0.48

И Windows 3, надо полагать? Код на форуме рассчитан на последнюю версию AHK.

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

8

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

teadrinker
Грешен
Слишком много понаписал в свое время, никак не перейти в новую жизнь...

9

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

Вот так на старом AHK должно сработать (с вашей горячей клавишей):

+LCtrl::
   ControlGetFocus, CtrlFocus, A
   PostMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, GetInputLangID("A") != 0x409 ? 0x409 : 0x419, %CtrlFocus%, A
   return


GetInputLangID(window)  {
   If !(hWnd := WinExist(window))
      return

   WinGetClass, winClass

   if (winClass != "ConsoleWindowClass")  {
      threadId := DllCall("GetWindowThreadProcessId", UInt, hWnd, UInt, 0, UInt)
      lyt := DllCall("GetKeyboardLayout", UInt, threadId, UInt)
      langID := lyt & 0x3FFF
   }
   else  {
      WinGet, consolePID, PID
      DllCall("AttachConsole", UInt, consolePID)
      VarSetCapacity(lyt, 16)
      DllCall("GetConsoleKeyboardLayoutName", Str, lyt)
      DllCall("FreeConsole")
      langID := "0x" . SubStr(lyt, -4)
   }
   return langID
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10 (изменено: Vadus, 2017-08-05 13:12:43)

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

Спасибо, работает, но почему-то не во всех приложениях. Например, не работает в Word'e и Internet Explorer.
Мой вариант работает в Word'e, но не работает в Internet Explorer.

11

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

У меня везде работает. Учитывайте, что в вашем варианте горячей клавиши нужно сначала нажимать Shift, а потом LCtrl.

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

12

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

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

13

Re: AHK: При переключении раскладки клавиатуры пропустить ненужную

Согласен с постом выше .

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.