1 (изменено: Drugoy, 2013-02-21 21:48:06)

Тема: AHK: Исправление набранного в неверной раскладке текста

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

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
StringCaseSense, On
#SingleInstance, Force
SetBatchLines, -1
SetKeyDelay, 10

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

$<^<+Space::
KeyWait LCtrl
KeyWait LShift
KeyWait Space
savedClip := Clipboard
Sleep 1
Send ^{vk41}^{vk43}
Sleep 1
Clipboard ~= "i)[a-z]" ? (layoutIn := en, layoutOut := ru) : (layoutIn := ru, layoutOut := en)
Loop, Parse, Clipboard
{
    IfNotInString, layoutIn, %A_LoopField%
        newChar := A_LoopField
    Else
        StringReplace, newChar, A_LoopField, %A_LoopField%, % SubStr(layoutOut, InStr(layoutIn, A_LoopField, True), 1), All
    outputStr .= newChar
}
Clipboard := outputStr
Sleep 1
Send ^{vk56}
Clipboard := savedClip
savedClip := outputStr := layoutIn := layoutOut := newChar := ""
Return

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

Во-вторых, прошу помощи в тестировании/отладке/улучшении скрипта: мне удобно использовать для работы скрипта хоткей LCtrl+LShift+Space, но т.к. он в дальнейшем посылает CTRL+A и CTRL+C для получения доступа к набранному тексту, то появился конфликт хоткеев (и триггер-хоткей и посылаемые скриптом нажатия клавиш содержат CTRL).

Вроде исправил, добавив $ (вроде должен помогать избежать параллельного [вернее, в ahk нет параллелизма, а есть псевдо-параллелизм, достигаемый добавлением команд в очередь] запуска хоткея) в хоткей, а также getkeystate проверки, которые заставляют скрипт дожидаться пока пользователь не отпустит все 3 кнопки.

Вроде глюк исчез, но т.к. скрипт работает с буфером обмена (который известен своей медленной работой) - в коде всё равно есть паузы, которые я правда попытался снизить.

Остался редкий глюк: если 20 раз подряд понажимать хоткей - некоторые разы получается так, что после вставки текста он оказывается всё ещё выделенным и потом почему-то срабатывает нажатие Space, который заменяет выделенный текст собой. CTRL+Z и повторное нажатие хоткеия в таком случае, конечно, спасёт, но лучше бы исправить этот глюк в коде (где паузы-то увеличить? не нашёл зависимости).


Есть ещё идея добавить в скрипт доп. хоткеи чтоб можно было выбирать какой кусок текста преобразовать: весь, 1 строку, или последнее слово.

2

Re: AHK: Исправление набранного в неверной раскладке текста

Смена раскладки написанного текста

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

3

Re: AHK: Исправление набранного в неверной раскладке текста

okay_face.jpg
но мне импонирует то, что мой код в >2.5 раза короче
Тему можно не сносить?
У вас в коде

   SendInput, ^{vk43}   ; Ctrl + C
   ClipWait, 0

Так вот я когда пробую с ClipWait - он иногда стопорится же если вдруг буфер успел быстро поменяться, до того, как наступила череда ClipWait.

4 (изменено: serzh82saratov, 2013-02-12 21:55:43)

Re: AHK: Исправление набранного в неверной раскладке текста

Нужная штука!
Часто неглядя печатаю, и всё через гуглю перевожу потом
Правда непонял как должен работать ваш код. Сделал под себя чтоб просто обвёл текст, нажал, и на его месте всё заменилось

+ открыть спойлер

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

1::
Clipboard =
Send, ^{vk43} ; Ctrl + C  
If Clipboard =
Return
savedClip := Clipboard
inputStr := Clipboard
inputStr ~= "i)[a-z]" ? (layoutIn := en, layoutOut := ru) : (layoutIn := ru, layoutOut := en)
outputStr := ""
Loop, Parse, inputStr
{
    IfNotInString, layoutIn, %A_LoopField%
        newChar := A_LoopField
    Else
        StringReplace, newChar, A_LoopField, %A_LoopField%, % SubStr(layoutOut, InStr(layoutIn, A_LoopField, True), 1), All                                                    ;% 
    outputStr .= newChar
}
Clipboard := outputStr
While !(Clipboard == outputStr)
    Sleep 10
Send, ^{vk56} ; Ctrl + V
Return

Подскажите нубу - что нужного я удалил, и чего лишнего оставил.
Заменил Send ^v на Send, ^{vk56} т.к. часто печаталось только "V".

Ещё заметил что "Ё" переводит в символ, а символ обратно в "Ё" нет, или это я что-то напортачил?

Хм. Все символы из английской раскладки не переводит.

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

5

Re: AHK: Исправление набранного в неверной раскладке текста

Drugoy пишет:

но мне импонирует то, что мой код в >2.5 раза короче

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

Drugoy пишет:

Так вот я когда пробую с ClipWait - он иногда стопорится же если вдруг буфер успел быстро поменяться, до того, как наступила череда ClipWait.

Не совсем понял, это вопрос? У меня, вроде, проблем не было.

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

6

Re: AHK: Исправление набранного в неверной раскладке текста

serzh82saratov пишет:

Правда непонял как должен работать ваш код.

Это к кому вопрос?

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

7

Re: AHK: Исправление набранного в неверной раскладке текста

teadrinker пишет:
serzh82saratov пишет:

Правда непонял как должен работать ваш код.

Это к кому вопрос?

К ТС, но если знаете ответ, то поделитесь.

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

8

Re: AHK: Исправление набранного в неверной раскладке текста

serzh82saratov пишет:

Хм. Все символы из английской раскладки не переводит.

teadrinker
А ваш код всё заменяет.

serzh82saratov пишет:

Сделал под себя чтоб просто обвёл текст, нажал, и на его месте всё заменилось

И переделывать не надо

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

9

Re: AHK: Исправление набранного в неверной раскладке текста

serzh82saratov пишет:

Правда непонял как должен работать ваш код.

он переводит весь введённый текст, т.е. посылает CTRL+A (выделить всё), CTRL+C, трансформирует текст, потом вставляет его через CTRL+V и восстанавливает исходное состояние буфера обмена.

10

Re: AHK: Исправление набранного в неверной раскладке текста

Значит я всё правильно понял, просто у меня оно не работало

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

11

Re: AHK: Исправление набранного в неверной раскладке текста

Drugoy пишет:

он переводит весь введённый текст

А если уже есть много правильно введённого текста?

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

12

Re: AHK: Исправление набранного в неверной раскладке текста

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

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

13

Re: AHK: Исправление набранного в неверной раскладке текста

teadrinker пишет:

А если уже есть много правильно введённого текста?

Присоединяюсь, это неудобно.
И замените CTRL+C и CTRL+V на коды, у меня скрипт 8 из 10 печатал по две буквы.
+ поправить траблу с символами.

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

14 (изменено: Alectric, 2013-02-13 20:45:17)

Re: AHK: Исправление набранного в неверной раскладке текста

Давно пользуюсь этим скриптом, отладил и оптимизировал его для медленных машин.
Break - последнее или выделенное слово.
Shift+Break - выделенное слово (надежней).
Ctrl - переключение раскладки.

Хоткеи можно поставить свои, незабудте поменять там где "a_thishotkey".


#SingleInstance,Force
AutoTrim,Off
CoordMode,Mouse,Screen
CoordMode,ToolTip
Menu,Tray,UseErrorLevel
SendMode,Input
SetBatchLines,-1
SetControlDelay,0
SetKeyDelay,0
SetTitleMatchMode,2
SetWinDelay,-1
SetWorkingDir,%A_ScriptDir%
StringCaseSense,On

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

+Break::
Break::
if work=0
  return
keywait,Break
if A_TimeSinceThisHotkey>200
  return
Critical
TempClipboard:=ClipboardAll
Clipboard=
NewText=
SelText=
if (a_thishotkey="+break")
{
  SendInput,^{vk43}
  ClipWait,1
  SelText:=Clipboard
}
else
{
  SendInput,^{vk43}
  sleep,1
  if Clipboard!=
    if Clipboard not contains `n,`r
      SelText:=Clipboard
  if SelText=
    loop,33
    {
      Clipboard=
      SendInput,{shift down}
      tooltip
      SendInput,{Left}
      tooltip
      SendInput,{shift up}
      tooltip
      loop,5
      {
        SendInput,^{vk43}
        ClipWait,0
        if clipboard!=
          break
      }
      if Clipboard=
        break
      Len:=StrLen(Clipboard)
      if (Len = PrevLen)
      {
        SelText:=Clipboard
        break
      }
      PrevLen:=Len
      swd:=SubStr(Clipboard,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(Clipboard,1,2)
        SelText:=SubStr(ClipBoard,RegExMatch(swd,"[\n\r]{2}") ? 3 : 2)
        break
      }
    }
}
Loop,parse,SelText
{
  found=
  if found:=InStr(Lat, A_LoopField, 1)
    NewText.=SubStr(Cyr, found, 1)
  if !found
    if found:=InStr(Cyr, A_LoopField, 1)
      NewText.=SubStr(Lat, found, 1)
  if !found
    NewText.=A_LoopField
}
Clipboard:=NewText
Sleep,1
SendInput,^{vk56}
Sleep,300
Clipboard:=TempClipboard
TempClipboard:=SelText:=
gosub,SwitchLocale
return

; //////////Переключение языка____________________________HOTKEYS_________________________
Ctrl::
if work=0
  return
keywait,ctrl,T0.2
if errorlevel=1
  return
SwitchLocale:
WinGet,ID,id,A
ThreadID:=DllCall("GetWindowThreadProcessId", UInt, ID, UInt, 0)
InputLocaledID:=DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)
if % InputLocaledID=Localed1
  SendMessage,0x50,0,%Localed2%,,ahk_id %ID%
else if % InputLocaledID=Localed2
  SendMessage,0x50,0,%Localed1%,,ahk_id %ID%
else
  SendMessage,0x50,0,%Localed2%,,ahk_id %ID%
MouseGetPos,x,y
InputLocaledID:=DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)
CoordMode,tooltip,Relative
if % InputLocaledID=Localed1
  ToolTip,Английский,A_CaretX+10,A_CaretY-20,3
else if % InputLocaledID=Localed2
  ToolTip,Русский,A_CaretX+10,A_CaretY-20,3
CoordMode,tooltip,Screen
SetTimer,RemoveToolTip,1000
return

RemoveToolTip:
SetTimer,RemoveToolTip,off
loop,20
  tooltip,,,,%A_index%
return

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

15 (изменено: Drugoy, 2013-02-22 15:15:35)

Re: AHK: Исправление набранного в неверной раскладке текста

Переделал свой скрипт так, что теперь есть не 1, а 5 разных хоткеев:
RCtrl+RShift+Space - конвертировать весь текст (работает через отправку Ctrl+A)
RShift+Space - конвертировать только всю строку (работает через отправку End, Shift+Home)
RCtrl+Space - конвертировать только (левую) часть строки: от начала строки до каретки (работает через отправку Shift+Home)
RCtrl+RAlt+Space - конвертировать только (правую) часть строки: от каретки до конца строки (работает через отправку Shift+End)
RAlt+Space - конвертировать только последнее слово (словом считается любая группа символов не содержащая пробел) [если в текстовом поле всего 1 строка из 1 слова, то скрипт "залипнет", чтобы он "отлип" надо нажать Esc]

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
StringCaseSense, On
#SingleInstance, Force
SetBatchLines, -1
SetKeyDelay, 10

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

; Transform all text
$>^>+Space::
KeyWait RCtrl
KeyWait RShift
KeyWait Space
savedClip := Clipboard
Sleep 1
Send ^{vk41}^{vk43}
Sleep 1
Clipboard := transformTextLayout(Clipboard)
Sleep 1
Send ^{vk56}
Clipboard := savedClip
savedClip := ""
Return

; Transform only last line (full line)
$>+Space::
KeyWait RShift
KeyWait Space
savedClip := Clipboard
Sleep 1
Send {End}+{Home}^{vk43}
Sleep 1
Clipboard := transformTextLayout(Clipboard)
Sleep 1
Send ^{vk56}
Clipboard := savedClip
savedClip := ""
Return

; Transform only (left) part of a line (from the beginning of the line to the caret)
$>^Space::
KeyWait RCtrl
KeyWait Space
savedClip := Clipboard
Sleep 1
Send +{Home}^{vk43}
Sleep 1
Clipboard := transformTextLayout(Clipboard)
Sleep 1
Send ^{vk56}
Clipboard := savedClip
savedClip := ""
Return

; Transform only (right) part of a line (from the beginning of the line to the caret)
$>^>!Space::
KeyWait RCtrl
KeyWait RAlt
KeyWait Space
savedClip := Clipboard
Sleep 1
Send +{End}^{vk43}
Sleep 1
Clipboard := transformTextLayout(Clipboard)
Sleep 1
Send ^{vk56}
Clipboard := savedClip
savedClip := ""
Return

; Transform only last word
$>!Space::
KeyWait RAlt
KeyWait Space
savedClip := Clipboard
Sleep 1
Loop
{
    If GetKeyState("Esc", "P")
        Exit
    Send ^+{Left}
    If A_LoopField = 1
        Continue
    Else
        Send ^{vk43}
    Sleep 1
    IfInString, Clipboard, %A_Space%
    {
        Send ^+{Right}^{vk43}
        Sleep 1
        Break
    }
}
Clipboard := transformTextLayout(Clipboard)
Sleep 1
Send ^{vk56}
Clipboard := savedClip
savedClip := ""
Return

transformTextLayout(textContainer)
{
    Global en, ru
    textContainer ~= "i)[a-z]" ? (layoutIn := en, layoutOut := ru) : (layoutIn := ru, layoutOut := en)
    Loop, Parse, textContainer
    {
        IfNotInString, layoutIn, %A_LoopField%
            newChar := A_LoopField
        Else
            StringReplace, newChar, A_LoopField, %A_LoopField%, % SubStr(layoutOut, InStr(layoutIn, A_LoopField, True), 1)
        outputStr .= newChar
    }
    textContainer := outputStr
    outputStr := layoutIn := layoutOut := newChar := ""
    Return textContainer
}

Т.к. я заметил, что при печатании текста я использую только левые shift/alt/ctrl, то все хоткеи с этими клавишами были намерено переделаны под правые shift/alt/ctrl во избежание случайных срабатываний (да, заметил, что они у меня случались).

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

Gosub, SwitchLocale

а куда-то в конец скрипта добавить

SwitchLocale:
WinGet,ID,id,A
ThreadID:=DllCall("GetWindowThreadProcessId", UInt, ID, UInt, 0)
InputLocaledID:=DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)
if % InputLocaledID=Localed1
  SendMessage,0x50,0,%Localed2%,,ahk_id %ID%
else if % InputLocaledID=Localed2
  SendMessage,0x50,0,%Localed1%,,ahk_id %ID%
else
  SendMessage,0x50,0,%Localed2%,,ahk_id %ID%
MouseGetPos,x,y
InputLocaledID:=DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)
CoordMode,tooltip,Relative
if % InputLocaledID=Localed1
  ToolTip,Английский,A_CaretX+10,A_CaretY-20,3
else if % InputLocaledID=Localed2
  ToolTip,Русский,A_CaretX+10,A_CaretY-20,3
CoordMode,tooltip,Screen
SetTimer,RemoveToolTip,1000
return

Этот кусок кода пока не проверялся мною на работоспособность, я просто позаимствовал его у Alectric (из предыдущего сообщения).

p.s.: хочу добавить, что ClipWait у меня в коде не используется, т.к. у меня он ну совсем не работает, а если его заменить на Sleep,1 - всё начинает нормально работать (даже при таком маленьком интервале в 1мс, но если его мало для вашей машины - рекомендую увеличить его до 15-20мс).
p.p.s.: если вам захочется сменить хоткеи на свои - не забудьте также сменить и KeyWait'ы в этих хоткеях.

16 (изменено: serzh82saratov, 2013-02-22 00:23:09)

Re: AHK: Исправление набранного в неверной раскладке текста

Хорошо бы ещё добавить изменение регистра букв. Иногда с зажатым капслоком тоже бывает нехорошо выходит

OFF:

+ открыть спойлер

p.p.s.: если вам захочется сменить хоткеи на свои - не забудьте также сменить и KeyWait'ы в этих хоткеях.

Может просто KeyWait, % LTrim( A_ThisHotkey, "+|^|#|>|$|<|!") . Разве не сгодится?
И если в скрипте много подпрограмм, непроще приводить список сверху ввиде:


$>^>+Space::Goto, Конвертировать_весь_текст
;+Space::Goto, Конвертировать_только_всю_строку 
;^Space::Goto, Конвертировать_только_левую_часть_строки 

;****

Конвертировать_весь_текст:
KeyWait, % LTrim( A_ThisHotkey, "+|^|#|>|$|<|!")
MsgBox %A_ThisHotkey% х конвертировать_весь_текст
Return

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

--------------

Вот и я перемудрил с KeyWait, % LTrim( A_ThisHotkey, "+|^|#|>|$|<|!")
Достаточно просто записать как:

$>^>+Space  UP::Goto, Конвертировать_весь_текст

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

17

Re: AHK: Исправление набранного в неверной раскладке текста

Спасибо за замечания.
Я тоже думал как бы проще сократить код, но в итоге решил, что оно того не стоит как раз из-за того, что у каждого свои keywait'ы.
Я не очень понимаю как ваш код

KeyWait, % LTrim( A_ThisHotkey, "+|^|#|>|$|<|!")

или другой со Space UP заменят мои keywait'ы - ведь их же надо несколько, на каждую кнопку по одному. Ведь последней кнопкой пользователь может отпустить не обязательно пробел, а какой-то модификатор (ктрл-шифт-альт), а к тому времени уже будет исполняться скрипт.
Про регистр букв думаю можно и добавить, но толь не ещё 5 хоткеев, а только 1 (типа shift+capslock), который будет работать только с выделенным текстом.

18 (изменено: serzh82saratov, 2013-02-22 10:41:17)

Re: AHK: Исправление набранного в неверной раскладке текста

Погорячился... Хотя непонимаю зачем ждать отпускания перед началом действия? Нажимаешь ведь для действия, а если нажал и передумал, то всё равно отпустишь, и оно...

Может так:


<^<+Space::KeyWait("Конвертировать_весь_текст", "LCtrl|LShift|Space")

; если не надо ждать, то кнопки неуказывать 
; <^<+Space::KeyWait("Конвертировать_весь_текст")     будет как Gosub
; или можно указать одну кнопку, или до кучи ту которой нет в комбинации, но мешается под рукой :)

; \|/\|/\|/\|/\|/\|/\|/\|/\|/ где-то глубоко \|/\|/\|/\|/\|/\|/\|/\|/\|/

Конвертировать_весь_текст:
    MsgBox ok     
    Return


KeyWait(Label, Buttons = "") {
    Loop, Parse, Buttons, |
        KeyWait, %A_LoopField%
    Gosub, %Label%
}

чтобы "вниз не лазить" неискушенным пользователям

то всё равно отпустишь, и оно...

Хмм... Наверное чтобы нажатия не послать в текст. Тут конечно :facepalm:





Взял на вооружение:

+ открыть спойлер


#UseHook
Goto, Start

>^>+Space::KeyWait("Transform_all_text", "RCtrl|RShift|Space")
>+Space::KeyWait("Transform_only_last_line", "RShift|Space")
>^>!Space::KeyWait("Transform_only_right_part", "RCtrl|RAlt|Space")
>^Space::KeyWait("Transform_only_left_part", "RCtrl|Space")
>!Space::KeyWait("Transform_only_last_word", "RAlt|Space")
;KeyWait("SwitchLocale")                                                            

 ; --------------------------------------------------------------------------------------------
Start:
    #NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
    SendMode Input 
    StringCaseSense, On
    #SingleInstance, Force
    SetBatchLines, -1
    SetKeyDelay, 10
    en := "``qwertyuiop[]asdfghjkl;'zxcvbnm,./~@#$^&QWERTYUIOP{}|ASDFGHJKL:""ZXCVBNM<>?"
    ru := "ёйцукенгшщзхъфывапролджэячсмитьбю.Ё""№;:?ЙЦУКЕНГШЩЗХЪ/ФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,"
    Return
    
Transform_all_text:                ; Transform all text
    savedClip := Clipboard
    Sleep 1
    Send ^{vk41}^{vk43}
    Sleep 1
    Clipboard := transformTextLayout(Clipboard)
    Sleep 1
    Send ^{vk56}
    Clipboard := savedClip
    savedClip := ""
    Return

Transform_only_last_line:                ; Transform only last line (full line)
    savedClip := Clipboard
    Sleep 1
    Send {End}+{Home}^{vk43}
    Sleep 1
    Clipboard := transformTextLayout(Clipboard)
    Sleep 1
    Send ^{vk56}
    Clipboard := savedClip
    savedClip := ""
    Return

Transform_only_left_part:                ; Transform only (left) part of a line (from the beginning of the line to the caret)
    savedClip := Clipboard
    Sleep 1
    Send +{Home}^{vk43}
    Sleep 1
    Clipboard := transformTextLayout(Clipboard)
    Sleep 1
    Send ^{vk56}
    Clipboard := savedClip
    savedClip := ""
    Return

Transform_only_left_right:                ; Transform only (right) part of a line (from the beginning of the line to the caret)
    savedClip := Clipboard
    Sleep 1
    Send +{End}^{vk43}
    Sleep 1
    Clipboard := transformTextLayout(Clipboard)
    Sleep 1
    Send ^{vk56}
    Clipboard := savedClip
    savedClip := ""
    Return

Transform_only_last_word:                ; Transform only last word
    savedClip := Clipboard
    Sleep 1
    Loop
    {
        Send ^+{Left}
        If A_LoopField = 1
            Continue
        Else
            Send ^{vk43}
        Sleep 1
        IfInString, Clipboard, %A_Space%
        {
            Send ^+{Right}^{vk43}
            Sleep 1
            Break
        }
    }
    Clipboard := transformTextLayout(Clipboard)
    Sleep 1
    Send ^{vk56}
    Clipboard := savedClip
    savedClip := ""
    Return

transformTextLayout(textContainer)
    {
        Global en, ru
        textContainer ~= "i)[a-z]" ? (layoutIn := en, layoutOut := ru) : (layoutIn := ru, layoutOut := en)
        Loop, Parse, textContainer
        {
            IfNotInString, layoutIn, %A_LoopField%
                newChar := A_LoopField
            Else
                StringReplace, newChar, A_LoopField, %A_LoopField%, % SubStr(layoutOut, InStr(layoutIn, A_LoopField, True), 1)
            outputStr .= newChar
        }
        textContainer := outputStr
        outputStr := layoutIn := layoutOut := newChar := ""
        Return textContainer
    }
    
SwitchLocale:
    WinGet,ID,id,A
    ThreadID:=DllCall("GetWindowThreadProcessId", UInt, ID, UInt, 0)
    InputLocaledID:=DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)
    if % InputLocaledID=Localed1
        SendMessage,0x50,0,%Localed2%,,ahk_id %ID%
    else if % InputLocaledID=Localed2
        SendMessage,0x50,0,%Localed1%,,ahk_id %ID%
    else
        SendMessage,0x50,0,%Localed2%,,ahk_id %ID%
    MouseGetPos,x,y
    InputLocaledID:=DllCall("GetKeyboardLayout", UInt, ThreadID, UInt)
    CoordMode,tooltip,Relative
    if % InputLocaledID=Localed1
        ToolTip,Английский,A_CaretX+10,A_CaretY-20,3
    else if % InputLocaledID=Localed2
        ToolTip,Русский,A_CaretX+10,A_CaretY-20,3
    CoordMode,tooltip,Screen
    SetTimer,RemoveToolTip,1000
    return
    RemoveToolTip:
    ToolTip
    return
    
KeyWait(Label, Buttons = "") {
    Loop, Parse, Buttons, |
        KeyWait, %A_LoopField%
    Gosub, %Label%
}

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

19

Re: AHK: Исправление набранного в неверной раскладке текста

Я уж 150 лет использую Punto, но интересно стало, равноценная ли замена будет ему? В чем плюсы и минусы? Автопереключение вряд ли реализовано?

20

Re: AHK: Исправление набранного в неверной раскладке текста

serzh82saratov пишет:

Погорячился... Хотя непонимаю зачем ждать отпускания перед началом действия? Нажимаешь ведь для действия, а если нажал и передумал, то всё равно отпустишь, и оно...

использованные мной хоткеи содержат ctrl и shift, а они же участвуют далее в скрипте с командами Send. Это приводит к конфликту, если не дождаться keywait'а.

serzh82saratov пишет:

Хмм... Наверное чтобы нажатия не послать в текст. Тут конечно :facepalm:

не, там же используются кнопки-модификаторы, на текст бы они не повлияли. Вся проблема в этих ctrl+c, ctrl+v и т.д.: если у тебя уже зажат ctrl, то send сработает криво, "отжав" его (и не знаю зажмёт ли его ещё после этого), и вместо ctrl+c отправится c.

serzh82saratov пишет:

Взял на вооружение:

я не очень понял сути изменений - код просто перетасован ради ре-группировки? Так получилось только в 2 раза длинней.

Zohann пишет:

Я уж 150 лет использую Punto, но интересно стало, равноценная ли замена будет ему?

Однозначно нет.

Zohann пишет:

В чем плюсы и минусы?

Мой скрипт, вероятно, будет жрать меньше памяти (~7.5Mb), но зато менее функционален, возможны баги, не имеет интерфейса.

Zohann пишет:

Автопереключение вряд ли реализовано?

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

21 (изменено: serzh82saratov, 2013-02-22 23:54:46)

Re: AHK: Исправление набранного в неверной раскладке текста

я не очень понял сути изменений - код просто перетасован ради ре-группировки? Так получилось только в 2 раза длинней.

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

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

22

Re: AHK: Исправление набранного в неверной раскладке текста

Помогите, пожалуйста, изменить ф-ию таким образом, чтобы весь выделенный текст заменялся на противоположный. Например, текст "Привет! Rfr ltkf&" заменялся на "Ghbdtn! Как дела?".

transformTextLayout(textContainer)
{
	en := "``qwertyuiop[]asdfghjkl;'zxcvbnm,./~@#$^&QWERTYUIOP{}|ASDFGHJKL:""ZXCVBNM<>?"
	ru := "ёйцукенгшщзхъфывапролджэячсмитьбю.Ё""№;:?ЙЦУКЕНГШЩЗХЪ/ФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,"
	textContainer ~= "i)[a-z]" ? (layoutIn := en, layoutOut := ru) : (layoutIn := ru, layoutOut := en)
	Loop, Parse, textContainer
	{
		IfNotInString, layoutIn, %A_LoopField%
			newChar := A_LoopField
		Else
			StringReplace, newChar, A_LoopField, %A_LoopField%, % SubStr(layoutOut, InStr(layoutIn, A_LoopField, True), 1)
		outputStr .= newChar
	}
	Return outputStr
}

23

Re: AHK: Исправление набранного в неверной раскладке текста

http://forum.script-coding.com/viewtopi … 490#p82490

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

24 (изменено: serzh82saratov, 2017-02-04 17:59:32)

Re: AHK: Исправление набранного в неверной раскладке текста

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


СhangedKeysLocale()
{
	Static Chars := "ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮёйцукенгшщзхъфывапролджэячсмитьбю,.""№;?"
				.   "~QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>``qwertyuiop[]asdfghjkl;'zxcvbnm,.?/@#$&"
	SelText := GetWord(TempClipboard)
	Loop, parse, SelText
      NewText .= (found := InStr(Chars, A_LoopField, 1))
         ? SubStr(Chars, found - 72, 1) : A_LoopField
	If (SelText = "" || NewText = "" || SelText == NewText)
		Return 1, Clipboard := TempClipboard
	Clipboard := NewText
	SendInput, ^{vk56}
	Sleep, 100
	Clipboard := TempClipboard
	ToggleLocale()
}

ToggleLocale()
{
	Static WM_INPUTLANGCHANGEREQUEST := 0x50
	InputLocale := (DllCall("GetKeyboardLayout", "Int"
	, DllCall("GetWindowThreadProcessId", "Ptr", WinExist("A"), "Int", "0")) & 0x0000FFFF)
	ControlGetFocus, CtrlFocus
	PostMessage, WM_INPUTLANGCHANGEREQUEST, 0, InputLocale = 0x409 ? 0x419 : 0x409, %CtrlFocus%
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui