1

Тема: AHK: Break и Shift+Break как в пунто свитчере

Пытаюсь создать скрипт выполняющий функции как в PuntoSwitcher'е конвертирующие раскладку по клавише Break и Shift+Break(конвертировать раскладку напечатанного ранее или выделенного текста соответственно).

Вот что у меня получилось:

#NoEnv
#SingleInstance,Force
SendMode,Input
SetBatchLines,-1
SetKeyDelay,10


EN=0x4090409 ;Английский
RU=0x4190419 ;Русский


+break::
break::
{
keywait,break

; Узнаем текущую раскладку в активном окне
WinGet,ID,id,A
ThreadID:=DllCall("GetWindowThreadProcessId",UInt,ID,UInt,0)
LO:=DllCall("GetKeyboardLayout",UInt,ThreadID,UInt)
if % lo=EN
  Lang=EN
else if % lo=RU
  Lang=RU

if a_thishotkey=break ; Если клавиша Break
{
clipboard:= ; Очистка буфера
Loop ; Выделение и копирование текста в буфер
{
  send,{CTRL DOWN}
  Send,{SHIFT DOWN}
  Send,{left}
  Send,{SHIFT UP}
  Send,{vk43}
  Send,{CTRL UP}
  ClipWait,1
  if ErrorLevel=0
    break
}
}
else if a_thishotkey=+break ; Если клавиша Shift+Break
{
clipboard:= ; Очистка буфера
; Копирование предварительно выделенного текста в буфер
Send,{CTRL DOWN}
Send,{vk43}
Send,{CTRL UP}
sleep,300
}

clip=%clipboard% ; Перенос текста из буфера в переменную

if lang=RU ; Обработка текста если раскладка была русская (а текс печатался английский например: РУДДЩ (HELLO))
{
SendMessage,0x50,,%EN%,,ahk_id %ID% ; Переключение на английскую раскладку для продолжения набора текста уже на английском

StringReplace,clip,clip, а , f , All
StringReplace,clip,clip, б , `, , All
StringReplace,clip,clip, в , d , All
StringReplace,clip,clip, г , u , All
StringReplace,clip,clip, д , l , All
StringReplace,clip,clip, е , t , All
StringReplace,clip,clip, ё , `` , All
StringReplace,clip,clip, ж , `; , All
StringReplace,clip,clip, з , p , All
StringReplace,clip,clip, и , b , All
StringReplace,clip,clip, й , q , All
StringReplace,clip,clip, к , r , All
StringReplace,clip,clip, л , k , All
StringReplace,clip,clip, м , v , All
StringReplace,clip,clip, н , y , All
StringReplace,clip,clip, о , j , All
StringReplace,clip,clip, п , g , All
StringReplace,clip,clip, р , h , All
StringReplace,clip,clip, с , c , All
StringReplace,clip,clip, т , n , All
StringReplace,clip,clip, у , e , All
StringReplace,clip,clip, ф , a , All
StringReplace,clip,clip, х , [ , All
StringReplace,clip,clip, ц , w , All
StringReplace,clip,clip, ч , x , All
StringReplace,clip,clip, ш , i , All
StringReplace,clip,clip, щ , o , All
StringReplace,clip,clip, ъ , ] , All
StringReplace,clip,clip, ы , s , All
StringReplace,clip,clip, ь , m , All
StringReplace,clip,clip, э , ' , All
StringReplace,clip,clip, ю , . , All
StringReplace,clip,clip, я , z , All

StringReplace,clip,clip, А , F , All ; *Проблема* Верхний регистр необрабатывается
StringReplace,clip,clip, Б , < , All
StringReplace,clip,clip, В , D , All
StringReplace,clip,clip, Г , U , All
StringReplace,clip,clip, Д , L , All
StringReplace,clip,clip, Е , T , All
StringReplace,clip,clip, Ё , ~ , All
StringReplace,clip,clip, Ж , : , All
StringReplace,clip,clip, З , P , All
StringReplace,clip,clip, И , B , All
StringReplace,clip,clip, Й , Q , All
StringReplace,clip,clip, К , R , All
StringReplace,clip,clip, Л , K , All
StringReplace,clip,clip, М , V , All
StringReplace,clip,clip, Н , Y , All
StringReplace,clip,clip, О , J , All
StringReplace,clip,clip, П , G , All
StringReplace,clip,clip, Р , H , All
StringReplace,clip,clip, С , C , All
StringReplace,clip,clip, Т , N , All
StringReplace,clip,clip, У , E , All
StringReplace,clip,clip, Ф , A , All
StringReplace,clip,clip, Х , { , All
StringReplace,clip,clip, Ц , W , All
StringReplace,clip,clip, Ч , X , All
StringReplace,clip,clip, Ш , I , All
StringReplace,clip,clip, Щ , O , All
StringReplace,clip,clip, Ъ , } , All
StringReplace,clip,clip, Ы , S , All
StringReplace,clip,clip, Ь , M , All
StringReplace,clip,clip, Э , `" , All
StringReplace,clip,clip, Ю , > , All
StringReplace,clip,clip, Я , Z , All

StringReplace,clip,clip, . , / , All
StringReplace,clip,clip, `" , @ , All
StringReplace,clip,clip, № , # , All
StringReplace,clip,clip, `; , $ , All
StringReplace,clip,clip, : , ^ , All
StringReplace,clip,clip, ? , & , All
StringReplace,clip,clip, / , | , All
}
else if lang=EN ; Обработка текста если раскладка была английская (а текс печатался русский например: YF:FNBT (НАЖАТИЕ))
{                     ; *Проблема* Слово обрабатывается только до двоеточия тоесть на выходе получается YF:АТИЕ
SendMessage,0x50,,%RU%,,ahk_id %ID%

StringReplace,clip,clip, q , й , All
StringReplace,clip,clip, w , ц , All
StringReplace,clip,clip, e , у , All
StringReplace,clip,clip, r , к , All
StringReplace,clip,clip, t , е , All
StringReplace,clip,clip, y , н , All
StringReplace,clip,clip, u , г , All
StringReplace,clip,clip, i , ш , All
StringReplace,clip,clip, o , щ , All
StringReplace,clip,clip, p , з , All
StringReplace,clip,clip, a , ф , All
StringReplace,clip,clip, s , ы , All
StringReplace,clip,clip, d , в , All
StringReplace,clip,clip, f , а , All
StringReplace,clip,clip, g , п , All
StringReplace,clip,clip, h , р , All
StringReplace,clip,clip, j , о , All
StringReplace,clip,clip, k , л , All
StringReplace,clip,clip, l , д , All
StringReplace,clip,clip, z , я , All
StringReplace,clip,clip, x , ч , All
StringReplace,clip,clip, c , с , All
StringReplace,clip,clip, v , м , All
StringReplace,clip,clip, b , и , All
StringReplace,clip,clip, n , т , All
StringReplace,clip,clip, m , ь , All

StringReplace,clip,clip, Q , Й , All ; Верхний регистр необрабатывается
StringReplace,clip,clip, W , Ц , All
StringReplace,clip,clip, E , У , All
StringReplace,clip,clip, R , К , All
StringReplace,clip,clip, T , Е , All
StringReplace,clip,clip, Y , Н , All
StringReplace,clip,clip, U , Г , All
StringReplace,clip,clip, I , Ш , All
StringReplace,clip,clip, O , Щ , All
StringReplace,clip,clip, P , З , All
StringReplace,clip,clip, A , Ф , All
StringReplace,clip,clip, S , Ы , All
StringReplace,clip,clip, D , В , All
StringReplace,clip,clip, F , А , All
StringReplace,clip,clip, G , П , All
StringReplace,clip,clip, H , Р , All
StringReplace,clip,clip, J , О , All
StringReplace,clip,clip, K , Л , All
StringReplace,clip,clip, L , Д , All
StringReplace,clip,clip, Z , Я , All
StringReplace,clip,clip, X , Ч , All
StringReplace,clip,clip, C , С , All
StringReplace,clip,clip, V , М , All
StringReplace,clip,clip, B , И , All
StringReplace,clip,clip, N , Т , All
StringReplace,clip,clip, M , Ь , All

StringReplace,clip,clip, / , . , All
StringReplace,clip,clip, `@ , `" , All
StringReplace,clip,clip, # , № , All
StringReplace,clip,clip, `$ , `; , All
StringReplace,clip,clip, ^ , : , All
StringReplace,clip,clip, & , ? , All
StringReplace,clip,clip, | , / , All
StringReplace,clip,clip, `` , ё , All
StringReplace,clip,clip, ~ , Ё , All
StringReplace,clip,clip, < , Б , All
StringReplace,clip,clip, > , Ю , All
StringReplace,clip,clip, : , Ж , All
StringReplace,clip,clip, `" , Э , All
StringReplace,clip,clip, { , Х , All
StringReplace,clip,clip, } , Ъ , All
StringReplace,clip,clip, `, , б , All
StringReplace,clip,clip, . , ю , All
StringReplace,clip,clip, ? , `, , All
StringReplace,clip,clip, `; , ж , All
StringReplace,clip,clip, ' , э , All
StringReplace,clip,clip, [ , х , All
StringReplace,clip,clip, ] , ъ , All
}

send,%clip% ; Выделенный текст заменяется обработанным
}
return

Проблемы:
1) Необрабатываются буквы в верхнем регистре, весь текст преобразуется в нижний.
2) При нажатии Break я использовал посылку Ctrl+Shift+Left чтобы выделить слово перед курсором. Но если слово содержит русские буквы: х, ъ, ж, э, б, ю; напечатанные в английской раскладке слово выделаяется только до них а не целиком.(отмечено в коментах)

Наверняка эти проблемы решаются с комощью скан кодов и DLLCALL, к сожалению я незнаю как.

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

2

Re: AHK: Break и Shift+Break как в пунто свитчере

Alectric пишет:

1) Необрабатываются буквы в верхнем регистре, весь текст преобразуется в нижний.
2) При нажатии Break я использовал посылку Ctrl+Shift+Left чтобы выделить слово перед курсором. Но если слово содержит русские буквы: х, ъ, ж, э, б, ю; напечатанные в английской раскладке слово выделаяется только до них а не целиком.(отмечено в коментах)

Наверняка эти проблемы решаются с комощью скан кодов и DLLCALL, к сожалению я незнаю как.

1) В описании же на это указано. Нужно в начале скрипта написать:

StringCaseSense On

2) посылать shift+left пока не наткнёмся на неалфавитный символ или не закончится текст.
А DllCall тут навряд ли поможет, скорее уж SendMessage .

3 (изменено: Alectric, 2011-11-01 20:23:24)

Re: AHK: Break и Shift+Break как в пунто свитчере

StringCaseSense On

Пробовал. Работает через раз и иногда наоборот маленькие буквы делает заглавными. Наверно есть зависимость от последовательности обработки символов StringReplace'ом
А с определением символа(пробела) попробую... но сомневаюсь. Подскажите пожалуйста как определить когда слово кончится
Да и SendMessage посылать в Edit текстового редактора с 1000ми строками текста страшновато както... Или я чето нето говорю?...

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

4

Re: AHK: Break и Shift+Break как в пунто свитчере

Alectric пишет:

Пробовал. Работает через раз и иногда наоборот маленькие буквы делает заглавными. Наверно есть зависимость от последовательности обработки символов StringReplace'ом

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

Alectric пишет:

А с определением символа(пробела) попробую... но сомневаюсь. Подскажите пожалуйста как определить когда слово кончится

Когда длина строки не изменится после копирования.

Alectric пишет:

Да и SendMessage посылать в Edit текстового редактора с 1000ми строками текста страшновато както... Или я чето нето говорю?...

Ну точно не страшнее чем имитировать ввод с клавиатуры и использовать буфер обмена для анализа и редактирования введённого текста . Список команд для edit'ов можно посмотреть здесь. Часть функционала предоставляет ControlGet.

5

Re: AHK: Break и Shift+Break как в пунто свитчере

Когда длина строки не изменится после копирования.

Исключено. Строка продолжит увеличиватся если слово находится в предложении.

Спасибо за ссылки буду искать варианты...

Или просто подскажите в виде кода как мне взять в переменную последнее слово в Editе и после обработки заменить его с помощью SendMessage и ControlGet.

winget,id,id,A
MouseGetPos,,,,focus
ControlGetText,text,%focus%,ahk_id %id%
; Что дальше?!?

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

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

6

Re: AHK: Break и Shift+Break как в пунто свитчере

Как-то всё сложно у вас. Вот для выделенного слова в блокноте по F11:

Cyr = ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮйцукенгшщзхъфывапролджэячсмитьбю
Lat = QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>qwertyuiop[]asdfghjkl;'zxcvbnm,.

CyrArray := [], LatArray := []

Loop, parse, Cyr
   CyrArray[A_Index] := A_LoopField
   
Loop, parse, Lat
   LatArray[A_Index] := A_LoopField
   
#IfWinActive, ahk_class Notepad
F11::
   WinWait, ahk_class Notepad
   
   VarSetCapacity(buf1, 4), VarSetCapacity(buf2, 4)
   SendMessage, EM_GETSEL := 0xB0, &buf1, &buf2, Edit1
   StartPos := NumGet(buf1) + 1
   EndPos := NumGet(buf2) + 1
   
   ControlGetText, Text, Edit1
   SelText := SubStr(Text, StartPos, EndPos - StartPos)
   
   Loop, parse, SelText
   {
      for k, v in CyrArray
         if (A_LoopField == v)
            NewText .= LatArray[k], found := 1
      
      if !found
         for k, v in LatArray
            if (A_LoopField == v)
               NewText .= CyrArray[k], found := 1
      
      if !found
         NewText .= A_LoopField
         
      found =
   }
   SendMessage, EM_REPLACESEL := 0xC2, 0, &NewText, Edit1
   NewText =
   Return

Подумаю, как конвертировать последнее написанное слово.

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

7

Re: AHK: Break и Shift+Break как в пунто свитчере

Alectric пишет:

Исключено. Строка продолжит увеличиватся если слово находится в предложении.

Я думал имеется ввиду достижение первого символа контрола. Иначе очевидно- нужно составить алфавит из допустимых символов.

Alectric пишет:

Или просто подскажите в виде кода как мне взять в переменную последнее слово в Editе и после обработки заменить его с помощью SendMessage и ControlGet.

winget,id,id,A
MouseGetPos,,,,focus
ControlGetText,text,%focus%,ahk_id %id%
; Что дальше?!?

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

Ну буфер универсальнее, ведь сообщения EM_* обрабатываются только edit'ом и richedit'ом. А выделить последнее слово очень просто при помощи регулярных выражений(код лучше оптимизировать ):

f10::
   winget id,id,A
   ControlGetFocus cont, ahk_id %id%
   if(!RegExMatch(cont, "i)edit\d+")) ; тут проверяем класс
   {
      msgbox не тот контрол
	  return
   }
   ControlGet strnum, CurrentLine, , %cont%, ahk_id %id% ; получили номер выбранной строки
   ControlGet str, Line, %strnum%, %cont%, ahk_id %id% ; получили саму строку
   ControlGet colnum, CurrentCol , , %cont%, ahk_id %id% ; получаем расположение курсора
   if(!RegExMatch(SubStr(str, colnum-1, 1), "[`~a-zA-Z\[\]{};:'\x22<>,\.]+"))
   {
      msgbox слева от курсора недопустимый символ
	  return
   }
   i:=1
   loop
   {
      FoundPos := RegExMatch(str, "[`~a-zA-Z\[\]{};:'\x22<>,\.]+", res, i) ;
      if(!FoundPos || FoundPos+StrLen(res)>=colnum)
         break
      i:=FoundPos+StrLen(res)
   }
   msgbox %res%
return

В этом примере по нажатию F10 выводится сообщение с последним словом, которое было набрано русскими буквами, но на английской раскладке. "Последним словом" здесь является слово, которому принадлежит буква слева от курсора.

teadrinker пишет:

Как-то всё сложно у вас.

Ну вообще-то примерно это я и предлагал. Только я не был уверен, что используется именно AutoHotkey_L и алгоритм я бы иной выбрал .

8

Re: AHK: Break и Shift+Break как в пунто свитчере

Если есть выделенный текст, то по F11 меняет раскладку выделенного текста, если нет — слова слева от каретки до пробела. Меняет локаль на основе последнего найденного символа — если латиница — на русскую, кириллица — на английскую. Работает с любыми edit-контролами, принимающими сообщения для стандартного Edit-контрола. Работа с браузером немного сложнее, но теоретически тоже возможна через javascript или посылы клавиш.

Cyr = ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮйцукенгшщзхъфывапролджэячсмитьбю
Lat = QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>qwertyuiop[]asdfghjkl;'zxcvbnm,.

CyrArray := [], LatArray := []

Loop, parse, Cyr
   CyrArray[A_Index] := A_LoopField
   
Loop, parse, Lat
   LatArray[A_Index] := A_LoopField
   
#If EditControl := EditControlFocused()
F11::
   VarSetCapacity(buf1, 4), VarSetCapacity(buf2, 4)
   SendMessage, EM_GETSEL := 0xB0, &buf1, &buf2, % EditControl, A
   StartPos := NumGet(buf1)
   EndPos := NumGet(buf2)
   
   ControlGetText, Text, % EditControl, A
   if (StartPos = EndPos)
   {
      SubText := SubStr(Text, 1, EndPos)
      if RegExMatch(SubText, "[ \t]$")
         Return
      SelText := RegExReplace(SubText, "s).*\s(\S+).*", "$1")
      Start := EndPos - StrLen(SelText)
   }
   else
      SelText := SubStr(Text, StartPos + 1, EndPos - StartPos)
   
   Loop, parse, SelText
   {
      for k, v in CyrArray
         if (A_LoopField == v)
            NewText .= LatArray[k], lastfound := found := 1
      
      if !found
         for k, v in LatArray
            if (A_LoopField == v)
               NewText .= CyrArray[k], lastfound := found := 2
      
      if !found
         NewText .= A_LoopField
         
      found =
   }
   
   if (StartPos = EndPos)
   {
      SendMessage, EM_SETSEL := 0xB1, Start, EndPos, % EditControl, A
      WordLen1 := WordPos1 := ""
   }
   
   SendMessage, EM_REPLACESEL := 0xC2, 1, &NewText, % EditControl, A
   NewText =
   
;переключаем раскладку   
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   If SubStr(Locale2 := NumGet(List, 4), -3) = 0409
      En := Locale2, Ru := Locale1
   Else
      En := Locale1, Ru := Locale2

   WinGet, WinID,, A
   ThreadID := DllCall("GetWindowThreadProcessId", UInt, WinID, UInt, 0)
   InputLocaleID := DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)

   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 2 ? Ru : En,, A
   Return
   
EditControlFocused()
{
   ControlGetFocus, Control, A
   StringCaseSense, Off
   if InStr(Control, "Edit")
      Return Control
}
Александр_ пишет:

и алгоритм я бы иной выбрал

Хотелось сделать без использования буфера обмена и посылов клавиш, ибо ненадёжно.

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

9

Re: AHK: Break и Shift+Break как в пунто свитчере

teadrinker пишет:

Хотелость сделать без использования буфера обмена и посылов клавиш, ибо ненадёжно.

Я про алгоритм парсинга говорил.

teadrinker пишет:

Работает с любыми edit-контролами, принимающими сообщения для стандартного Edit-контрола.
...

if InStr(Control, "Edit")


teadrinker пишет:

Работа с браузером немного сложнее, но теоретически тоже возможна через javascript или посылы клавиш.

А у тебя не возникло желание punto switcher или аналоги поковырять? Лично у меня- нет .

10

Re: AHK: Break и Shift+Break как в пунто свитчере

Александр_ пишет:
teadrinker пишет:

Работает с любыми edit-контролами, принимающими сообщения для стандартного Edit-контрола.
...

if InStr(Control, "Edit")

Я подробно не изучал, но в их названии действительно часто содержится это буквосочетание, RichEdit, например.

Александр_ пишет:

А у тебя не возникло желание punto switcher или аналоги поковырять? Лично у меня- нет .

Да нет, я так, ради интереса попробовал.

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

11

Re: AHK: Break и Shift+Break как в пунто свитчере

teadrinker пишет:

Хотелось сделать без использования буфера обмена и посылов клавиш, ибо ненадёжно.

Хотя, присмотревшись к работе punto switcher'а, кажется, он работает именно методом посыла клавиш.

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

12

Re: AHK: Break и Shift+Break как в пунто свитчере

teadrinker пишет:

Хотя, присмотревшись к работе punto switcher'а, кажется, он работает именно методом посыла клавиш.

Ага- [link]. Цитата:

http://punto.yandex.ru/faq пишет:

Почему конвертация выделенного текста не работает в некоторых программах?
    Некоторые программы не поддерживают копирование в буфер обмена по команде Ctrl+C и вставку — по Ctrl+V. Если это возможно, настройте программу, которую вы используете, для работы с данными комбинациями.

Но всех вопросов это не снимает

13

Re: AHK: Break и Shift+Break как в пунто свитчере

Важная тема, интересный вопрос.
В ANSI версии ahk с функцией исправления неверной раскладки при вводе качественно справлялся этот скрипт.
Аналогов в коллекции скриптов не нашел в своё время, да и сейчас использую его в скомпилированном виде.
Из явных недостатков — не обрабатывает «ё» и соответственно «`».

14

Re: AHK: Break и Shift+Break как в пунто свитчере

Попозже исправлю.

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

15

Re: AHK: Break и Shift+Break как в пунто свитчере

teadrinker пишет:

Хотя, присмотревшись к работе punto switcher'а, кажется, он работает именно методом посыла клавиш.

Сие хорошо видно при попытке конвертации с помощью PS текста в окне консоли: в окно приходит «^V» («Ctlr-V»).

16

Re: AHK: Break и Shift+Break как в пунто свитчере

Спасибо за ответы!

Off:
Какбудто в густой лес зашел... Такие сложные коды... Мне еще далеко до Вас...

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

17 (изменено: Alectric, 2011-11-02 19:24:54)

Re: AHK: Break и Shift+Break как в пунто свитчере

Вот в таком "страшном" виде все работает как положенно, но немного дольше чем надо:

#NoEnv
#SingleInstance,Force
SetBatchLines,-1
SetKeyDelay,100
process,priority,,realtime

EN=0x4090409
RU=0x4190419
Cyr = ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮйцукенгшщзхъфывапролджэячсмитьбю.,
Lat = QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>qwertyuiop[]asdfghjkl;'zxcvbnm,./?
; "
CyrArray := [], LatArray := []
Loop, parse, Cyr
   CyrArray[A_Index] := A_LoopField
Loop, parse, Lat
   LatArray[A_Index] := A_LoopField

+break::
break::
{
keywait,break
ClipSaved:=ClipboardAll
WinGet,ID,id,A
ThreadID:=DllCall("GetWindowThreadProcessId",UInt,ID,UInt,0)
LO:=DllCall("GetKeyboardLayout",UInt,ThreadID,UInt)
if % lo=EN
  Lang=EN
else if % lo=RU
  Lang=RU
if lang=RU
{
  SendMessage,0x50,,%EN%,,ahk_id %ID%
  tooltip,Английский,x+10,y-20,3
}
else if lang=EN
{
  SendMessage,0x50,,%RU%,,ahk_id %ID%
  tooltip,Русский,x+10,y-20,3
}
SetTimer,REMOVE_TOOLTIP,1000

if a-thishotkey=break
{
  clipboard:=
  gosub,copy
  StringReplace,clipboard,clipboard,`n,,All
}
else if a_thishotkey=+break
{
  clipboard:=
  Loop
  {
    Send,{CTRL DOWN}
    Send,{vk43}
    Send,{CTRL UP}
    ClipWait,1
    if ErrorLevel=0
      break
  }
}

Seltext=%clipboard%

   Loop, parse, SelText
   {
      for k, v in CyrArray
         if (A_LoopField == v)
            NewText .= LatArray[k], lastfound := found := 1

      if !found
         for k, v in LatArray
            if (A_LoopField == v)
               NewText .= CyrArray[k], lastfound := found := 2

      if !found
         NewText .= A_LoopField

      found =
   }

   send,%NewText%
   NewText=
   Clipboard:=ClipSaved
   ClipSaved=
}
return


REMOVE_TOOLTIP:
   SetTimer,REMOVE_TOOLTIP,off
   tooltip,,,,3
   return


copy:
{
loop
{
  StringLen,cliplen,clipboard
  if % old_cliplen=cliplen
    return
  old_cliplen:=cliplen

  if clipboard not contains %a_space%,`n
  {
    Loop
    {
      send,{CTRL DOWN}
      sleep,10
      Send,{SHIFT DOWN}
      sleep,10
      Send,{left}
      sleep,10
      Send,{SHIFT UP}
      sleep,10
      Send,{vk43}
      sleep,10
      Send,{CTRL UP}
      sleep,10
      ClipWait,1
      if ErrorLevel=0
        break
    }
  }
  else
  {
    Loop
    {
      send,{CTRL DOWN}
      sleep,10
      Send,{SHIFT DOWN}
      sleep,10
      Send,{right}
      sleep,10
      Send,{SHIFT UP}
      sleep,10
      Send,{vk43}
      sleep,10
      Send,{CTRL UP}
      sleep,10
      ClipWait,1
      if ErrorLevel=0
        return
    }
  }
}
}
return

А можно ли както вытащить последнее набранное слово с помощью этого?:

#persistent
;#notrayicon
SetBatchLines, -1

logpath=c:\log.log

hHookKeybd:=DllCall("SetWindowsHookEx",Int,WH_KEYBOARD_LL:=13,UInt,RegisterCallback("LowLevelKeyboardProc","Fast"),UInt,DllCall("GetModuleHandle",Int,0),UInt,0)
OnExit,Exit

Exit:
DllCall("UnhookWindowsHookEx",UInt,hHookKeybd)
ExitApp

LowLevelKeyboardProc(nCode,wParam,lParam)
{
global
;Critical

if (wParam=0x100)
{
  vk:=NumGet(lParam+0)
  sc:=NumGet(lParam+0,4)
WinGetTitle,titl,A
Char:=GetCharOfKey(vk,sc)
fileappend,%Char%,%logpath%
}
Return DllCall("CallNextHookEx",UInt,0,Int,nCode,UInt,wParam,UInt,lParam)
}


GetCharOfKey(vk,sc)
{
ThreadID := DllCall("GetWindowThreadProcessId",UInt,WinExist("A"),UInt,0)
InputLocaleID := DllCall("GetKeyboardLayout",UInt,ThreadID)
VarSetCapacity(KeyState, 256)
DllCall("AttachThreadInput",UInt,ThreadID,UInt,DllCall("GetCurrentThreadId"),UInt,1)
DllCall("GetKeyboardState",UInt,&KeyState)
VarSetCapacity(Buffer,2)
A_IsUnicode ? DllCall("ToUnicodeEx",UInt,vk,UInt,sc,UInt,&KeyState,Str,Buffer,Int,1,UInt,0,UInt,InputLocaleID) : DllCall("ToAsciiEx",UInt,vk,UInt,sc,UInt,&KeyState,Str,Buffer,UInt,0,UInt,InputLocaleID)
Return Buffer
}

PS: Разумеется без использования fileappend.

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

18

Re: AHK: Break и Shift+Break как в пунто свитчере

Alectric пишет:

А можно ли както вытащить последнее набранное слово с помощью этого?:

Можно с помощью этого.

Вариант с посылом клавиш, по F11 меняет раскладку выделенного, если есть, если нет — последнего слова слева от каретки до пробела, таба, переноса строки или начала текста. Также меняет раскладку клавиатуры на основе последнего найденного символа. Обрабатывает "Ё"

SetBatchLines, -1
SetKeyDelay, 0

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

CyrArray := [], LatArray := []

Loop, parse, Cyr
   CyrArray[A_Index] := A_LoopField

Loop, parse, Lat
   LatArray[A_Index] := A_LoopField

F11::
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   ClipWait, 0
   SelText := ErrorLevel ? GetWord() : Clipboard
   
   Loop, parse, SelText
   {
      found =
      for k, v in CyrArray
         if (A_LoopField == v)
            NewText .= LatArray[k], lastfound := found := 1

      if !found
         for k, v in LatArray
            if (A_LoopField == v)
               NewText .= CyrArray[k], lastfound := found := 2

      if !found
         NewText .= A_LoopField
   }
   Clipboard := NewText
   SendInput, ^{vk56}
   Clipboard := TempClipboard
   NewText =
   
;переключаем раскладку
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   If SubStr(Locale2 := NumGet(List, 4), -3) = 0409
      En := Locale2, Ru := Locale1
   Else
      En := Locale1, Ru := Locale2

   WinGet, WinID,, A
   ThreadID := DllCall("GetWindowThreadProcessId", UInt, WinID, UInt, 0)
   InputLocaleID := DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)

   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 2 ? Ru : En,, A
   Return
   
   
GetWord()
{
   While A_Index < 100
   {
      Clipboard =
      SendInput, +{Left}
      SendInput, ^{vk43}
      ClipWait, 500
      if ErrorLevel
         Return
      
      Len := StrLen(Clipboard)
      if (Len = PrevLen)
         Return Clipboard
      PrevLen := Len
      s := SubStr(Clipboard, 1, 1)
      if (s = A_Space || s = A_Tab || s = "`n" || s = "`r")
      {
         SendInput, +{Right}
         s := SubStr(Clipboard, 1, 2)
         Return SubStr(ClipBoard, RegExMatch(s, "[\n\r]{2}") ? 3 : 2)
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19

Re: AHK: Break и Shift+Break как в пунто свитчере

Работае, но с глюками.

Поставил вместо:   

SendInput, ^{vk56}

Вот это
 

 send,%NewText%

А иначе периодически вставляется старый буфер.

Спасибо за помощь.

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

20

Re: AHK: Break и Shift+Break как в пунто свитчере

Немного глючно, потом отредактирую

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

21 (изменено: Alectric, 2011-11-02 20:20:18)

Re: AHK: Break и Shift+Break как в пунто свитчере

В какойто момент перестает работать. Застрявает на

ClipWait,500

Сделал

ClipWait,1

Попробовал сделать выделение не по символу а по слову... неработает. Мой вариант в этом плане быстрее отрабатывает.

      SendInput, ^+{Left}

Off: Всеравно красивее чем мои скрипты.

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

22 (изменено: Alectric, 2011-11-02 20:34:56)

Re: AHK: Break и Shift+Break как в пунто свитчере

Немного подправил свой код. Впринципе это готовый рабочий вариант:

#NoEnv
#SingleInstance,Force
SetBatchLines,-1
SetKeyDelay,100
process,priority,,realtime

EN=0x4090409
RU=0x4190419
Cyr = ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮйцукенгшщзхъфывапролджэячсмитьбю.,
Lat = QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>qwertyuiop[]asdfghjkl;'zxcvbnm,./?
; "
CyrArray := [], LatArray := []
Loop, parse, Cyr
   CyrArray[A_Index] := A_LoopField
Loop, parse, Lat
   LatArray[A_Index] := A_LoopField

+break::
break::
{
keywait,break
ClipSaved:=ClipboardAll
WinGet,ID,id,A
ThreadID:=DllCall("GetWindowThreadProcessId",UInt,ID,UInt,0)
LO:=DllCall("GetKeyboardLayout",UInt,ThreadID,UInt)
if % lo=EN
  Lang=EN
else if % lo=RU
  Lang=RU
if lang=RU
{
  SendMessage,0x50,,%EN%,,ahk_id %ID%
  tooltip,Английский,x+10,y-20,3
}
else if lang=EN
{
  SendMessage,0x50,,%RU%,,ahk_id %ID%
  tooltip,Русский,x+10,y-20,3
}
SetTimer,REMOVE_TOOLTIP,1000

if a-thishotkey=break
{
  clipboard:=
  gosub,copy
  StringReplace,clipboard,clipboard,`n,,All
}
else if a_thishotkey=+break
{
  clipboard:=
  Loop
  {
    Send,{CTRL DOWN}
    Send,{vk43}
    Send,{CTRL UP}
    ClipWait,1
    if ErrorLevel=0
      break
  }
}

Seltext=%clipboard%

   Loop, parse, SelText
   {
      for k, v in CyrArray
         if (A_LoopField == v)
            NewText .= LatArray[k], lastfound := found := 1

      if !found
         for k, v in LatArray
            if (A_LoopField == v)
               NewText .= CyrArray[k], lastfound := found := 2

      if !found
         NewText .= A_LoopField

      found =
   }

   send,%NewText%
   NewText=
   Clipboard:=ClipSaved
   ClipSaved=
}
return


REMOVE_TOOLTIP:
   SetTimer,REMOVE_TOOLTIP,off
   tooltip,,,,3
   return


copy:
{
loop
{
  StringLen,cliplen,clipboard
  if % old_cliplen=cliplen
    return
  old_cliplen:=cliplen

  if clipboard not contains %a_space%,`n
  {
    Loop
    {
      send,{CTRL DOWN}
      Send,{SHIFT DOWN}
      Send,{left}
      Send,{SHIFT UP}
      sleep,10
      Send,{vk43}
      sleep,10
      Send,{CTRL UP}
      ClipWait,1
      if ErrorLevel=0
        break
    }
  }
  else
  {
    Loop
    {
      send,{CTRL DOWN}
      Send,{SHIFT DOWN}
      Send,{right}
      Send,{SHIFT UP}
      sleep,10
      Send,{vk43}
      sleep,10
      Send,{CTRL UP}
      ClipWait,1
      if ErrorLevel=0
        return
    }
  }
}
}
return

Результат:
При нажатии Break конвертируется слово перед текстовым курсором. (Хотя в PuntoSwitcherе конвертируется последний набранный текст а не слово)
При выделении текста и нажатии Shift+Break конвертируется выделенный текст.

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

23 (изменено: creature.ws, 2011-11-02 21:17:46)

Re: AHK: Break и Shift+Break как в пунто свитчере

При нажатии Break конвертируется слово перед текстовым курсором и удаляется пробел перед этим словом,
При выделении текста и нажатии Shift+Break конвертируется выделенный текст за исключением первого слова.

24 (изменено: Alectric, 2011-11-02 21:44:21)

Re: AHK: Break и Shift+Break как в пунто свитчере

У меня нормально все работает...
Возможно у Вас конфликтует с другим скриптом или с оригинальным PuntoSwitcherом.

Хотя наверно проблема сдесь:

if clipboard not contains %a_space%,`n
  {
    Loop
    {
      send,{CTRL DOWN}
      Send,{SHIFT DOWN}
      Send,{left}
      Send,{SHIFT UP}
      sleep,10
      Send,{vk43}
      sleep,10
      Send,{CTRL UP}
      ClipWait,1
      if ErrorLevel=0
        break
    }
  }
  else
  {
    Loop
    {
      send,{CTRL DOWN}
      Send,{SHIFT DOWN}
      Send,{right}
      Send,{SHIFT UP}
      sleep,10
      Send,{vk43}
      sleep,10
      Send,{CTRL UP}
      ClipWait,1
      if ErrorLevel=0
        return
    }
  }

Надо так:

if clipboard not contains %a_space%,`n
  {
    Loop
    {
      send,{CTRL DOWN}
      sleep,10
      Send,{SHIFT DOWN}
      sleep,10
      Send,{left}
      sleep,10
      Send,{SHIFT UP}
      sleep,10
      Send,{vk43}
      sleep,10
      Send,{CTRL UP}
      ClipWait,1
      if ErrorLevel=0
        break
    }
  }
  else
  {
    Loop
    {
      send,{CTRL DOWN}
      sleep,10
      Send,{SHIFT DOWN}
      sleep,10
      Send,{right}
      sleep,10
      Send,{SHIFT UP}
      sleep,10
      Send,{vk43}
      sleep,10
      Send,{CTRL UP}
      ClipWait,1
      if ErrorLevel=0
        return
    }
  }

Более стабильно работает.

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

25

Re: AHK: Break и Shift+Break как в пунто свитчере

С внесёнными исправлениями работает как и прежде (за исключением скорости ввода текста )
Нет, иных скриптов на момент тестирования запущено небыло, как и PuntoSwitcherа.

26

Re: AHK: Break и Shift+Break как в пунто свитчере

Вот так, вроде, без глюков работает:

SetBatchLines, -1
SetKeyDelay, 0

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

CyrArray := [], LatArray := []

Loop, parse, Cyr
   CyrArray[A_Index] := A_LoopField

Loop, parse, Lat
   LatArray[A_Index] := A_LoopField

F11::
   Critical
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   ClipWait, 0
   SelText := ErrorLevel ? GetWord() : Clipboard

   Loop, parse, SelText
   {
      found =
      for k, v in CyrArray
         if (A_LoopField == v)
            NewText .= LatArray[k], lastfound := found := 1

      if !found
         for k, v in LatArray
            if (A_LoopField == v)
               NewText .= CyrArray[k], lastfound := found := 2

      if !found
         NewText .= A_LoopField
   }
   Clipboard := NewText
   SendInput, ^{vk56}
   Sleep, 200
   Clipboard := TempClipboard
   NewText =

;переключаем раскладку
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   If SubStr(Locale2 := NumGet(List, 4), -3) = 0409
      En := Locale2, Ru := Locale1
   Else
      En := Locale1, Ru := Locale2

   WinGet, WinID,, A
   ThreadID := DllCall("GetWindowThreadProcessId", UInt, WinID, UInt, 0)
   InputLocaleID := DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)

   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 2 ? Ru : En,, A
   Return

GetWord()
{
   While A_Index < 100
   {
      Clipboard =
      SendInput, +{Left}
      SendInput, ^{vk43}
      ClipWait, 0
      if ErrorLevel
         Return

      Len := StrLen(Clipboard)
      if (Len = PrevLen)
         Return Clipboard
      PrevLen := Len
      s := SubStr(Clipboard, 1, 1)
      if (s = A_Space || s = A_Tab || s = "`n" || s = "`r")
      {
         SendInput, +{Right}
         s := SubStr(Clipboard, 1, 2)
         Return SubStr(ClipBoard, RegExMatch(s, "[\n\r]{2}") ? 3 : 2)
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Break и Shift+Break как в пунто свитчере

Исправил небольшую ошибочку.

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

28

Re: AHK: Break и Shift+Break как в пунто свитчере

Да работает и довольно быстро.

Но почему-то непереключает язык если часть слова была набрана.
Печатал я на английской раскладке русское слово нажал Ф11, сконвертировалось но продолжал печатать на английской раскладке.
Можно исправить какнибудь?

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

29

Re: AHK: Break и Shift+Break как в пунто свитчере

А что конкретно напечатал?

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

30

Re: AHK: Break и Shift+Break как в пунто свитчере

Работает.
teadrinker, большое спасибо!

31 (изменено: Alectric, 2011-11-03 15:45:53)

Re: AHK: Break и Shift+Break как в пунто свитчере

Ну допустим слово "работает" - "hf,jnftn"
В середине слова переконвертировал.

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

32

Re: AHK: Break и Shift+Break как в пунто свитчере

У меня переключает. Что значит в середине слова переконвертировал? Что конкретно было напечатано?

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

33

Re: AHK: Break и Shift+Break как в пунто свитчере

Глюк какойто...

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

34

Re: AHK: Break и Shift+Break как в пунто свитчере

Так переключает, или нет?

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

35 (изменено: Alectric, 2011-11-03 15:50:49)

Re: AHK: Break и Shift+Break как в пунто свитчере

Сначало набрал "hf,j" без ковычек потом нажал Ф11, поидее язык должен переключится, но подозреваю он переключился снова на английский, подозреваю дело в этом:

;переключаем раскладку
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   If SubStr(Locale2 := NumGet(List, 4), -3) = 0409
      En := Locale2, Ru := Locale1
   Else
      En := Locale1, Ru := Locale2

   WinGet, WinID,, A
   ThreadID := DllCall("GetWindowThreadProcessId", UInt, WinID, UInt, 0)
   InputLocaleID := DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)

   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 2 ? Ru : En,, A

Всмысле гдето сдесь.

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

36

Re: AHK: Break и Shift+Break как в пунто свитчере

Alectric пишет:

Сначало набрал "hf,j" без ковычек потом нажал Ф11, поидее язык должен переключится, но подозреваю он переключился снова на английский

Хм, у меня на русский переключается. В коде, вроде, всё верно.

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

37 (изменено: Alectric, 2011-11-03 15:55:27)

Re: AHK: Break и Shift+Break как в пунто свитчере

Да в логе есть переключение:

if (A_LoopField == v)  
032: if (A_LoopField == v)  
032: if (A_LoopField == v)  
032: if (A_LoopField == v)  
032: if (A_LoopField == v)  
032: if (A_LoopField == v)  
035: if !found  
037: }
038: Clipboard := NewText
039: SendInput,^{vk56}
040: Sleep,200 (0.20)
041: Clipboard := TempClipboard
042: NewText = 
045: VarSetCapacity(List, 8)  
046: DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)  
047: Locale1 := NumGet(List)
048: if SubStr(Locale2 := NumGet(List, 4), -3) = 0409  
051: En := Locale1, Ru := Locale2  
053: WinGet,WinID,,A
054: ThreadID := DllCall("GetWindowThreadProcessId", UInt, WinID, UInt, 0)
055: InputLocaleID := DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)
057: SendMessage,WM_INPUTLANGCHANGEREQUEST := 0x50,,lastfound = 2 ? Ru : En,,A ; переключение
058: Return (60.75)

Press [F5] to refresh.

Но увы...
Может от винды зависит... У меня ХП про
Левых скриптов незапущено.

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

38

Re: AHK: Break и Shift+Break как в пунто свитчере

Ага, понял, сейчас исправлю.

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

39

Re: AHK: Break и Shift+Break как в пунто свитчере

Вот так попробуй:

SetBatchLines, -1
SetKeyDelay, 0

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

CyrArray := [], LatArray := []

Loop, parse, Cyr
   CyrArray[A_Index] := A_LoopField

Loop, parse, Lat
   LatArray[A_Index] := A_LoopField

F11::
   Critical
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   ClipWait, 0
   SelText := ErrorLevel ? GetWord() : Clipboard

   Loop, parse, SelText
   {
      found =
      for k, v in CyrArray
         if (A_LoopField == v)
            NewText .= LatArray[k], lastfound := found := 1

      if !found
         for k, v in LatArray
            if (A_LoopField == v)
               NewText .= CyrArray[k], lastfound := found := 2

      if !found
         NewText .= A_LoopField
   }
   Clipboard := NewText
   SendInput, ^{vk56}
   Sleep, 200
   Clipboard := TempClipboard
   NewText =

;переключаем раскладку
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   If SubStr(Locale2 := NumGet(List, 4), -3) = 0409
      En := Locale2, Ru := Locale1
   Else
      En := Locale1, Ru := Locale2
   SetFormat, IntegerFast, D

   WinGet, WinID,, A
   ThreadID := DllCall("GetWindowThreadProcessId", UInt, WinID, UInt, 0)
   InputLocaleID := DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)

   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 2 ? Ru : En,, A
   Return

GetWord()
{
   While A_Index < 100
   {
      Clipboard =
      SendInput, +{Left}
      SendInput, ^{vk43}
      ClipWait, 0
      if ErrorLevel
         Return

      Len := StrLen(Clipboard)
      if (Len = PrevLen)
         Return Clipboard
      PrevLen := Len
      s := SubStr(Clipboard, 1, 1)
      if (s = A_Space || s = A_Tab || s = "`n" || s = "`r")
      {
         SendInput, +{Right}
         s := SubStr(Clipboard, 1, 2)
         Return SubStr(ClipBoard, RegExMatch(s, "[\n\r]{2}") ? 3 : 2)
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

40

Re: AHK: Break и Shift+Break как в пунто свитчере

Работает!!!
Спасибо за работу!

Думаю тему можно закрыть.
А скрипт добавить в коллекцию, скорее всего пригодится комунибудь.
PS: F11 лучше заменить на Break так привычнее.

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

41

Re: AHK: Break и Shift+Break как в пунто свитчере

У меня просто Break другим занята.

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

42

Re: AHK: Break и Shift+Break как в пунто свитчере

Off: Объясните пожалуйста зачем в скрипте "Critical"?
Я его убираю и работоспособность остается.

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

43

Re: AHK: Break и Shift+Break как в пунто свитчере

На случай, если горячая клавиша случайно будет нажата повторно до того, как предыдущая отработает полностью. Если без Critical, тогда выполнение предыдущей будет прервано, а там в конце возврат в буфер обмена изначального содержания.

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

44

Re: AHK: Break и Shift+Break как в пунто свитчере

А-а. Ясно спасибо за объяснения.

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

45

Re: AHK: Break и Shift+Break как в пунто свитчере

Слегка оптимизированный вариант:

SetBatchLines, -1
SetKeyDelay, 0

F11::
   Critical
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   ClipWait, 0
   
   SelText := ErrorLevel ? GetWord() : Clipboard
   pResult := ConvertText(SelText)
   
   Clipboard := StrGet(pResult + 4)
   SendInput, ^{vk56}
   
   Sleep, 200
   Clipboard := TempClipboard
   TempClipboard := SelText := ""
   
   SwitchLocale(NumGet(pResult+0))
   Return

GetWord()
{
   While A_Index < 100
   {
      Clipboard =
      SendInput, +{Left}
      SendInput, ^{vk43}
      ClipWait, 0
      if ErrorLevel
         Return

      Len := StrLen(Clipboard)
      if (Len = PrevLen)
         Return Clipboard
      PrevLen := Len
      s := SubStr(Clipboard, 1, 1)
      if (s = A_Space || s = A_Tab || s = "`n" || s = "`r")
      {
         SendInput, +{Right}
         s := SubStr(Clipboard, 1, 2)
         Return SubStr(ClipBoard, RegExMatch(s, "[\n\r]{2}") ? 3 : 2)
      }
   }
}

ConvertText(Text)
{
   static
   local NewText
   
   if !IsObject(CyrArray)
   {
      Cyr = ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮёйцукенгшщзхъфывапролджэячсмитьбю
      Lat = ~QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>``qwertyuiop[]asdfghjkl;'zxcvbnm,.

      CyrArray := [], LatArray := []

      Loop, parse, Cyr
         CyrArray[A_Index] := A_LoopField

      Loop, parse, Lat
         LatArray[A_Index] := A_LoopField
   }
   
   Loop, parse, Text
   {
      found =
      for k, v in LatArray
         if (A_LoopField == v)
            NewText .= CyrArray[k], lastfound := found := 2

      if !found
         for k, v in CyrArray
            if (A_LoopField == v)
               NewText .= LatArray[k], lastfound := found := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, 4 + StrPut(NewText))
   NumPut(lastfound, Result), StrPut(NewText, &Result + 4)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, 4), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 2 ? Ru : En,, A
}

В предыдущем коде строки

   WinGet, WinID,, A
   ThreadID := DllCall("GetWindowThreadProcessId", UInt, WinID, UInt, 0)
   InputLocaleID := DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)

были лишними.

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

46

Re: AHK: Break и Shift+Break как в пунто свитчере

Правда, есть проблема. В окнах ввода текста, например, В Контакте, промежуток между словами не определяется, как символ A_Space и теряется при поиске начала слова.

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

47 (изменено: Alectric, 2011-11-03 21:33:12)

Re: AHK: Break и Shift+Break как в пунто свитчере

И он продолжает выделять текст дальше или останавливается оставляя выделенным текст?

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

48

Re: AHK: Break и Shift+Break как в пунто свитчере

Выделяет до пробела, затем пробел, после этого выходит из цикла по условию

Len := StrLen(Clipboard)
if (Len = PrevLen)
   Return Clipboard

т. е пробел остаётся выделенным. Потом посылает Ctrl+V (сконвертированный текст), и пробел теряется.

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

49

Re: AHK: Break и Shift+Break как в пунто свитчере

А если так?:

GetWord()
{
   While A_Index < 100
   {
      Clipboard =
      SendInput, +{Left}
      SendInput, ^{vk43}
      ClipWait, 0
      if ErrorLevel
         Return

      PrevLen := Len
      s := SubStr(Clipboard, 1, 3)
      if s contains %A_Space%,%A_Tab%,`n,`r,
      {
         SendInput, +{Right}
         s := SubStr(Clipboard, 1, 2)
         Return SubStr(ClipBoard, RegExMatch(s, "[\n\r]{2}") ? 3 : 2)
      }
      Len := StrLen(Clipboard)
      if (Len = PrevLen)
         Return Clipboard
   }
}
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

50

Re: AHK: Break и Shift+Break как в пунто свитчере

А в чём разница? Всё равно пробел должен определиться, а он не определяется. Сам-то попробовал?

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

51

Re: AHK: Break и Shift+Break как в пунто свитчере

Пробовал... Только ненашел такого места где он так работает... Я не зареген в контакте.

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

52

Re: AHK: Break и Shift+Break как в пунто свитчере

В Одноклассниках также.

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

53

Re: AHK: Break и Shift+Break как в пунто свитчере

В строках логин пароля также? Ато я и там незареген.

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

54

Re: AHK: Break и Shift+Break как в пунто свитчере

Нет, в логине как раз нормально определяется.

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

55 (изменено: Alectric, 2011-11-03 22:12:49)

Re: AHK: Break и Shift+Break как в пунто свитчере

Сейчас взял пароль у брата, зашел... Щас посмотрю.


Да нет, все нормально работает.
Только после вставки текста каретка в начало строки уходит.

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

56

Re: AHK: Break и Shift+Break как в пунто свитчере

А браузер какой?

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

57 (изменено: Alectric, 2011-11-03 22:14:29)

Re: AHK: Break и Shift+Break как в пунто свитчере

Opera
О программе
Информация о версии
Версия:
10.01
Сборка:
1844
Платформа:
Win32
Система:
Windows XP
Версия Java:
Java не установлен
Модуль XHTML+Voice:
Плагин не загружен

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

58

Re: AHK: Break и Shift+Break как в пунто свитчере

Немного оффтопика:
После включения обсуждаемого скрипта в мой основной перестали срабатывать хоткеи вида:

vkA5 & vk20::SendInput % GetKeyState("Shift","P") ? Chr(0x200B) : Chr(0x00A0)

Признаться, сломал голову в поиске причины...

59

Re: AHK: Break и Shift+Break как в пунто свитчере

В IE работает, в FF — нет.

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

60

Re: AHK: Break и Shift+Break как в пунто свитчере

creature.ws пишет:

Немного оффтопика:
После включения обсуждаемого скрипта в мой основной перестали срабатывать хоткеи вида:

vkA5 & vk20::SendInput % GetKeyState("Shift","P") ? Chr(0x200B) : Chr(0x00A0)

Признаться, сломал голову в поиске причины...

А что за символы Chr(0x200B) и Chr(0x00A0)? У меня такой код не работает ни в ANSI, ни в Unicode версии.

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

61 (изменено: Alectric, 2011-11-03 22:35:52)

Re: AHK: Break и Shift+Break как в пунто свитчере

Нажимай с зажатым шифтом, вместо символа знак вопроса появится.
Судя по хекс редактору отправляется 3F с шифтом и A0 без.

У меня работает в одном скрипте с обсуждаемым.

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

62 (изменено: creature.ws, 2011-11-03 22:44:51)

Re: AHK: Break и Shift+Break как в пунто свитчере

teadrinker пишет:

А что за символы Chr(0x200B) и Chr(0x00A0)? У меня такой код не работает ни в ANSI, ни в Unicode версии.

Chr(0x200B) - ZERO-WIDTH SPACE
Chr(0x00A0) - неразрывный пробел

Возможно пример неудачный
Использую подобие раскладки Бирмана:


; фрагмент
vkA5 & vkBC::SendInput % (GetKeyState("Shift", "P")) ? Chr(0xAB) : Chr(60)  ;< or <<
vkA5 & vkBE::SendInput % (GetKeyState("Shift", "P")) ? Chr(0xBB) : Chr(62)  ;>  or >>
vkA5 & vkDC::SendInput % (GetKeyState("Shift", "P")) ? Chr(0xA6) : Chr(124) ;|
vkA5 & vkBF::SendInput % (GetKeyState("Shift", "P")) ? Chr(191) : Chr(0x2026) ; ? or ...
vkA5 & vkBD::SendInput % (GetKeyState("Shift", "P")) ? Chr(0x2212) : Chr(0x2014) ; -
vkA5 & vkBB::SendInput % (GetKeyState("Shift", "P")) ? Chr(0xB1) : Chr(0x2260) ;± or notequal
vkA5 & vk20::SendInput % (GetKeyState("Shift", "P")) ? Chr(0x200B) : Chr(0xA0) ; space
; и т.д.

63

Re: AHK: Break и Shift+Break как в пунто свитчере

У меня работает это, если добавить в конец кода:

vkA5 & vkBC::SendInput % (GetKeyState("Shift", "P")) ? Chr(0xAB) : Chr(60)  ;< or <<

Какой вариант скрипта используешь?

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

64

Re: AHK: Break и Shift+Break как в пунто свитчере

Александр_ пишет:

и алгоритм я бы иной выбрал .

Да, алгоритм конвертации можно подсократить, я слегка перемудрил.

SetBatchLines, -1
SetKeyDelay, 0

F11::
   Critical
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   ClipWait, 0

   SelText := ErrorLevel ? GetWord() : Clipboard
   pResult := ConvertText(SelText)

   Clipboard := StrGet(pResult + 4)
   SendInput, ^{vk56}

   Sleep, 200
   Clipboard := TempClipboard
   TempClipboard := SelText := ""

   SwitchLocale(NumGet(pResult+0))
   Return

GetWord()
{
   While A_Index < 100
   {
      Clipboard =
      SendInput, +{Left}
      SendInput, ^{vk43}
      ClipWait, 0
      if ErrorLevel
         Return

      Len := StrLen(Clipboard)
      if (Len = PrevLen)
         Return Clipboard

      PrevLen := Len
      s := SubStr(Clipboard, 1, 1)
      if s in %A_Space%,%A_Tab%,`n,`r
      {
         SendInput, +{Right}
         s := SubStr(Clipboard, 1, 2)
         Return SubStr(ClipBoard, RegExMatch(s, "[\n\r]{2}") ? 3 : 2)
      }
   }
}

ConvertText(Text)
{
   static Result

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

   Loop, parse, Text
   {
      found =
      if found := InStr(Lat, A_LoopField, 1)
         NewText .= SubStr(Cyr, found, 1), lastfound := 2

      if !found
         if found := InStr(Cyr, A_LoopField, 1)
            NewText .= SubStr(Lat, found, 1), lastfound := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, 4 + StrPut(NewText))
   NumPut(lastfound, Result), StrPut(NewText, &Result + 4)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, 4), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 1 ? En : Ru,, A
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

65 (изменено: creature.ws, 2011-11-04 08:56:28)

Re: AHK: Break и Shift+Break как в пунто свитчере

Вопрос-оффтопик закрыт, скрипт конвертер в нестандартном поведении хоткеев не замешан.

Дело было в хитром взаимодействии скомпилированной «старой» ANSI-версии конвертера со скриптом запущенным в AHK_L обеспечивавшем работу хоткеев вида

vkA5 & vkBC::SendInput % (GetKeyState("Shift", "P")) ? Chr(0xAB) : Chr(60)  ;< or <<

Замена  SendInput на Send восстановила функции хоткеев.

66 (изменено: creature.ws, 2011-11-05 01:09:16)

Re: AHK: Break и Shift+Break как в пунто свитчере

Странно, но при попытке перекодирования текста > 40 символов происходит стабильное падение AHK

Faulting application name: AutoHotkey.exe, version: 1.1.5.1, time stamp: 0x4e9a4220
Faulting module name: AutoHotkey.exe, version: 1.1.5.1, time stamp: 0x4e9a4220
Exception code: 0xc0000005
Fault offset: 0x00000000000cdfb9

Win7 x64, ahk_l x64 unicode

//add
А иногда в конец перекодированной фразы добавляется некое число вида: 3636176096

67

Re: AHK: Break и Shift+Break как в пунто свитчере

Так попробуй:

SetBatchLines, -1
SetKeyDelay, 0

F11::
   Critical
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   ClipWait, 0

   SelText := ErrorLevel ? GetWord() : Clipboard
   pResult := ConvertText(SelText)

   Clipboard := StrGet(pResult + A_PtrSize)
   SendInput, ^{vk56}

   Sleep, 200
   Clipboard := TempClipboard
   TempClipboard := SelText := ""
   SwitchLocale(NumGet(pResult+0))
   Return

GetWord()
{
   While A_Index < 100
   {
      Clipboard =
      SendInput, +{Left}
      SendInput, ^{vk43}
      ClipWait, 0
      if ErrorLevel
         Return

      Len := StrLen(Clipboard)
      if (Len = PrevLen)
         Return Clipboard

      PrevLen := Len
      s := SubStr(Clipboard, 1, 1)
      if s in %A_Space%,%A_Tab%,`n,`r
      {
         SendInput, +{Right}
         s := SubStr(Clipboard, 1, 2)
         Return SubStr(ClipBoard, RegExMatch(s, "[\n\r]{2}") ? 3 : 2)
      }
   }
}

ConvertText(Text)
{
   static Result

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

   Loop, parse, Text
   {
      found =
      if found := InStr(Lat, A_LoopField, 1)
         NewText .= SubStr(Cyr, found, 1), lastfound := 2

      if !found
         if found := InStr(Cyr, A_LoopField, 1)
            NewText .= SubStr(Lat, found, 1), lastfound := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, A_PtrSize + StrPut(NewText))
   NumPut(lastfound, &Result), StrPut(NewText, &Result + A_PtrSize)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, 4), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 1 ? En : Ru,, A
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

68

Re: AHK: Break и Shift+Break как в пунто свитчере

Попробовал, явных изменений не заметил

Faulting application name: AutoHotkey.exe, version: 1.1.5.1, time stamp: 0x4e9a4220
Faulting module name: ntdll.dll, version: 6.1.7601.17514, time stamp: 0x4ce7c8f9
Exception code: 0xc0000374
Fault offset: 0x00000000000c40f2

69

Re: AHK: Break и Shift+Break как в пунто свитчере

А текст где написан? Выделял ли перед конвертацией?

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

70 (изменено: creature.ws, 2011-11-05 01:36:42)

Re: AHK: Break и Shift+Break как в пунто свитчере

Текст написан во всех доступных EditBox'ах, winword, akelpad, firefox etc.
Да, текст выделяется перед конвертацией, GetWord() не используется.
Вот образец: (в этом виде и используется)

SetBatchLines, -1
SetKeyDelay, 0

CapsLock::
!Capslock::
+CapsLock::

  KeyWait, CapsLock
  
  If (A_ThisHotkey = "CapsLock") {
    SendInput {LAlt Down}{Shift Down}{LAlt Up}{Shift Up}
    Sleep 50
    ToolTip, % InputLayout(), % A_CaretX + 10, % A_CaretY - 20
    SetTimer,REMOVE_TOOLTIP, 500
    Return
    }
  if (A_ThisHotkey = "!Capslock" )
    SendInput {Shift Down}{Home}{Shift Up}

  Critical
  TempClipboard := ClipboardAll
  Clipboard =
  SendInput, ^{vk43}
  ClipWait, 0
  If (ErrorLevel)
    Return
  SelText := Clipboard
  pResult := ConvertText(SelText)
  Clipboard := StrGet(pResult + A_PtrSize)
  SendInput, ^{vk56}
  Sleep, 200
  Clipboard := TempClipboard
  TempClipboard := SelText := ""
  SwitchLocale(NumGet(pResult+0))
  Critical, Off
  Sleep 50
  ToolTip, % InputLayout(), % A_CaretX + 10, % A_CaretY - 20
  SetTimer,REMOVE_TOOLTIP, 500
Return

REMOVE_TOOLTIP:
  SetTimer,REMOVE_TOOLTIP,off
  ToolTip
Return

InputLayout() {
  SetFormat, Integer, H
  WinGet, WinID,, A
  ThreadID:=DllCall("GetWindowThreadProcessId", "Int", WinID, "Int", "0")
  HKL:=DllCall("GetKeyboardLayout", "uint", ThreadID, "uint")
  VarSetCapacity( sKbd, 260, 0 )
  DllCall("GetLocaleInfo","uint",HKL>>16,"uint",0x1001, "str",sKbd, "uint",260)
  Return %sKbd%
}

ConvertText(Text)
{
   static Result

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

   Loop, parse, Text
   {
      found =
      if found := InStr(Lat, A_LoopField, 1)
         NewText .= SubStr(Cyr, found, 1), lastfound := 2

      if !found
         if found := InStr(Cyr, A_LoopField, 1)
            NewText .= SubStr(Lat, found, 1), lastfound := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, A_PtrSize + StrPut(NewText))
   NumPut(lastfound, &Result), StrPut(NewText, &Result + 4)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, 4), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 1 ? En : Ru,, A
}

71

Re: AHK: Break и Shift+Break как в пунто свитчере

Не, это я вначале не совсем правильно написал, теперь исправлено.
Там вместо

NumPut(lastfound, &Result), StrPut(NewText, &Result + 4)

теперь

NumPut(lastfound, &Result), StrPut(NewText, &Result + A_PtrSize)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

72

Re: AHK: Break и Shift+Break как в пунто свитчере

Исправлено, падает.

SetBatchLines, -1
SetKeyDelay, 0

CapsLock::
!Capslock::
+CapsLock::

  KeyWait, CapsLock
  
  If (A_ThisHotkey = "CapsLock") {
    SendInput {LAlt Down}{Shift Down}{LAlt Up}{Shift Up}
    Sleep 50
    ToolTip, % InputLayout(), % A_CaretX + 10, % A_CaretY - 20
    SetTimer,REMOVE_TOOLTIP, 500
    Return
    }
  if (A_ThisHotkey = "!Capslock" )
    SendInput {Shift Down}{Home}{Shift Up}

  Critical
  TempClipboard := ClipboardAll
  Clipboard =
  SendInput, ^{vk43}
  ClipWait, 0
  If (ErrorLevel)
    Return
  SelText := Clipboard
  pResult := ConvertText(SelText)
  Clipboard := StrGet(pResult + A_PtrSize)
  SendInput, ^{vk56}
  Sleep, 200
  Clipboard := TempClipboard
  TempClipboard := SelText := ""
  SwitchLocale(NumGet(pResult+0))
  Critical, Off
  Sleep 50
  ToolTip, % InputLayout(), % A_CaretX + 10, % A_CaretY - 20
  SetTimer,REMOVE_TOOLTIP, 500
Return

REMOVE_TOOLTIP:
  SetTimer,REMOVE_TOOLTIP,off
  ToolTip
return

InputLayout() {
  SetFormat, Integer, H
  WinGet, WinID,, A
  ThreadID:=DllCall("GetWindowThreadProcessId", "Int", WinID, "Int", "0")
  HKL:=DllCall("GetKeyboardLayout", "uint", ThreadID, "uint")
  VarSetCapacity( sKbd, 260, 0 )
  DllCall("GetLocaleInfo","uint",HKL>>16,"uint",0x1001, "str",sKbd, "uint",260)
  Return %sKbd%
}

ConvertText(Text)
{
   static Result

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

   Loop, parse, Text
   {
      found =
      if found := InStr(Lat, A_LoopField, 1)
         NewText .= SubStr(Cyr, found, 1), lastfound := 2

      if !found
         if found := InStr(Cyr, A_LoopField, 1)
            NewText .= SubStr(Lat, found, 1), lastfound := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, A_PtrSize + StrPut(NewText))
   NumPut(lastfound, &Result), StrPut(NewText, &Result + A_PtrSize)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, 4), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 1 ? En : Ru,, A
}

73

Re: AHK: Break и Shift+Break как в пунто свитчере

Попробуй исправить строчку

VarSetCapacity(Result, A_PtrSize + StrPut(NewText))

на

VarSetCapacity(Result, A_PtrSize + StrPut(NewText)*2)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

74

Re: AHK: Break и Shift+Break как в пунто свитчере

А так не падает Большое спасибо!

Для отчётности:

SetBatchLines, -1
SetKeyDelay, 0

CapsLock::
!Capslock::
+CapsLock::

  KeyWait, CapsLock
  
  If (A_ThisHotkey = "CapsLock") {
    SendInput {LAlt Down}{Shift Down}{LAlt Up}{Shift Up}
    Sleep 50
    ToolTip, % InputLayout(), % A_CaretX + 10, % A_CaretY - 20
    SetTimer,REMOVE_TOOLTIP, 500
    Return
    }
  if (A_ThisHotkey = "!Capslock" )
    SendInput {Shift Down}{Home}{Shift Up}

  Critical
  TempClipboard := ClipboardAll
  Clipboard =
  SendInput, ^{vk43}
  ClipWait, 0
  If (ErrorLevel)
    Return
  SelText := Clipboard
  pResult := ConvertText(SelText)
  Clipboard := StrGet(pResult + A_PtrSize)
  SendInput, ^{vk56}
  Sleep, 200
  Clipboard := TempClipboard
  TempClipboard := SelText := ""
  SwitchLocale(NumGet(pResult+0))
  Critical, Off
  Sleep 50
  ToolTip, % InputLayout(), % A_CaretX + 10, % A_CaretY - 20
  SetTimer,REMOVE_TOOLTIP, 500
Return

REMOVE_TOOLTIP:
  SetTimer,REMOVE_TOOLTIP,off
  ToolTip
return

InputLayout() {
  SetFormat, Integer, H
  WinGet, WinID,, A
  ThreadID:=DllCall("GetWindowThreadProcessId", "Int", WinID, "Int", "0")
  HKL:=DllCall("GetKeyboardLayout", "uint", ThreadID, "uint")
  VarSetCapacity( sKbd, 260, 0 )
  DllCall("GetLocaleInfo","uint",HKL>>16,"uint",0x1001, "str",sKbd, "uint",260)
  Return %sKbd%
}

ConvertText(Text)
{
   static Result

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

   Loop, parse, Text
   {
      found =
      if found := InStr(Lat, A_LoopField, 1)
         NewText .= SubStr(Cyr, found, 1), lastfound := 2

      if !found
         if found := InStr(Cyr, A_LoopField, 1)
            NewText .= SubStr(Lat, found, 1), lastfound := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, A_PtrSize + StrPut(NewText)*2)
   NumPut(lastfound, &Result), StrPut(NewText, &Result + A_PtrSize)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, 4), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 1 ? En : Ru,, A
}

75

Re: AHK: Break и Shift+Break как в пунто свитчере

Да, мой недосмотр. В Unicode версии для строки требуется больший буфер.

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

76

Re: AHK: Break и Shift+Break как в пунто свитчере

Более универсальный вариант

VarSetCapacity(Result, A_PtrSize + StrPut(NewText)*(A_IsUnicode ? 2 : 1)
SetBatchLines, -1
SetKeyDelay, 0

F11::
   Critical
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   ClipWait, 0

   SelText := ErrorLevel ? GetWord() : Clipboard
   pResult := ConvertText(SelText)

   Clipboard := StrGet(pResult + A_PtrSize)
   SendInput, ^{vk56}

   Sleep, 200
   Clipboard := TempClipboard
   TempClipboard := SelText := ""
   SwitchLocale(NumGet(pResult+0))
   Return

GetWord()
{
   While A_Index < 100
   {
      Clipboard =
      SendInput, +{Left}
      SendInput, ^{vk43}
      ClipWait, 0
      if ErrorLevel
         Return

      Len := StrLen(Clipboard)
      if (Len = PrevLen)
         Return Clipboard

      PrevLen := Len
      s := SubStr(Clipboard, 1, 1)
      if s in %A_Space%,%A_Tab%,`n,`r
      {
         SendInput, +{Right}
         s := SubStr(Clipboard, 1, 2)
         Return SubStr(ClipBoard, RegExMatch(s, "[\n\r]{2}") ? 3 : 2)
      }
   }
}

ConvertText(Text)
{
   static Result

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

   Loop, parse, Text
   {
      found =
      if found := InStr(Lat, A_LoopField, 1)
         NewText .= SubStr(Cyr, found, 1), lastfound := 2

      if !found
         if found := InStr(Cyr, A_LoopField, 1)
            NewText .= SubStr(Lat, found, 1), lastfound := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, A_PtrSize + StrPut(NewText)*(A_IsUnicode ? 2 : 1))
   NumPut(lastfound, &Result), StrPut(NewText, &Result + A_PtrSize)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, 4), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 1 ? En : Ru,, A
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

77

Re: AHK: Break и Shift+Break как в пунто свитчере

Более интеллектуальный поиск последнего слова, быстрее:

SetBatchLines, -1
SetKeyDelay, 0

F11::
   Critical
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   ClipWait, 0

   SelText := ErrorLevel ? GetWord() : Clipboard
   pResult := ConvertText(SelText)

   Clipboard := StrGet(pResult + A_PtrSize)
   SendInput, ^{vk56}

   Sleep, 200
   SwitchLocale(NumGet(pResult+0))
   Sleep, 200
   Clipboard := TempClipboard
   TempClipboard := SelText := ""
   Return

GetWord()
{
   While A_Index < 10
   {
      Clipboard =
      SendInput, ^+{Left}^{vk43}
      ClipWait, 1
      if ErrorLevel
         Return

      if RegExMatch(Clipboard, "P).*([ \t])", Found)
      {
         SendInput, ^+{Right}
         Return SubStr(Clipboard, FoundPos1 + 1)
      }

      PrevClipboard := Clipboard
      Clipboard =
      SendInput, +{Left}^{vk43}
      ClipWait, 1
      if ErrorLevel
         Return

      if (StrLen(Clipboard) = StrLen(PrevClipboard))
      {
         Clipboard =
         SendInput, +{Left}^{vk43}
         ClipWait, 1
         if ErrorLevel
            Return

         if (StrLen(Clipboard) = StrLen(PrevClipboard))
            Return Clipboard
         Else
         {
            SendInput, +{Right 2}
            Return PrevClipboard
         }
      }

      SendInput, +{Right}

      s := SubStr(Clipboard, 1, 1)
      if s in %A_Space%,%A_Tab%,`n,`r
      {
         Clipboard =
         SendInput, +{Left}^{vk43}
         ClipWait, 1
         if ErrorLevel
            Return

         Return Clipboard
      }
   }
}

ConvertText(Text)
{
   static Result

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

   Loop, parse, Text
   {
      found =
      if found := InStr(Lat, A_LoopField, 1)
         NewText .= SubStr(Cyr, found, 1), lastfound := 2

      if !found
         if found := InStr(Cyr, A_LoopField, 1)
            NewText .= SubStr(Lat, found, 1), lastfound := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, A_PtrSize + StrPut(NewText)*(A_IsUnicode ? 2 : 1))
   NumPut(lastfound, &Result), StrPut(NewText, &Result + A_PtrSize)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, 8)
   DllCall("GetKeyboardLayoutList", Int, 2, UInt, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, 4), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 1 ? En : Ru,, A
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

78

Re: AHK: Break и Shift+Break как в пунто свитчере

Спасибо! Отлично работает!

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

79

Re: AHK: Break и Shift+Break как в пунто свитчере

А в коллекции аналога нет

80

Re: AHK: Break и Shift+Break как в пунто свитчере

Да, надо бы добавить, как руки дойдут!

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

81

Re: AHK: Break и Shift+Break как в пунто свитчере

Исправленный вариант для правильного переключения раскладки при использовании AHK_L x64, по Shift + Break:

+Break::SwitchKeysLocale()

SwitchKeysLocale()
{
   Critical

   SetBatchLines, -1
   SetKeyDelay, 0

   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}   ; Ctrl + C
   ClipWait, 0
; если буфер обмена пуст (ничего не выделено), определяем и выделяем
; с помощью ф-ции GetWord() последнее слово слева от курсора
   SelText := ErrorLevel ? GetWord() : Clipboard
   pResult := ConvertText(SelText)   ; получаем конвертированный текст и раскладку последней найденной буквы

   Clipboard := StrGet(pResult + A_PtrSize)
   SendInput, ^{vk56}
; переключаем раскладку клавиатуры в зависимости от раскладки последней найденной буквы
   Sleep, 200
   SwitchLocale(NumGet(pResult+0, "UInt"))
   Sleep, 200
   Clipboard := TempClipboard
}

GetWord()
{
   While A_Index < 10
   {
      Clipboard =
      SendInput, ^+{Left}^{vk43}
      ClipWait, 1
      if ErrorLevel
         Return

      if RegExMatch(Clipboard, "P).*([ \t])", Found)
      {
         SendInput, ^+{Right}
         Return SubStr(Clipboard, FoundPos1 + 1)
      }

      PrevClipboard := Clipboard
      Clipboard =
      SendInput, +{Left}^{vk43}
      ClipWait, 1
      if ErrorLevel
         Return

      if (StrLen(Clipboard) = StrLen(PrevClipboard))
      {
         Clipboard =
         SendInput, +{Left}^{vk43}
         ClipWait, 1
         if ErrorLevel
            Return

         if (StrLen(Clipboard) = StrLen(PrevClipboard))
            Return Clipboard
         Else
         {
            SendInput, +{Right 2}
            Return PrevClipboard
         }
      }

      SendInput, +{Right}

      s := SubStr(Clipboard, 1, 1)
      if s in %A_Space%,%A_Tab%,`n,`r
      {
         Clipboard =
         SendInput, +{Left}^{vk43}
         ClipWait, 1
         if ErrorLevel
            Return

         Return Clipboard
      }
   }
}

ConvertText(Text)
{
   static Result

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

   Loop, parse, Text
   {
      found =
      if found := InStr(Lat, A_LoopField, 1)
         NewText .= SubStr(Cyr, found, 1), lastfound := 2

      if !found
         if found := InStr(Cyr, A_LoopField, 1)
            NewText .= SubStr(Lat, found, 1), lastfound := 1

      if !found
         NewText .= A_LoopField
   }
   VarSetCapacity(Result, A_PtrSize + StrPut(NewText)*(A_IsUnicode ? 2 : 1))
   NumPut(lastfound, &Result), StrPut(NewText, &Result + A_PtrSize)
   Return &Result
}

SwitchLocale(lastfound)
{
   SetFormat, IntegerFast, H
   VarSetCapacity(List, A_PtrSize*2)
   DllCall("GetKeyboardLayoutList", Int, 2, Ptr, &List)
   Locale1 := NumGet(List)
   b := SubStr(Locale2 := NumGet(List, A_PtrSize), -3) = 0409
   En := b ? Locale2 : Locale1
   Ru := b ? Locale1 : Locale2
   SendMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, lastfound = 1 ? En : Ru,, A
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

82

Re: AHK: Break и Shift+Break как в пунто свитчере

Никто не делал чтоб сразу при наборе автоматически конвертировались слова, как в пунте свитчере?

83 (изменено: creature.ws, 2012-09-30 21:44:07)

Re: AHK: Break и Shift+Break как в пунто свитчере

Найдите словарик распространённых русских слов, конвертируйте содержимое в «английскую раскладку», создайте скрипт с множеством строк автозамены полученных «неправильных» слов на «правильные» слова из того же словаря.

Например:

::{fvbnt::Хамите
::{j-{j::Хо-хо
::Pyfvtybnj::Знаменито
::Vhfxysq::Мрачный
::Vhfr::Мрак
:::enm::Жуть
::Gfhybif::Парниша
::Yt exbnt vtyz `;bnm::Не учите меня жить
::Rfr ht,``yrf::Как ребёнка
::Rhfcjnf::Красота
::Njkcnsq b rhfcbdsq::Толстый и красивый
::Gjtltv yf bpdjpxbrt::Поедем на извозчике
::Gjtltv yf nfrcj::Поедем на таксо
::E dfc dcz cgbyf ,tkfz::У вас вся спина белая
::Gjlevftim::Подумаешь
::Juj::Ого

84 (изменено: Irbis, 2012-09-30 22:10:52)

Re: AHK: Break и Shift+Break как в пунто свитчере

Что-то мне подсказывает, что создатели Punto использовали другой подход. Не есть истина в последней инстанции, но рассуждения здравые.

85 (изменено: creature.ws, 2012-10-01 00:28:29)

Re: AHK: Break и Shift+Break как в пунто свитчере

По словарику надёжнее, нелепых словосочетаний позволяет избежать, частых для пользователей Рuntо Swіtсhеr.
А вообще —

#NoEnv

loop {
    Input, word, vi, {space}
    if !IsValidWord(word)
        SendInput % GetRawBS(StrLen(word)+1) . GetValidWord(word) . " "
}

IsValidWord(word)
{
    return false ; вот здесь то и разместить алгоритм определяющий какому языку принадлежит слово, введеное до нажатия пробела
}

GetRawBS(length)
{
    loop %length%
        str .= "`b"
    return str
}

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

    loop, parse, word
    {
        if found := InStr(char1, A_loopField, 1)
            temp .= SubStr(char0, found, 1), lastFound := 1

        else if found := InStr(char0, A_loopField, 1)
            temp .= SubStr(char1, found, 1), lastFound := 0

        else if found := InStr(symb%lastFound%, A_loopField, 1)
            lastFound_invert := !lastFound, temp .= SubStr(symb%lastFound_invert%, found, 1)

        else temp .= A_loopField
    }

    return temp
}

86

Re: AHK: Break и Shift+Break как в пунто свитчере

teadrinker пишет:

Исправленный вариант для правильного переключения раскладки при использовании AHK_L x64, по Shift + Break:

Неприятные баги:
- если перед курсором стоит пробел (например, " ghbdtn "), то последнее слово не конвертируется, а курсор может сдвинуться на одну позицию вправо.
- если курсор стоит вначале строки и запустить конвертирование, то текущая строка поднимается на вверх.

Просьба, если не затруднит, посмотреть работу скрипта в редакторе FAR Manage. Там похожие глюки.

87

Re: AHK: Break и Shift+Break как в пунто свитчере

creature.ws пишет:

По словарику надёжнее, нелепых словосочетаний позволяет избежать, частых для пользователей Рuntо Swіtсhеr.

Это немножко не то. В пунте можно вслепую набирать, не обращая внимания на раскладку. Пунта сама исправит слова в нужную кодировку. Хотелось бы также

88

Re: AHK: Break и Shift+Break как в пунто свитчере

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

Естественно, это разные «подходы», преимуществ в использовании некого алгоритма определяющего «правильность» слова я не вижу, если учесть количество ошибок конвертации слов разговорной речи в сообщениях набранных вслепую пользователями «Згтещ Switcher», используемый приложением алгоритм, мягко говоря, несовершенен.

89

Re: AHK: Break и Shift+Break как в пунто свитчере

creature.ws пишет:

преимуществ в использовании некого алгоритма определяющего «правильность» слова я не вижу, если учесть количество ошибок конвертации слов разговорной речи в сообщениях набранных вслепую пользователями «Згтещ Switcher»,

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

90

Re: AHK: Break и Shift+Break как в пунто свитчере

Reihe пишет:

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

Для меня сие приложение оказалось сугубо вредительским. Может и срабатывает как надо, но этого не заметно, да и сама проблема для меня не так уж актуальна, но вот подлянку обязательно подкинет в самый неподходящий момент, например когда волей случая начало цифро-буквенного кода (в смысле пароля и т.п., а не скрипта и т.п.) абсурдно с точки зрения английского языка, но в "русском" варианте имеет смысл. Так что спорить на эту тему, видимо, бессмысленно, ибо приемлемость данного продукта для каждого своя.

BIG BROTHER IS WATCHING YOU.

91

Re: AHK: Break и Shift+Break как в пунто свитчере

А каким образом последние посты в теме соотносятся с её названием, или хотя бы вообще с АНК?
Пофлудить на тему плюсов и минусов некой программы - так такой цели не преследовалось, насколько я понимаю.

92

Re: AHK: Break и Shift+Break как в пунто свитчере

Reihe пишет:

- если перед курсором стоит пробел (например, " ghbdtn "), то последнее слово не конвертируется

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

Спасибо

93

Re: AHK: Break и Shift+Break как в пунто свитчере

vadim1sh пишет:

здорово это подрихтовать, если не слишком проблематично.

Ctrl+Shift+Left и горячая клавиша.

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

94 (изменено: serzh82saratov, 2014-05-01 09:36:35)

Re: AHK: Break и Shift+Break как в пунто свитчере

Новая версия. Добавлено переключение регистра выделенного текста или последнего слова слева от каретки (введённого с ошибочно включенным CapsLock).Новая версия. Добавлено переключение регистра выделенного текста или последнего слова слева от каретки (введённого с ошибочно включенным CapsLock).

Отлично! Давно пора, Я вот по многу раз в день эту кнопочку жму.

Добавлено переключение регистра

В качестве однострочно\односложного бреда:


ConvertRegistr(text)  {
    Static sym := "ёйцукенгшщзхъфывапролджэячсмитьбюqwertyuiopasdfghjklzxcvbnm       "
        . "ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM       " 
    Loop, parse, text
        res.=(p:=InStr(sym,A_LoopField,1)) ? SubStr(sym,p-66,1) : A_LoopField
   Return res
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

95

Re: AHK: Break и Shift+Break как в пунто свитчере

Я тоже, честно говоря, думал, что проще создать массив (или строку) символов, чем рассчитывать Asc-коды. Ну ладно уж, тот вариант вроде нормально работает. А краткость записи — не всегда плюс, потом поменять что-то нужно будет — фиг разберёшься, что там когда-то наколдовал.

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

96

Re: AHK: Break и Shift+Break как в пунто свитчере

Вариантов много, а в пищу надо употребить один. Думаю что всё таки в варианте с Asc, производительность должна быть более оптимальной. Ведь идёт простое сравнение чисел в 5 диапазонах. А InStr видимо проверяет на соответствие каждый символ, хотя конечно, кто его знает.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

97 (изменено: serzh82saratov, 2014-05-01 12:49:08)

Re: AHK: Break и Shift+Break как в пунто свитчере

Всё таки наверное лучше со строкой, тем более что в ConvertText также, будет как то гармоничнее смотрется что ли. Я упростил ConvertRegistr:

SubStr(sym,p-66,1)

вчера тут было бредовое условие. Уж очень по-моему симпатично смотрится в контексте:


ConvertRegistr(Text)  {
    Static Chars := "ёйцукенгшщзхъфывапролджэячсмитьбю.......qwertyuiopasdfghjklzxcvbnm"
                . "ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ.......QWERTYUIOPASDFGHJKLZXCVBNM" 

    Loop, parse, Text
        NewText .= (found := InStr(Chars, A_LoopField, 1)) 
                ? SubStr(Chars, found - 66, 1) : A_LoopField
   Return NewText
}

Раз уж руки дошли причесать код.
Не совсем ясно наличие в ConvertText:

static Result

Не ясна необходимость каждо разового объявления переменных Lat Cyr.
Также зависимость количества LatCount и CyrCount в Text, от символов (не букв) содержащихся в Lat Cyr.
Не понятны танцы вокруг передачи OppositeLayout в SwitchKeysLocale.
В Lat Cyr добавил по паре символов в конец.
Предлагаю так:


ConvertText(Text, ByRef OppositeLayout)
{  
    Static Cyr := "ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮёйцукенгшщзхъфывапролджэячсмитьбю,.""№;?"
        , Lat := "~QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>``qwertyuiop[]asdfghjkl;'zxcvbnm,.?/@#$&"  
   
    RegExReplace(Text, "i)[A-Z]", "", LatCount)
    RegExReplace(Text, "i)[А-ЯЁ]", "", CyrCount)
    CurrentLayout := LatCount > CyrCount ? "Lat" : "Cyr"
    OppositeLayout := LatCount > CyrCount ? "Cyr" : "Lat"
    
    Loop, parse, Text
        NewText .= (found := InStr(%CurrentLayout%, A_LoopField, 1)) 
                ? SubStr(%OppositeLayout%, found, 1) : A_LoopField
    Return NewText
}


SwitchKeysLocale()
{
   SelText := GetWord(TempClipboard) 
   Clipboard := ConvertText(SelText, Layout)
   SendInput, ^{vk56} 
   Sleep, 50
   SwitchLocale(Layout)
   Sleep, 50
   Clipboard := TempClipboard
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

98

Re: AHK: Break и Shift+Break как в пунто свитчере

serzh82saratov пишет:

Всё таки наверное лучше со строкой, тем более что в ConvertText также, будет как то гармоничнее смотрется что ли. Я упростил ConvertRegistr:

SubStr(sym,p-66,1)

вчера тут было бредовое условие. Уж очень по-моему симпатично смотрится в контексте:


ConvertRegistr(Text)  {
    Static Chars := "ёйцукенгшщзхъфывапролджэячсмитьбю.......qwertyuiopasdfghjklzxcvbnm"
                . "ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ.......QWERTYUIOPASDFGHJKLZXCVBNM" 

    Loop, parse, Text
        NewText .= (found := InStr(Chars, A_LoopField, 1)) 
                ? SubStr(Chars, found - 66, 1) : A_LoopField
   Return NewText
}

Изменить стоит, но не потому, что смотрится симпатичнее, а потому, что в ANSI-версии тот вариант не работает — там коды другие. Только не очень понятно наличие стольких точек в строках, зачем они?

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

99

Re: AHK: Break и Shift+Break как в пунто свитчере

serzh82saratov пишет:

Не совсем ясно наличие в ConvertText:

static Result

Не ясна необходимость каждо разового объявления переменных Lat Cyr.
Также зависимость количества LatCount и CyrCount в Text, от символов (не букв) содержащихся в Lat Cyr.
Не понятны танцы вокруг передачи OppositeLayout в SwitchKeysLocale.

Там сейчас отредактировано немного. У меня была такая мысль по поводу этого. Можно, конечно, для переключения раскладки ориентироваться на текущую, но если пользователь уже переключил раскладку? Далее, среди введённых символов могут встретиться такие, которые есть и в том, и в другом наборе, поэтому я решил ориентироваться на принадлежность большего числа введённых символов к тому или иному набору, пока этот вариант не подводил. static Result остался от прошлого варианта, удалю.

serzh82saratov пишет:

Предлагаю так:


ConvertText(Text, ByRef OppositeLayout)
{  
    Static Cyr := "ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮёйцукенгшщзхъфывапролджэячсмитьбю,.""№;?"
        , Lat := "~QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>``qwertyuiop[]asdfghjkl;'zxcvbnm,.?/@#$&"  
   
    RegExReplace(Text, "i)[A-Z]", "", LatCount)
    RegExReplace(Text, "i)[А-ЯЁ]", "", CyrCount)
    CurrentLayout := LatCount > CyrCount ? "Lat" : "Cyr"
    OppositeLayout := LatCount > CyrCount ? "Cyr" : "Lat"
    
    Loop, parse, Text
        NewText .= (found := InStr(%CurrentLayout%, A_LoopField, 1)) 
                ? SubStr(%OppositeLayout%, found, 1) : A_LoopField
    Return NewText
}

Символы добавлю, не заметил сразу. А вот RegExReplace() ничем не лучше, по-моему, перебора символов, вряд ли этот вариант лучше по производительности.

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

100

Re: AHK: Break и Shift+Break как в пунто свитчере

Да уж, анси пережиток прошлого.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui