1 (изменено: Krot66, 2013-10-06 22:06:07)

Тема: AHK: Еще один заменитель Punto Switcher'a

Основан на скрипте cargo отсюда: http://www.autohotkey.com/board/topic/2 … -switcher/ .
Принципиальное отличие - обработка текста осуществляется с помощью команды Input, а не выделения по горячим клавишам. Благодаря этому отпадают проблемы с символами, интерпретируемыми как разделители слов и становится возможно быстрое изменения раскладки текста, набранного посередине предложения или даже слова.
Поскольку ничего кроме Backspace не требуется, гораздо более совместим с программами, не являющихся редакторами.
Работает с Far.
Добавлен настраиваемый дневник.
Добавлена транслитерация буфера и выделенного текста.

#NoEnv 
SetWorkingDir %A_ScriptDir%
SendMode Input 
#SingleInstance, force
#MaxHotkeysPerInterval 500
SetKeyDelay 50, 50
Menu, Tray, Icon, shell32.dll, 134

;----------------------------------------------------------
; Pause - конвертация последнего слова или выделенного текста
; RCtrl+T - транслитерация выделенного текста
; RCtrl+B - транслитерация буфера обмена 
;----------------------------------------------------------
log:=1 ; - вести дневник
logfile:="Logs\Keys\" A_MM "." A_YYYY ".txt" ; - файл дневника
block:="Far 3,SciTE,AlReader,GoldenDict,PotPlayer,MPC-BE" ; - фрагменты заголовков окон программ-исключений дневника
cliplog:=1 ; - сохранять текстовый буфер обмена
cliplength:=1000 ; - обрезать до ... символов
ignor:="</h,</p>" ; - комбинации символов, при наличии которых буфер игнорируется
fkey:="Tab,Backspace,Enter,NumpadEnter,Escape" ; - завершающие клавиши, отображаемые в дневнике (см. переменную endkey)
;----------------------------------------------------------
endkey:="{Pause}{Space}{Enter}{NumpadEnter}{Tab}{Backspace}{Escape}{LControl}{RControl}{LAlt}{RAlt}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{Capslock}{Numlock}{PrintScreen}"
Eng=qwertyuiop[]asdfghjkl;'zxcvbnm,.QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>
Rus=йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ

if log
{
    SplitPath logfile, , dir
    FileCreateDir % dir
}
clip_old:=Clipboard

Loop
{
    WinGetTitle t, A
    Input text, i v, % endkey
    StringLen count, text
    e:=ErrorLevel
    if e=Endkey:Pause
        Translate()
    Log()
}

~LButton::
~RButton::
~MButton::
Input
return

Translate()
{    
    global
    clip:=Clipboard
    if (count>0)
        Send {BS %count%}
    else
    {
        Send ^{Ins}
        ClipWait 0.3
        if ! Errorlevel
        {
            Send {Del}
            text:=Clipboard
        }
        else
        {
            Tooltip Отмена невозможна, % A_CaretX,% A_CaretY
            Sleep 500
            ToolTip
            goto end
        }
    }
    r:="" 
    Loop, parse,text
    { 
       SendMessage, 0x50,, 0x4090409,, A ; Eng 
       p := InStr(Eng, A_LoopField, true) 
       if p > 0 
          r := r . SubStr(Rus, p, 1) 
       else 
       { 
          SendMessage, 0x50,, 0x4190419,, A ; Rus 
          p := InStr(Rus, A_LoopField, true) 
          if p > 0 
             r := r . SubStr(Eng, p, 1) 
          else 
             r := r . A_LoopField 
       } 
    } 
    PostMessage, 0x50, 2, 0,, A
    Send % r
    end:
    text:=r
    Clipboard:=clip
    return 
}

Log()
{
    global
    if ! log
        return
    if t contains % block
        return
    if (count>0)
    {
        if (t<>tlast)
        {
            FileAppend % "`n`n" A_DD "." A_MM "." A_YYYY "  " A_Hour ":" A_Min "  (" t ")`n", % logfile
            tlast:=t
        }
        if e contains EndKey
            StringTrimLeft e, e, 7
        k:=" "
        if e contains % fkey
            k:=" {" e "} "
        if e contains Enter
            k:=k "`n"
        if e=NewInput
            k:=" {Click} "
        FileAppend % text . k , % logfile
    }
    cl:=Clipboard
    if ((cl<>clip_old) && (cl<>""))
    {
        if cl contains % ignor
            return
        StringLen  l, cl
        end:=""
        if (l>cliplength)
            end:=" {...}"
        StringLeft cl, cl, % cliplength
        FileAppend % "`n`n### Clipboard  (" t ")`n" cl . end "`n###`n", % logfile
        
    }
    clip_old:=cl
    return
}

;------ Translit ------
>^vk42::
Translit()
MsgBox, 64, Translit, Текст в буфере!, 1
return

>^vk54::
Translit()
Send {Del}
Sleep 200
Send ^{vk56}
return

Translit()
{
    KeyWait RCtrl
    ClipBoard := "" 
    Send ^{Ins}
    ClipWait 2
    x:=ClipBoard

    StringReplace, x, x, а , a , All
    StringReplace, x, x, б , b , All
    StringReplace, x, x, в , v , All
    StringReplace, x, x, г , g , All
    StringReplace, x, x, д , d , All
    StringReplace, x, x, е , e , All
    StringReplace, x, x, ё , yo , All
    StringReplace, x, x, ж , zh , All
    StringReplace, x, x, з , z , All
    StringReplace, x, x, и , i , All
    StringReplace, x, x, й , j , All
    StringReplace, x, x, к , k , All
    StringReplace, x, x, л , l , All
    StringReplace, x, x, м , m , All
    StringReplace, x, x, н , n , All
    StringReplace, x, x, о , o , All
    StringReplace, x, x, п , p , All
    StringReplace, x, x, р , r , All
    StringReplace, x, x, с , s , All
    StringReplace, x, x, т , t , All
    StringReplace, x, x, у , u , All
    StringReplace, x, x, ф , f , All
    StringReplace, x, x, х , kh , All
    StringReplace, x, x, ц , ts , All
    StringReplace, x, x, ч , ch , All
    StringReplace, x, x, ш , sh , All
    StringReplace, x, x, щ , shh , All
    StringReplace, x, x, ъ , " , All
    StringReplace, x, x, ы , y , All
    StringReplace, x, x, ь , ' , All
    StringReplace, x, x, э , eh , All
    StringReplace, x, x, ю , yu , All
    StringReplace, x, x, я , ya , All

    StringReplace, x, x, А , A , All
    StringReplace, x, x, Б , B , All
    StringReplace, x, x, В , V , All
    StringReplace, x, x, Г , G , All
    StringReplace, x, x, Д , D , All
    StringReplace, x, x, Е , E , All
    StringReplace, x, x, Ё , Yo , All
    StringReplace, x, x, Ж , Zh , All
    StringReplace, x, x, З , Z , All
    StringReplace, x, x, И , I , All
    StringReplace, x, x, Й , J , All
    StringReplace, x, x, К , K , All
    StringReplace, x, x, Л , L , All
    StringReplace, x, x, М , M , All
    StringReplace, x, x, Н , N , All
    StringReplace, x, x, О , O , All
    StringReplace, x, x, П , P , All
    StringReplace, x, x, Р , R , All
    StringReplace, x, x, С , S , All
    StringReplace, x, x, Т , T , All
    StringReplace, x, x, У , U , All
    StringReplace, x, x, Ф , F , All
    StringReplace, x, x, Х , Kh , All
    StringReplace, x, x, Ц , Ts , All
    StringReplace, x, x, Ч , Ch , All
    StringReplace, x, x, Ш , Sh , All
    StringReplace, x, x, Щ , Shh , All
    StringReplace, x, x, Ъ , " , All
    StringReplace, x, x, Ы , Y , All
    StringReplace, x, x, Ь , ' , All
    StringReplace, x, x, Э , Eh , All
    StringReplace, x, x, Ю , Yu , All
    StringReplace, x, x, Я , Ya , All

    return Clipboard:=x
}

2

Re: AHK: Еще один заменитель Punto Switcher'a

А где сейчас используется транслит?

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

3

Re: AHK: Еще один заменитель Punto Switcher'a

В каком смысле? Я делал для себя и как в оригинале. Могу убрать

4

Re: AHK: Еще один заменитель Punto Switcher'a

Нет, я просто хотел узнать, для чего это нужно, я не в курсе.

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

5 (изменено: stealzy, 2014-11-10 17:38:08)

Re: AHK: Еще один заменитель Punto Switcher'a

Чуток улучшил.
• перевесил исправление на Hotkey(теперь можно выбрать любое сочетание клавиш),
• убрал пробел из EndKey(можно успеть набрать несколько слов прежде чем заметишь неправильный раскладку),
• вместо ClipWait используется сравнение буфера до и после
(как вариант можно очищать буфер и смотреть не появилось ли чего),
из-за низкой надежности срабатывания ClipWait и кракозябр при повторном нажатии(у меня во всяком случае)

#NoEnv 
SendMode Input 
#SingleInstance, force
#MaxHotkeysPerInterval 500
SetKeyDelay 50, 50
Menu, Tray, Icon, shell32.dll, 134

;----------------------------------------------------------
; Shift+Pause - конвертация последнего текста(слова) или выделенного текста
;----------------------------------------------------------
endkey:="{Enter}{NumpadEnter}{Tab}{Backspace}{Escape}{LControl}{RControl}{LAlt}{RAlt}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{Capslock}{Numlock}{PrintScreen}"
Lat:="~QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>``qwertyuiop[]asdfghjkl;'zxcvbnm,.?&@#"
Cyr:="ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮёйцукенгшщзхъфывапролджэячсмитьбю,?""№"

clip_old:=Clipboard

Loop
{
    WinGetTitle t, A
    Input text, i v, % endkey
    StringLen count, text
    if fTranslateAfter
        Translate()
}

~LButton::
~RButton::
~MButton::
Input
return

+Pause::
Input
fTranslateAfter:=1
return

Translate()
{    
    global
    clip:=Clipboard
    if (count>0)
        Send {BS %count%}
    else
    {
        Send ^{Ins}
        Sleep 20
        clipAfter:=Clipboard
        if (clip != clipAfter) ; ! Errorlevel
        {
            Send {Del}
            text:=Clipboard
        }
        else
        {
            Tooltip Отмена невозможна, % A_CaretX,% A_CaretY
            Sleep 500
            ToolTip
            goto end
        }
    }
    r:="" 
    Loop, parse,text
    { 
       SendMessage, 0x50,, 0x4090409,, A ; Eng 
       p := InStr(Lat, A_LoopField, true) 
       if p > 0 
          r := r . SubStr(Cyr, p, 1) 
       else 
       { 
          SendMessage, 0x50,, 0x4190419,, A ; Rus 
          p := InStr(Cyr, A_LoopField, true) 
          if p > 0 
             r := r . SubStr(Lat, p, 1) 
          else 
             r := r . A_LoopField 
       } 
    } 
    PostMessage, 0x50, 2, 0,, A
    Send % r
    end:
    text:=r
    Clipboard:=clip
    fTranslateAfter:=0
    return 
}

Баг — при пропускании текста через

Loop, parse

перевод строки — CR;LF(Windows формат) удваивается.
Если просто CR или LF (Mac или Unix формат) все ок.
Кто-нибудь знает как побороть?

6 (изменено: stealzy, 2014-11-24 11:55:51)

Re: AHK: Еще один заменитель Punto Switcher'a

Окончательный вариант, одна функция - один хоткей.
Отличие от других вариантов — исправление текста, набранного посередине другого текста или слова.

; Shift+Pause — конвертация  последнего текста  или  выделенного текста
; Зажмите Shift+Pause на 2с — в трее появится иконка, 
; откуда можно добавить скомпилированый скрипт в автозагрузку, или закрыть скрипт.
;----------------------------------------------------------
#NoEnv
#SingleInstance, force
#MaxHotkeysPerInterval 500
SetKeyDelay 50, 50
{ ; отключаемая иконка в трее
Menu, Tray, NoIcon
Menu, tray, NoStandard
NewName:="Добавить в автозагрузку"
Menu, tray, add, %NewName%, AutorunSwitch
Menu, tray, add, Выход, _Exit
}
endkey:="{Enter}{NumpadEnter}{Tab}{Backspace}{Escape}{LControl}{RControl}{LAlt}{RAlt}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{Capslock}{Numlock}{PrintScreen}"
Global Lat, Cyr
Lat:="~QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>``qwertyuiop[]asdfghjkl;'zxcvbnm,./|?@#$^&"
Cyr:="ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮёйцукенгшщзхъфывапролджэячсмитьбю./,""№;:?"

Loop
{
    Input text, i v, % endkey
    if fReplaceAfter {
        ReplaceText(text)
        fReplaceAfter:=0
    }
}

~LButton::
~RButton::
~MButton::
Input
return

+Pause::
Input
KeyWait, vk10, T2
if ErrorLevel
{
    checkIcon()
} else {
    fReplaceAfter:=1
}
return

ReplaceText(text) {
    ; take text & clear failure
    StringLen count, text
    clip:=Clipboard
    if (count>0)
        SendInput {BS %count%}
    else
    {
        SendPlay ^{Ins}
        Sleep 20 ; без задержки не всегда успевает попасть в буфер
        clipAfter:=Clipboard
        if (clip != clipAfter) ; ! Errorlevel
        {
            SendInput {Del}
            text:=Clipboard
        }
        else
        {
            Tooltip Отмена невозможна, % A_CaretX,% A_CaretY
            Sleep 500
            ToolTip
            goto end
        }
    }
    
    ; determine lang
    ;    lang    ID        code        layoute
    ;    En        1033    0x4090409    Lat
    ;    Ru        1049    0x4190419    Cyr
    EnID := 1033
    EnCode:=0x4090409
    RuCode:=0x4190419
    
    failureLangID := GetInputLangID("A")
    correctLangCode := (failureLangID=EnID) ? RuCode : EnCode
    failureLayoute := (failureLangID = EnID) ? Lat : Cyr
    correctLayoute := (failureLangID = EnID) ? Cyr : Lat
    
    ; replace text
    substituteText:="" 
    Loop, parse,text,`r
    {
        symbol := InStr(failureLayoute, A_LoopField, true)
        if symbol > 0
            substituteText .= SubStr(correctLayoute, symbol, 1)
        else
            substituteText .= A_LoopField
    }
    
    ; change language & send text
    changeLang(correctLangCode)
    Sleep 50 ; без задержки появляются баги со знаками пунктуации
    SendInput {Raw}%substituteText% ; режим Raw позволяет посылать фигурные скобки [{], [}] вместо [Х], [Ъ]. Без Raw скобку { придется оборачивать так: {{}
    end:
    Clipboard:=clip
    return
}
changeLang(lcode=0) {
    WinGetClass, Class, % "ahk_id" hwnd := WinExist("A")
    if (Class = "#32770")
        hwnd := DllCall("GetWindow", Ptr, hwnd, UInt, GW_OWNER := 4, Ptr)
    if lcode
        PostMessage, 0x50,,%lcode%,, ahk_id %hwnd%
    else
        PostMessage, 0x50, 2,,, ahk_id %hwnd%
}
GetInputLangID(window) {
    If !(hWnd := WinExist(window))
        return
 
    WinGetClass, Class
 
    if (Class == "ConsoleWindowClass")
    {
        WinGet, consolePID, PID
        DllCall("AttachConsole", Ptr, consolePID)
        VarSetCapacity(buff, 16)
        DllCall("GetConsoleKeyboardLayoutName", Str, buff)
        DllCall("FreeConsole")
        langID := "0x" . SubStr(buff, -3)
    }
    Else
        langID := DllCall("GetKeyboardLayout", Ptr, DllCall("GetWindowThreadProcessId", Ptr, hWnd, UInt, 0, Ptr), Ptr) & 0xFFFF
 
    return langID
}

; дальнейший код нужен только для версии с иконкой
checkIcon() {
Static fIconShow:=0
if fIconShow
    Menu, Tray, NoIcon
Else {
    Menu, Tray, Icon
    TrayTip, ShiftPause, I here
}
fIconShow:=!fIconShow
}
AutorunSwitch:
{
    if (NewName != "Убрать из автозагрузки")
    {
        OldName := "Добавить в автозагрузку"
        NewName := "Убрать из автозагрузки"
        FileCreateShortcut, %A_ScriptFullPath%, %A_Startup%\ShiftPause.lnk
    } else {
        OldName := "Убрать из автозагрузки"
        NewName := "Добавить в автозагрузку"
        FileDelete, %A_Startup%\ShiftPause.lnk
    }
    menu, tray, rename, %OldName%, %NewName%
}
Return
_Exit:
ExitApp
; Основан на коде Krot66, использована ф-я для определения языка от teadrinker

Можно сделать .ехе с помощью ahk2exe.

7

Re: AHK: Еще один заменитель Punto Switcher'a

Ошибка на 69 строке - A Goto/Gosub must not jump into a block that doesn't enclose it.

Windows 10 x64

8 (изменено: stealzy, 2014-11-20 16:43:58)

Re: AHK: Еще один заменитель Punto Switcher'a

Поправил, спасибо. Ошибка была из-за добавленых под конец фиг. скобок для красивого фолдинга. Не проверил.

9

Re: AHK: Еще один заменитель Punto Switcher'a

А если у меня своя раскладка типа

q::a
w::s

и т.д., и я использую SendMode Input, то строчка Input text, i v, % endkey не срабатывает для этих букв, даже если убрать опцию i, т.к. в справке по команде Input написано

I: Ignore input generated by any AutoHotkey script, such as the SendEvent command. However, the SendInput and SendPlay methods are always ignored, regardless of this setting.

Получается, единственный выход - использовать для скрипта вместо одного? Можно ли в один скрипт всё уместить?

Ещё в последнем варианте у меня цикл Loop, parse, text,`r не работает, нужно удалить ", `r".

10

Re: AHK: Еще один заменитель Punto Switcher'a

Скорее всего, надо просто видоизменить переменные Lat и Cyr ( в моей версии Rus и Eng), по которым производится замена символов.

11 (изменено: softrunner, 2015-08-15 13:47:26)

Re: AHK: Еще один заменитель Punto Switcher'a

Скорее всего, надо просто видоизменить переменные Lat и Cyr ( в моей версии Rus и Eng), по которым производится замена символов.

Не понял. Если используется SendMode Input, то в цикле получения строк зарегистрированные клавиши вообще не появляются. Похоже, остаётся лишь либо использовать SendMode Event, либо два отдельных скрипта.

12

Re: AHK: Еще один заменитель Punto Switcher'a

Ответ касался вашей нестандартной (бельгийской или какой еще) клавиатуры. Переменные, о которых писал - это ряды знаков, по которым производится замена символов при нажатии кнопки Pause. Если у вас перетасовано размещение руских и английских символов, нужно поправить эти ряды так, чтобы эти соответствия были верными. Это просто: заменяются знаки в одной и той же позиции в переменных Cyr и Lat.
Режим посылки клавиш SendEvent медленнее, но много более надежен, так что лучше убрать всю мешанину в скрипте и всюду использовать просто Send, как было у меня. Хотя это вопрос приложений, с которыми вы работаете - для большинства текстовых редакторов и офисных пакетов это не имеет значения.

13

Re: AHK: Еще один заменитель Punto Switcher'a

Krot66, клавиатура стандартная, просто раскладка не qwerty. Константы Lat и Cyr я, естественно, поменял. Сейчас перешёл на режим Send, хотя в справке написано

SendInput and SendPlay ... are generally faster and more reliable.

поэтому я и спрашиваю, можно ли обойти ограничение команды Input.

14

Re: AHK: Еще один заменитель Punto Switcher'a

На коротких фрагментах текста, которые обычно конвертирются, разница в десятые доли секунды, и если вы не будете ерзать мышью и клавиатурой в этот короткий промежуток, все будет в полном порядке. Ускорение же быстродействия и универсальность - это уже вопрос не к скрипту, а создателям Autohotkey.

15

Re: AHK: Еще один заменитель Punto Switcher'a

Пробовал этот сценарий и другой аналогичный с этого форума, оба при нажатии на горячую клавишу в окне Скайпа приводят последний в подвешенное состояние, после чего процесс не отвечает. Конкретно этот скрипт не срабатывает должным образом нигде, а именно перепечатывает только первый символ последнего слова. Система Win 10. Только у меня такая проблема? Есть ли альтернативные сценарии?

P.S.: Punto уже несколько раз сбрасывал собственные настройки, да и функция автопереключения мне ни к чему.

Win10x64, AHK v1.1.25

16

Re: AHK: Еще один заменитель Punto Switcher'a

Думаю, проблема в Win 10.

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

17 (изменено: Alectric, 2015-11-07 22:13:05)

Re: AHK: Еще один заменитель Punto Switcher'a

becauseim пишет:

Есть ли альтернативные сценарии?

Пользуюсь таким кодом:



Cyr:="ЙЦУКЕНГШЩЗФЫВАПРОЛДЯЧСМИТЬйцукенгшщзфывапролдячсмитьбюБЮхъХЪЖжэёЁЭ"""",.№;:?/"
Lat:="QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm,.<>{}[]:;'``~""""@?/#$^&|"
RegUp:=  "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM"
RegDown:="йцукенгшщзхъфывапролджэячсмитьбюqwertyuiopasdfghjklzxcvbnm"



loop
{
  sleep,100
  ; //////////////// фикс контрола \\\\\\\\\\\\\\\\\\\
  if GetKeyState("ctrl","P")
  {
    keywait,ctrl,T0.2
    if errorlevel
      ctrltimeout=1
  }
  else
    ctrltimeout=0
}

; ////////// переключение языка ____________________________HOTKEYS_________________________
Ctrl::
if !ctrltimeout
  InputLayout("T")
return

; ////////// переключение раскладки выделенного слова или слова перед кареткой, конвертация регистра_________HOTKEYS___________
+Break::
!Break::
Break::
Critical
keywait,Break,L
;if A_TimeSinceThisHotkey>200
;  return
TempClipboard:=ClipboardAll
;Clipboard=
PrevLen=
if a_thishotkey=break
{
  tmpc:=Copy(1)
  if (tmpc and !instr(tmpc,"`n,`r"))
    SelText:=tmpc
  else
  {
    loop,33
    {
;      Clipboard=
      SendInput,{shift down}
      tooltip
      SendInput,{Left}
      tooltip
      SendInput,{shift up}
      tooltip
      if !Clipboardd:=Copy(1)
        break
      Len:=StrLen(Clipboardd)
      if (Len=PrevLen)
      {
        SelText:=Clipboardd
        break
      }
      PrevLen:=Len
      swd:=SubStr(Clipboardd,1,1)
      if A_Index>32
        swd=`n
      if swd in %A_Space%,%A_Tab%,`n,`r
      {
        SendInput,{shift down}
        SendInput,{right}
        SendInput,{shift up}
        swd:=SubStr(Clipboardd,1,2)
        SelText:=SubStr(Clipboardd,RegExMatch(swd,"[\n\r]{2}") ? 3 : 2)
        break
      }
    }
  }
}
else
  SelText:=Copy(1)
NewText=
Loop,parse,SelText
{
  if (a_thishotkey="!break")
  {
    if found:=InStr(RegUp, A_LoopField, 1)
      NewText.=SubStr(RegDown, found, 1)
    else
      if found:=InStr(RegDown, A_LoopField, 1)
        NewText.=SubStr(RegUp, found, 1)
    if !found
      NewText.=A_LoopField
  }
  else
  {
    if found:=InStr(Lat, A_LoopField, 1)
    {
      Lang=Rus
      NewText.=SubStr(Cyr, found, 1)
    }
    else
      if found:=InStr(Cyr, A_LoopField, 1)
      {
        Lang=Eng
        NewText.=SubStr(Lat, found, 1)
      }
    if !found
      NewText.=A_LoopField
  }
}
Clipboard:=NewText
loop,30
{
  sleep,10
} until Clipboard
SendInput,^{vk56}
Sleep,300
Clipboard:=TempClipboard
TempClipboard:=SelText:=
if (a_thishotkey!="!break")
  InputLayout(Lang)
Return



RemoveToolTip:
tooltip
return



InputLayout(switch="T")
{
  mousegetpos,x,y
  WinGetClass,Class,% "ahk_id" hID:=WinExist("A")
  if !id:=DllCall("GetWindow",Ptr,hid,UInt,GW_OWNER:=4,Ptr)
    id:=hID
  ThreadID:=DllCall("GetWindowThreadProcessId",Ptr,id,Int,0)
  sKbd:=GetLayot(ThreadID)
  if (switch="T")
  {
    SendMessage,0x50,0,% sKbd="English" ? 0x4190419 : 0x4090409,,ahk_id %ID%
    ToolTip,% sKbd="English" ? "Русский" : "Английский",% A_CaretX=0 ? X : A_CaretX+10,% A_CaretY=0 Y ? : A_CaretY-20
    if (sKbd=GetLayot(ThreadID))
      send,{alt down}{shift down}{shift up}{alt up}
    SetTimer,RemoveToolTip,-1000
    Return 1
  }
  else if (switch="Eng")
  {
    SendMessage,0x50,0,0x4090409,,ahk_id %ID%
    ToolTip,Английский,% A_CaretX=0 ? X : A_CaretX+10,% A_CaretY=0 Y ? : A_CaretY-20
    sKbd=English
    if (sKbd!=GetLayot(ThreadID))
      send,{alt down}{shift down}{shift up}{alt up}
    SetTimer,RemoveToolTip,-1000
    Return 1
  }
  else if (switch="Rus")
  {
    SendMessage,0x50,0,0x4190419,,ahk_id %ID%
    ToolTip,Русский,% A_CaretX=0 ? X : A_CaretX+10,% A_CaretY=0 Y ? : A_CaretY-20
    sKbd=English ;
    if (sKbd=GetLayot(ThreadID))
      send,{alt down}{shift down}{shift up}{alt up}
    SetTimer,RemoveToolTip,-1000
    Return 1
  }
  Return sKbd
}
GetLayot(ThreadID)
{
    HKL:=DllCall("GetKeyboardLayout",uint,ThreadID,UShort)
    VarSetCapacity(sKbd,260,0)
    DllCall("GetLocaleInfo",uint,HKL
                           ,uint,0x1001
                           ,str,sKbd
                           ,uint,260)
  return sKbd
}

Copy(c="")
{
  if c
  {
    Clipboard=
    loop,30
    {
      sleep,10
    } until !Clipboard
    SendInput,^{vk43}
  }
  loop,30
  {
    sleep,10
  } until Clipboard
  return % Clipboard
}

ЗЫ Могут быть ошибки т.к. выдернул код из своего большого скрипта.

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

18 (изменено: becauseim, 2015-11-07 23:16:36)

Re: AHK: Еще один заменитель Punto Switcher'a

Alectric, работает! Но как и прежние сценарии, роняет Скайп.
Скажите, пожалуйста, за что отвечает "фикс контрола"? В каких случаях или в каких целях он используется?

loop
{
  sleep,100
  ; //////////////// фикс контрола \\\\\\\\\\\\\\\\\\\
  if GetKeyState("ctrl","P")
  {
    keywait,ctrl,T0.2
    if errorlevel
      ctrltimeout=1
  }
  else
    ctrltimeout=0
}
Win10x64, AHK v1.1.25

19

Re: AHK: Еще один заменитель Punto Switcher'a

По ctrl - простое переключение раскладки, фикс - чтобы переключение не срабатывало, если ctrl зажат дольше 200 ms.

becauseim пишет:

роняет Скайп

Что значит "роняет" скайп?

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

20

Re: AHK: Еще один заменитель Punto Switcher'a

Alectric, окно перестает отвечать.

Win10x64, AHK v1.1.25

21 (изменено: Alectric, 2015-11-15 11:06:14)

Re: AHK: Еще один заменитель Punto Switcher'a

Попробуй заменить функцию GetLayot(ThreadID) на пустышку:

GetLayot(ThreadID)
{
  return "English"
}

если перестанет зависать, то нужно подумать чем ее заменить. Если все равно зависает то нужно убирать все DLLCall.

Закоментируй строки:

;  if !id:=DllCall("GetWindow",Ptr,hid,UInt,GW_OWNER:=4,Ptr)
;    id:=hID
;  ThreadID:=DllCall("GetWindowThreadProcessId",Ptr,id,Int,0)
Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

22

Re: AHK: Еще один заменитель Punto Switcher'a

Alectric, сконвертировал дважды одно и то же слово, т.е. сначала в другую раскладку, потом опять в прежнюю, на третий раз "не отвечает". Да и работает с задержкой.

Win10x64, AHK v1.1.25

23

Re: AHK: Еще один заменитель Punto Switcher'a

Другие скрипты запущены?

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

24 (изменено: becauseim, 2015-11-15 11:16:18)

Re: AHK: Еще один заменитель Punto Switcher'a

Alectric пишет:

Закоментируй строки:

;  if !id:=DllCall("GetWindow",Ptr,hid,UInt,GW_OWNER:=4,Ptr)
;    id:=hID
;  ThreadID:=DllCall("GetWindowThreadProcessId",Ptr,id,Int,0)

https://i.gyazo.com/70805c75b61116a2c0e93ef6e2cee789.gif
То же и с выключенными другими скриптами.

Win10x64, AHK v1.1.25

25

Re: AHK: Еще один заменитель Punto Switcher'a

Попробуй сохранить сам скрипт в юникоде.

Win 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.