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
Skype dmitry_fiveg

27

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

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

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

28

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

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

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

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

29

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

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

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

30

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

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

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

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

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

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

32

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

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

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

33

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

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

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

34

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

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

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

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 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

36

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

Alectric пишет:

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

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

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

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 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

38

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

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

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

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
Skype dmitry_fiveg

40

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

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

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

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

41

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

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

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

42

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

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

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

43

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

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

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

44

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

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

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

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
Skype dmitry_fiveg

46

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

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

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

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

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

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

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

48

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

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

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

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

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

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 7 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

50

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

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

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