Тема: AHK: Смена раскладки написанного текста
Работает под AHK_L.
Скрипт меняет раскладку выделенного текста или последнего слова слева от каретки по Shift + Break, как программа Punto Switcher.
+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} ; Ctrl + V
; переключаем раскладку клавиатуры в зависимости от раскладки последней найденной буквы
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
}