101

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

Тем не менее, им многие до сих пор пользуются, например.

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

102

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

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

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

103

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

teadrinker пишет:

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

Хотя, выглядит всё же, вроде, логичнее, имеет смысл заменить.

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

104

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

serzh82saratov пишет:

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

Ну всё же разработчики от ANSI-версии пока не отказались, так что рано "бить по рукам" . Другое дело, когда упорно продолжают использовать basic-версию.

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

105

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

Отредактировал.

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

106

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

Только не очень понятно наличие стольких точек в строках, зачем они?

Вопрос ещё актуален?

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

107

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

В общем-то да, почему не так:

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

   Loop, parse, Text
      NewText .= (found := InStr(Chars, A_LoopField, 1)) 
         ? SubStr(Chars, found - 59, 1) : A_LoopField
   Return NewText
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

108

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

http://s019.radikal.ru/i606/1203/58/7b55e7d0f1c8.jpg

Баг головного мозга, надо поправить.

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

109

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

А я подумал — для красоты.

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

110

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

К сожалению, нет http://xbmc.ru/forum/images/smilies/facepalm.gif

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

111

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

У меня тоже что-то с кодировкой стало. Скрипт сохранён как UTF-8 без BOM, но почему-то из анг. получаются кракозябры, а кирилица вообще не меняется.

ќР†ЎРС!

  Даже не знаю после чего изменилось. Может после обновления Windows?

112

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

Скрипты должны сохраняться только с BOM в любом формате из ANSI, UTF-8, UTF-16.

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

113

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

Foma пишет:

У меня тоже что-то с кодировкой стало. Скрипт сохранён как UTF-8 без BOM, но почему-то из анг. получаются кракозябры, а кирилица вообще не меняется.

ќР†ЎРС!

  Даже не знаю после чего изменилось. Может после обновления Windows?

Тоже самое. Слово "Windows" набранное русской раскладкой "Цштвщцы", скриптом переделывается в "??????".
Скрипт сохраняю в UTF-8 c галкой BOM. Windows 8.1 64bit.

114

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

У меня семёрка, с таким не сталкивался. Попробуйте это почитать. И ещё здесь вариант решения подобных проблем в прошлых версиях Windows правкой реестра (в последней трети страницы).
Только что проэкспериментировал, что при сохранении скрипта в UTF-8 без BOM действительно делает из латинских символов кракозябры, а с кириллицей ничего не делает. Советую сохранять скрипты в ANSI. Если в юникоде — то обязательно с BOM.

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

115 (изменено: mafckz, 2015-04-10 06:45:13)

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

В выложенном скрипте меня не устраивало, что когда после написанного слова ставится пробел, и нажимается клавиша изменения раскладки, то изменения не происходили (это так задумано или нет?) К примеру, punto switcher изменяет текст в данном случае.

Сильно в коде не разбирался, но не понял зачем такой усложненной код в функции GetWord начиная со 130 строки (цикл While A_Index < 10). Поэтому начиная с этой строки и до конца фунции я заменил код на

   
else 
   {
    Send ^+{left}
    SendInput, ^{vk43}
    ClipWait, 0
    if !ErrorLevel
      Return Clipboard
   } 

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

116

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

mafckz пишет:

когда после написанного слова ставится пробел... то изменения не происходили (это так задумано или нет?)

Да, так и задумано, после пробела скрипт сработает, если только выделить предыдущий текст.

не понял зачем такой усложненной код

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

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

117

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

teadrinker пишет:

Да, так и задумано, после пробела скрипт сработает, если только выделить предыдущий текст

Все-таки это не совсем верный подход с точки зрения "юзер-френдли" интерфейса. Пользователь набрал слово, перевел его по хоткею в другую раскладку - работает. Снова набрал слово, отделил пробелом - жмет хоткей - а программа ему в ответ: "Извини,  я понимаю, что именно ты хочешь сделать, но у тебя предыдущее слово - ПРОБЕЛ, извини, такие правила."

+ -

Пример с пешеходами. В Советском Союзе делали для них дорожки по утвержденному плану, и ставили грозные таблички "По газону не ходить!!!". В Германии сначала смотрели, где люди протоптали дорожки наиболее удобными маршрутами, а потом их асфальтировали. У вас налицо склонность к 1му варианту. ))

118

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

+ дорожки

Дорожки так проложили в каком-то советском институте. А про Германию не очень верится. Там же орднунг. Айн-цвай-драй-полицай.

119 (изменено: serzh82saratov, 2015-11-18 03:32:28)

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

Может кто то сочтёт полезным переводить начало слов в верхний регистр:


ConvertTitle(delimiters = " ")
{ 
	SelText := GetWord(TempClipboard)
	SelText := RegExReplace(SelText, "(.)", Format("{:Ts}", SubStr(SelText, 1, 1)), , 1), pos := 1
	While (pos := RegExMatch(SelText, "S)[\Q" delimiters "\E][a-zа-яё]", M, pos))
		SelText := RegExReplace(SelText, ".", Format("{:Ts}", SubStr(M, 2, 1)), , 1, ++pos)
	Clipboard := SelText
	SendInput, ^{vk56}   ; Ctrl + V
	Sleep, 200
	Clipboard := TempClipboard
}

Например в кодинге можно использовать свои разделители:

ConvertTitle(" {[._""`n")
ab_ab ab{ab.ab"ab[ab`nab

Заменит здесь все "a" на титульные.

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

120 (изменено: serzh82saratov, 2015-11-18 16:15:05)

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

Собственно изначальный вопрос и не задал:

delimiters := "`n {([,._"""

SelText = абв_абв абв{абв.абв"абв[абв`nабв,абв

SelText := RegExReplace(SelText, "(.)", Format("{:Ts}", SubStr(SelText, 1, 1)), , 1), pos := 1
While (pos := RegExMatch(SelText, "S)[\Q" delimiters "\E][a-zа-яё]", M, pos))
	SelText := RegExReplace(SelText, ".", Format("{:Ts}", SubStr(M, 2, 1)), , 1, ++pos)
	; или   SelText := SubStr(SelText, 1, pos) Format("{:Ts}", SubStr(M, 2, 1)) SubStr(SelText, ++pos+1)
MsgBox % SelText

Можно ли упростить?

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

121

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

teadrinker
В последней версии строку из символов /// или {{{ не переводит, хотя например [[[ или /{[ переводит.

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

122

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

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

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

123

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

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

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

124

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

Как исправить следующие ошибки:
1. :^ (шифт-6) не перекодируется.
2. (iban-6) перекодируется на (iban-(шифт-6)
3. http://ф перекодируется на реезЖ..ф - хотя я набрал только "ф" и, по логике, должно получиться http://a

И как сделать:
4. Мне нужна перекодировка СТРОГО на раскладку, противоположную текущей (например, если смесь тех и этих букв, я именно раскладкой укажу нужное направление).
5. Без учёта пробелов и переводов строк, а то перекодируется лишнее, а в текстовых полях на некоторых сайтах делается лишний перевод строки.
По-моему, если от набранного слова отошёл - нечего мудрить, перекодируешь его через выделение.

Спасибо, вообще очень классный и нужный скрипт. Я сам писал такой, но там не было смены регистра, и он не работает с AHK_L.

125

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

PS. Посмотрел и разобрался. Спасибо.

126

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

AlanCast пишет:

1. :^ (шифт-6) не перекодируется.

Почему-то забыл эти символы добавить в набор, отредактировал в Коллекции.

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

127 (изменено: stealzy, 2016-09-02 16:38:21)

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

Кстати, велосипед ConvertRegistr() можно заменить на StringUpper/StringLower.

128

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

stealzy, поясните.

пРИВЕТ => Привет

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

129

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

Наверное можно подсократить:

text := "пРИВЕТ"
msgbox % RegExReplace(text, "([А-ЯЁA-Z])|([а-яёa-z])", "$L1$U2")

130

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

Да, так работает, интересное решение.

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

131 (изменено: stealzy, 2016-09-03 11:09:00)

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

teadrinker, упустил момент с разнорегистровым текстом.
А по-польски слабо список символов составить? :trollface

MsgBox % StringInvertCase("cZEŚĆ W jĘZYKU pOLSKIM")

StringInvertCase(str) {
	Loop, Parse, str
	{
		StringUpper charUpper , A_LoopField
		StringLower charLower , A_LoopField
		charInvert := (charUpper == A_LoopField) ? charLower : charUpper 
		strInvert .= charInvert
	}
	Return strInvert
}

132

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

stealzy пишет:

А по-польски слабо список символов составить?

Ну, это вряд ли пригодится. Хотя универсальность, конечно, приятна. Если бы ещё это как-то эффектно решить. Стал думать, можно ли как-то определить регистр символа? Ничего в голову не приходит.

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

133 (изменено: stealzy, 2016-09-03 11:09:53)

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

Можно глянуть как устроена StringUpper в коде. Наверняка не списком перечисляют весь юникод :-).

134

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

Можно ещё Translit добавить, полезно например вставить в путь к файлу.

Translit() {
	Static RU := "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
	, ENG := ["A","B","V","G","D","E","Yo","Zh","Z","I","Y","K","L","M","N","O"
	,"P","R","S","T","U","F","Kh","Ts","Ch","Sh","Sch","'","I","","E","Yu","Ya"]
	
	If (SelText := GetWord(TempClipboard)) = ""
		Return Clipboard := TempClipboard
	Loop, Parse, SelText
		If p := (RU ~= "Si)\Q" A_LoopField "\E")
			Translit .= (A_LoopField ~= "S)[А-ЯЁ]") ? ENG[p] : Format("{:L}", ENG[p])
		Else
			Translit .= A_LoopField
	Clipboard := Translit
	SendInput, ^{vk56}   ; Ctrl + V
	Sleep, 200
	Clipboard := TempClipboard
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

135 (изменено: mar9i, 2017-09-24 19:45:40)

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

Было б не плохо обновить в теме http://forum.script-coding.com/viewtopic.php?id=7186 полностью код, со всеми изменениями. Мне лично не хватает конвертирование "Заглавные Буквы" и "Первая заглавная". Пока чайник, не выходит написать код самому, помогите плиз.

136 (изменено: Nerv0z, 2019-09-30 10:03:33)

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

Не асилил читать всю тему, извините, если повторюсь.
Не работает последний вариант вашего скрипта у меня.. нажимаю перевод и получаю вместо слова привет из английской раскладки:
ghbdtn
вот это :
§РРЇћ‘

может кодировка  поехала в скрипте ??

137

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

Убедитесь, что установлена актуальная версия AHK, и что скрипт сохранен в кодировке UTF-8 c BOM.

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

138

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

stealzy пишет:

А по-польски слабо список символов составить? :trollface

Оказалось не слабо:

MsgBox % StringInvertCase("cZEŚĆ W jĘZYKU pOLSKIM", langID := 0x415)

StringInvertCase(str, langID) {
   VarSetCapacity(buff, 256, 0), VarSetCapacity(key, 2)
   layout := DllCall("LoadKeyboardLayout", "Str", "0000" . Format("{:04X}", langID), "UInt", 0)
   Loop, Parse, str
   {
      res := DllCall("VkKeyScanEx", UShort, Ord(A_LoopField), UInt, layout, UShort)
      vk := res & 0xFF, shift := res >> 8
      NumPut(shift ? 0 : 128, buff, 16, "Char")
      DllCall("ToUnicodeEx", UInt, vk, UInt, 0, Ptr, &buff, Str, key, Int, 2, UInt, 0, Ptr, layout)
      invertedStr .= key
   }
   Return invertedStr
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

139

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

stealzy, а у вас польская раскладка установлена?

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

140

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

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

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

141

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

Ну да, я предполагаю. Сейчас код выше у меня работает, но символами из английской раскладки. Установил в языковой панели польскую — ничего не изменилось, наверное ещё языковой пакет нужен, но пока не устанавливал.

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

142 (изменено: serzh82saratov, 2019-11-13 00:52:48)

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

Обычный польский показывает латиницу, попробуй в нём азербайджан.
https://i.imgur.com/Hn1Pv0t.png












Например "E" латинская.








https://i.imgur.com/oM5sQuH.png

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

143

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

Нет, а что?

stealzy пишет:

устроена StringUpper в коде. Наверняка не списком перечисляют

А может и списком перечисляют для восточноевропейских языков через таблицы трансляции. В любом случае я за стандартную библиотеку.

teadrinker пишет:

StringInvertCase(str, langID)

Раз у вас не юникод, то второй параметр наверно нужен, но логичнее тогда передавать encoding.

144

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

Используется стандартная функция CharLower/CharUpper.

145 (изменено: stealzy, 2019-11-13 03:02:10)

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

Malcev пишет:

стандартная функция

Я и не сомневался. Под ее капотом вполне вероятно таблицы трансляции.

P.S. 8 лет теме, 5 лет комменту с ConvertRegistr(Text), 3 года комменту с StringInvertCase.
Может лет через пять кому-то снова будет не слабо и мы увидим новый виток обсуждения преобразования регистра, если все это еще будет существовать.

146

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

Вроде мой код корректно работает, конкретно с польским что-то непонятное, но например с немецким, если установить немецкую раскладку, получается. öÄü —> ÖäÜ

stealzy пишет:

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

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

stealzy пишет:

Раз у вас не юникод, то второй параметр наверно нужен, но логичнее тогда передавать encoding.

Можете пояснить эту мысль?

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

147

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

teadrinker пишет:

конкретно с польским что-то непонятное

Я установил польский и скачал пакет. Но если печатать на польском, то все символы один в один как инглиш. У тебя как?

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

148

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

teadrinker, не понял что значит преобразование раскладки?
Encoding - кодировка, как единственная нужная информация для однозначной идентификации текста.
serzh82saratov, а там вся фишка в диакритических знаках - сочетания с Alt.

149

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

В общем поляков в *опу со своими "фишками", ну и китаёз. Делаем для нормальных (адекватных) национальностей. А эти пускай с китайского на польский сами пишут, одним разом, чтобы потом ни в коем случае, темы не поднимать, а то блин всякие привыкли через 5 лет отвечать, позор то какой, ой-ой-ой.

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

150 (изменено: teadrinker, 2019-11-13 21:06:06)

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

serzh82saratov пишет:

Но если печатать на польском, то все символы один в один как инглиш. У тебя как?

Я на Win 7 пробовал, там если так выбрать

https://i.imgur.com/VkDB92O.png

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

https://i.imgur.com/yMEkgYT.png

тогда диакритические знаки появляются. Но при нажатии Shift + [клавиша с диакритическим знаком] вместо того же знака в верхнем регистре появляется другой знак.

Поставил немецкую — там всё нормально.

stealzy пишет:

Encoding - кодировка, как единственная нужная информация для однозначной идентификации текста.

Путаете, это не тот случай. Кодировка нужна, когда символы задаются цифровым кодом, а в данном случае они однозначно задаются графически.

stealzy пишет:

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

А весь топик-то о чём? Изначально задача была изменить раскладку текста, написанного в неправильной раскладке: ghbdtn —> привет.

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

151 (изменено: serzh82saratov, 2019-11-17 10:53:55)

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

Удалено.

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

152

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

teadrinker пишет:

А весь топик-то о чём?

Просто думал раз написали функцию StringInvertCase(str, langID) про регистр продолжаем, конкретно в ней без раскладок и языков проще обойтись.

153 (изменено: Malcev, 2019-11-14 00:57:44)

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

teadrinker пишет:

Вроде мой код корректно работает, конкретно с польским что-то непонятное

Просто в твоём коде не учтены все модификаторы:

StringInvertCase("nNńŃ", langID := 0x415)

StringInvertCase(str, langID) {
   VarSetCapacity(buff, 256, 0), VarSetCapacity(key, 2)
   layout := DllCall("LoadKeyboardLayout", "Str", "0000" . Format("{:04X}", langID), "UInt", 0)
   Loop, Parse, str
   {
      res := DllCall("VkKeyScanEx", UShort, Ord(A_LoopField), UInt, layout, UShort)
      vk := res & 0xFF, shift := res >> 8
      msgbox % shift
      NumPut(shift ? 0 : 128, buff, 16, "Char")
      DllCall("ToUnicodeEx", UInt, vk, UInt, 0, Ptr, &buff, Str, key, Int, 2, UInt, 0, Ptr, layout)
      invertedStr .= key
   }
   Return invertedStr
}

1

Either SHIFT key is pressed.

2

Either CTRL key is pressed.

4

Either ALT key is pressed.

8

The Hankaku key is pressed

16

Reserved (defined by the keyboard layout driver).

32

Reserved (defined by the keyboard layout driver).

https://docs.microsoft.com/en-us/window … keyscanexw

154

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

Ага, точно, правильно так:

shift := (res >> 8)&1

Но всё равно у меня с польской диакритикой не работает.

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

155

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

Еще надо ALT, Ctrl и Hankaku добавлять в NumPut.

156 (изменено: teadrinker, 2019-11-14 02:24:15)

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

Вроде вышло:

MsgBox, % StringInvertCase("nNńŃ", langID := 0x415)

StringInvertCase(str, langID) {
   VarSetCapacity(buff, 256, 0), VarSetCapacity(key, 2)
   layout := DllCall("LoadKeyboardLayout", "Str", "0000" . Format("{:04X}", langID), "UInt", 0)
   Loop, Parse, str
   {
      res := DllCall("VkKeyScanEx", "UShort", Ord(A_LoopField), "UInt", layout, "UShort")
      vk := res & 0xFF, modifiers := res >> 8
      shift := modifiers & 1, ctrl := modifiers & 2, alt := modifiers & 4, hankaku := modifiers & 8
      for k, v in {ctrl: 0x11, alt: 0x12, hankaku: 0xF3}
         NumPut(%k% ? 128 : 0, buff, v, "Char")
      NumPut(shift ? 0 : 128, buff, 0x10, "Char")
      DllCall("ToUnicodeEx", "UInt", vk, "UInt", 0, "Ptr", &buff, "Str", key, "Int", 2, "UInt", 0, "Ptr", layout)
      invertedStr .= key
   }
   Return invertedStr
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

157

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

Теперь ещё вопрос остался, как первые четыре цифры в названии раскладки определять, они не всегда "0000".

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

158

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

Через список из реестра?

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts

159 (изменено: teadrinker, 2019-11-14 12:16:31)

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

Есть 00000415 и 00010415. Как понять, какая нужна? Мне нужно как-то соотнести значения вида 0x04150415 и "00000415".
Можно, конечно, запускать LoadKeyboardLayout, перебирая "0000", "0001" ... до тех пор, пока не получим в результате существующую раскладку, но, кроме того, что это не элегантное решение, оно ещё и много времени занимает.

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

160

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

Как я понимаю, надо загружать дефолтную раскладку:

An application can and will typically load the default input locale identifier or IME for a language and can do so by specifying only a string version of the language identifier.

https://docs.microsoft.com/en-us/window … ardlayouta
Cписок дефолтных раскладок тут:
https://docs.microsoft.com/en-us/window … uage-packs

161

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

Нет, дефолтная не пойдет для задачи смены раскладки.

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

162 (изменено: Malcev, 2019-11-16 17:58:05)

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

А как по-другому?
Например с польской 00000415 и 00010415 - это не названия раскладок, а их значения.
Названия же у 00000415 будет такое же, а у 00010415 - d0010415.
Названия, после установки, можно посмотреть здесь:

HKEY_CURRENT_USER\Keyboard Layout\Preload

Но с такой раскладкой данный код уже не работает

MsgBox, % StringInvertCase("nNńŃ", langID := 0x415)

StringInvertCase(str, langID) {
   VarSetCapacity(buff, 256, 0), VarSetCapacity(key, 2)
   msgbox % layout := DllCall("LoadKeyboardLayout", "Str", "d0010415", "UInt", 0)
   Loop, Parse, str
   {
      msgbox % res := DllCall("VkKeyScanEx", "UShort", Ord(A_LoopField), "UInt", layout, "UShort")
      vk := res & 0xFF, modifiers := res >> 8
      shift := modifiers & 1, ctrl := modifiers & 2, alt := modifiers & 4, hankaku := modifiers & 8
      for k, v in {ctrl: 0x11, alt: 0x12, hankaku: 0xF3}
         NumPut(%k% ? 128 : 0, buff, v, "Char")
      NumPut(shift ? 0 : 128, buff, 0x10, "Char")
      DllCall("ToUnicodeEx", "UInt", vk, "UInt", 0, "Ptr", &buff, "Str", key, "Int", 2, "UInt", 0, "Ptr", layout)
      invertedStr .= key
   }
   Return invertedStr
}

163

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

Malcev пишет:

Например с польской 00000415 и 00010415 - это не названия раскладок, а их значения.

Не знаю насчёт понятия "значение", у раскладки есть layout name, которое можно получить функцией GetKeyboardLayoutName, это как раз значение вида "00000415", и есть locale id, которое выдаёт функция GetKeyboardLayout. С layout name по моему текущему опыту функция LoadKeyboardLayout всегда работает. Проблема только в том, что GetKeyboardLayoutName работает только со своей веткой, поэтому приходится сначала сменить раскладку своей ветки, другого способа получить layout name я пока не нашёл.

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

164

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

Да, действительно, проверил - с названиями раскладок я ошибся.
Но так не работает:

MsgBox, % StringInvertCase("nNńŃ", langID := 0x415)

StringInvertCase(str, langID) {
   VarSetCapacity(buff, 256, 0), VarSetCapacity(key, 2)
   msgbox % layout := DllCall("LoadKeyboardLayout", "Str", "00010415", "UInt", 0)
   Loop, Parse, str
   {
      msgbox % res := DllCall("VkKeyScanEx", "UShort", Ord(A_LoopField), "UInt", layout, "UShort")
      vk := res & 0xFF, modifiers := res >> 8
      shift := modifiers & 1, ctrl := modifiers & 2, alt := modifiers & 4, hankaku := modifiers & 8
      for k, v in {ctrl: 0x11, alt: 0x12, hankaku: 0xF3}
         NumPut(%k% ? 128 : 0, buff, v, "Char")
      NumPut(shift ? 0 : 128, buff, 0x10, "Char")
      DllCall("ToUnicodeEx", "UInt", vk, "UInt", 0, "Ptr", &buff, "Str", key, "Int", 2, "UInt", 0, "Ptr", layout)
      invertedStr .= key
   }
   Return invertedStr
}

165

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

А почему ты именно "00010415" подставляешь, а не "00000415"? Может, у тебя и нету первой. Раскладка должна быть установлена.

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

166

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

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

167

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

Сейчас не могу проверить, но русская у меня не дефолтная установлена.

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

168

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

С русской mnemonic, например с буквой ё тоже не сработает.

169

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

Тут всё расписано:

Further proof that VkKeyScanEx sucks

http://archives.miloush.net/michkap/arc … 48742.html

170

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

Ну, пока что всё равно нет другого способа переконвертировать символ из одной раскладки в другую.

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

171

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

А чем массивы не устраивают?

172

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

А как на все раскладки массивы сделаешь?

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

173

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

Ну если много свободного времени и желания, то можно сделать.
Только зачем на все?

174

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

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

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

175

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

Ну тогда задача невыполнима.

176

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

Почему, выполнима на 90%.

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

177 (изменено: Malcev, 2019-11-19 22:23:12)

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

Можно попробовать увеличить процент, подгружая dll раскладки и анализируя его алгоритм, по типу Microsoft Keyboard Layout Creator.
https://www.codeproject.com/Articles/43 … or-in-32-6
http://archives.miloush.net/michkap/arc … 81107.html

178

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

Спасибо, попробую разобраться.

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

179

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

teadrinker пишет:

Ну, пока что всё равно нет другого способа переконвертировать символ из одной раскладки в другую.

Это вроде работает (не для иероглифов), например из QWERTY в AZERTY.
Или тут есть что поправить, упростить?


string = Россия-2020:`nвыживайте как сможете

Global oSymbols := SymbolsListCreate()

MsgBox % str2 := Translate(string, oSymbols["RUS"], oSymbols["ENU"])
MsgBox % Translate(str2, oSymbols["ENU"], oSymbols["RUS"]) 
Return    

Translate(string, inhkl, outhkl) {
	Loop, Parse, string
	{
		If !sc := oSymbols[inhkl].chartocode[Ord(A_LoopField)]
			newstring .= A_LoopField
		Else
			newstring .= oSymbols[outhkl].sctochar[sc]
	}
	Return newstring 
} 

SymbolsListCreate() {
	Static MAPVK_VK_TO_VSC := 0
	arr := {}
	for hkl, LayoutName in GetKeyboardLayoutList()
	{ 
		arr[hkl] := {}, arr[hkl].sctochar := {}, arr[hkl].chartocode := {}, arr[LayoutName] := hkl
		for min, max in {0x30:0x5A,0xBA:0xE2}
			loop % max - min + 1
			{
				vk := min + A_Index - 1
				If !sc := DllCall("MapVirtualKeyEx", "Uint", vk, "Uint", MAPVK_VK_TO_VSC, "Ptr", hkl, "Uint")
					Continue
				Char := GetKeyChar(vk, sc, hkl, 0), _Char := GetKeyChar(vk, sc, hkl, 1)
				If (Char = "" && _Char = "")
					Continue
				arr[hkl].sctochar[sc] := Char, arr[hkl].sctochar[-sc] := _Char
				arr[hkl].chartocode[Ord(Char)] := sc, arr[hkl].chartocode[Ord(_Char)] := -sc 
			}
	}
	Return arr
}

GetKeyChar(vk, sc, HKL, Shift = 0) {
    Static state, _ := VarSetCapacity(state, 256, 0)
		, char, __ := VarSetCapacity(char, 4, 0) 
	If Shift
		NumPut(-128, state, 0x10 , "Char")  
	Else 
		NumPut(0, state, 0x10 , "Char")   
    n := DllCall("ToUnicodeEx", "uint", vk, "uint", sc
        , "ptr", &state, "ptr", &char, "int", 1, "uint", 0, "ptr", HKL)
    Return StrGet(&char, n, "utf-16")
}
	
GetKeyboardLayoutList() {
   VarSetCapacity(List, A_PtrSize*5)
   Size := DllCall("GetKeyboardLayoutList", Int, 5, Str, List)
   Locales := []
   Loop % Size 
		Locales[Locale := NumGet(List, A_PtrSize*(A_Index - 1)) & 0xFFFF] := GetLangName(Locale)
   Return Locales
}

GetLangName(Locale, LCType := 3) { 
	Size := DllCall("GetLocaleInfo", UInt, Locale, UInt, LCType, UInt, 0, UInt, 0) * 2
	VarSetCapacity(lpLCData, Size, 0)
	DllCall("GetLocaleInfo", UInt, Locale, UInt, LCType, Str, lpLCData, UInt, Size)
	Return lpLCData
} 
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

180

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

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

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

181 (изменено: stuermer, 2023-03-15 20:08:05)

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

serzh82saratov

Это вроде работает (не для иероглифов), например из QWERTY в AZERTY.
Или тут есть что поправить, упростить?

Это новая и последняя версия конвертации en-ru-en, которая заменяет предыдущую?
Функцию Translate() нужно запускать по горячей клавише, когда неправильно введенный текст выделен?

182

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

stuermer пишет:

Это новая и последняя версия конвертации en-ru-en, которая заменяет предыдущую?

Насколько помню, то да.

stuermer пишет:

Функцию Translate() нужно запускать по горячей клавише, когда неправильно введенный текст выделен?

А в чём тут вопрос, когда по горячей клавише запускаете, что не так?

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

183

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

serzh82saratov пишет:

А в чём тут вопрос, когда по горячей клавише запускаете, что не так?

Эта программа заменяет функционал Punto Switcher. Punto Switcher работает так: выделить введенный текст в неправильной раскладке и нажать горячую клавишу. Поэтому оформлять программу нужно в таком же виде.
Ваша версия полностью отличается от предыдущей, которая оформлена правильно, с горячими клавишами и там понятно что и когда запускается. Поэтому я пытаюсь понять, как у вас выделенный текст передается в функцию Translate(). Там он передается через Clipboard.

184

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

stuermer пишет:

выделить введенный текст в неправильной раскладке и нажать горячую клавишу

Не знаю о чём вы, код так и используется.

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

185

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

stuermer пишет:

Функцию Translate() нужно запускать по горячей клавише, когда неправильно введенный текст выделен?

А, вы же про код из#179, а я про коллекцию думал. Тот не помню зачем писал, тест какой то был.

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

186

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

stuermer
Тут вопрос про GetKeySC возник, и я вспомнил, в #179 вроде моё решение про то чтобы работало со всеми раскладками а не только англ <> рус которые забиты в скрипте в коллекции. Но этот код я не добавлял в скрипт.

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

187

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

serzh82saratov
Тогда добавьте, если не трудно, тогда будет универсальная версия в коллекции скриптов. У меня как раз не англ <> рус. Он переключает между любыми двумя установленными в системе раскладками?

188

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

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

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

189 (изменено: stuermer, 2023-03-20 13:33:37)

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

serzh82saratov пишет:

я вспомнил, в #179 вроде моё решение про то чтобы работало со всеми раскладками

Я так понял, что #179 ваш, а тот, что в коллекции не ваш.
#179 удобнее, т.к. нужно только подставить раскладки из системы, а не отдельные символы. Можно было бы просто заменить ConvertText() на вашу Translate(), но у вас запуск Translate() идет с 2 параметрами исходной и конечной раскладки, а ConvertText() из коллекции использует 1 параметр для противоположной раскладки "OppositeLayout". Это соответствует функционалу PuntoSwitcher по горячей клавише.

190

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

stuermer пишет:

Это соответствует функционалу PuntoSwitcher по горячей клавише.

А если три языка, как PuntoSwitcher  считает на какой изменить?

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

191

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

Там есть опция, между какими языками переключаться. Если нет в системе EN, то можно назначить вместо EN - DE, т.е. другую латиницу. Но функционал с 3 языками это необязательно.

192

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

Упрощенный вариант фунции GetWord() из коллекции и её вызова :


SwitchKeysLocale()
{
   SelText := GetWord() 
   Clipboard := ConvertText(SelText, Layout)
   SendInput, ^{vk56}   ; Ctrl + V
   Sleep, 50
   SwitchLocale(Layout)
}

SwitchReg()
{
   SelText := GetWord()
   Clipboard := ConvertReg(SelText) 
   SendInput, ^{vk56}   ; Ctrl + V 
}

GetWord()
{
   SetKeyDelay, 0
   
   SendInput, ^{vk43}
   Sleep, 100
   if (Clipboard != "")
      Return Clipboard
   
   SendInput, +{Right}
}

193 (изменено: serzh82saratov, 2023-03-20 15:13:44)

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

stuermer пишет:

Если нет в системе EN, то можно назначить вместо EN - DE, т.е. другую латиницу

Значит в ней все списки символов с соответствием скан кодов забита, например Q английская и Q французкая это разные клавиши, хотя код символа одинаковый.
Снова приходим к тому что нужны списки, если как в PuntoSwitcher надо. А значит мой код нужно использовать для получения списка языка, а скрипт переделывать под скан коды, это уже не просто вставить мои функции в код.

stuermer пишет:

Упрощенный вариант фунции GetWord() из коллекции и её вызова :

Чем лучше, просто короче код?

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

194

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

Примерно так без ConvertRegistr.


Global oSymbols := {}
SymbolsListCreate("ENU", "RUS")
Return

^PGDN::SwitchKeysLocale()   ; Ctrl + Page Down
+PGDN::SwitchRegistr()      ; Shift + Page Down

SwitchKeysLocale()
{
   SelText := GetWord(TempClipboard) 
   Clipboard := ConvertText(SelText, Layout)
   SendInput, ^{vk56}   ; Ctrl + V
   Sleep, 50
   SwitchLocale(Layout)
   Sleep, 50
   Clipboard := TempClipboard
}

SwitchRegistr()
{
   SelText := GetWord(TempClipboard)
   Clipboard := ConvertRegistr(SelText) 
   SendInput, ^{vk56}   ; Ctrl + V 
   Sleep, 200 
   Clipboard := TempClipboard
}

GetWord(ByRef TempClipboard)
{
   SetBatchLines, -1
   SetKeyDelay, 0
   
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   Sleep, 100
   if (Clipboard != "")
      Return Clipboard
   
   While A_Index < 10
   {
      SendInput, ^+{Left}^{vk43}
      ClipWait, 1
      if ErrorLevel
         Return

      if RegExMatch(Clipboard, "P)([ \t])", Found) && A_Index != 1
      {
         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
      }
      Clipboard =
   }
}

ConvertText(Text, ByRef OppositeLayout)
{  
   RegExReplace(Text, "i)[A-Z@#\$\^&\[\]'`\{}]", "", LatCount)
   RegExReplace(Text, "i)[А-ЯЁ№]", "", CyrCount)
   
   if (LatCount != CyrCount)  {
      CurrentLayout := LatCount > CyrCount ? oSymbols.Langs[1] : oSymbols.Langs[2]
      OppositeLayout := LatCount > CyrCount ? oSymbols.Langs[2] : oSymbols.Langs[1]
   }
   else
   {
      threadId := DllCall("GetWindowThreadProcessId", Ptr, WinExist("A"), UInt, 0, Ptr)
      landId := DllCall("GetKeyboardLayout", Ptr, threadId, Ptr) & 0xFFFF
      if (oSymbols.Langs[1] = landId)
         CurrentLayout := oSymbols.Langs[2], OppositeLayout := oSymbols.Langs[1]
      else
         CurrentLayout := oSymbols.Langs[1], OppositeLayout := oSymbols.Langs[2]
   }  
   Return Translate(Text, CurrentLayout, OppositeLayout)
} 

SwitchLocale(Layout)
{
   ControlGetFocus, CtrlFocus, A
   PostMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, Layout, %CtrlFocus%, A
}

ConvertRegistr(string)
{

}

Translate(string, inhkl, outhkl) {
	Loop, Parse, string
	{ 
		If !sc := oSymbols[inhkl].chartocode[Ord(A_LoopField)]
			newstring .= A_LoopField
		Else
			newstring .= oSymbols[outhkl].sctochar[sc]
	}
	Return newstring 
} 

SymbolsListCreate(L1, L2) {
	Static MAPVK_VK_TO_VSC := 0
	oSymbols := {}
	oSymbols.Langs := [] 
	for hkl, LayoutName in GetKeyboardLayoutList()
	{
		If (LayoutName != L1 && LayoutName != L2)
			Continue 
		oSymbols.Langs[2 - (LayoutName = L1)] := hkl 
		oSymbols[hkl] := {}, oSymbols[hkl].sctochar := {}, oSymbols[hkl].chartocode := {}, oSymbols[LayoutName] := hkl
		for min, max in {0x30:0x5A,0xBA:0xE2}
			loop % max - min + 1
			{
				vk := min + A_Index - 1
				If !sc := DllCall("MapVirtualKeyEx", "Uint", vk, "Uint", MAPVK_VK_TO_VSC, "Ptr", hkl, "Uint")
					Continue
				Char := GetKeyChar(vk, sc, hkl, 0), _Char := GetKeyChar(vk, sc, hkl, 1)
				If (Char = "" && _Char = "")
					Continue
				oSymbols[hkl].sctochar[sc] := Char, oSymbols[hkl].sctochar[-sc] := _Char
				oSymbols[hkl].chartocode[Ord(Char)] := sc, oSymbols[hkl].chartocode[Ord(_Char)] := -sc 
			}
	}  
}

GetKeyChar(vk, sc, HKL, Shift = 0) {
    Static state, _ := VarSetCapacity(state, 256, 0)
		, char, __ := VarSetCapacity(char, 4, 0) 
	If Shift
		NumPut(-128, state, 0x10 , "Char")  
	Else 
		NumPut(0, state, 0x10 , "Char")   
    n := DllCall("ToUnicodeEx", "uint", vk, "uint", sc
        , "ptr", &state, "ptr", &char, "int", 1, "uint", 0, "ptr", HKL)
    Return StrGet(&char, n, "utf-16")
}
	
GetKeyboardLayoutList() {
   VarSetCapacity(List, A_PtrSize*5)
   Size := DllCall("GetKeyboardLayoutList", Int, 5, Str, List)
   Locales := []
   Loop % Size 
		Locales[Locale := NumGet(List, A_PtrSize*(A_Index - 1)) & 0xFFFF] := GetLangName(Locale)
   Return Locales
}

GetLangName(Locale, LCType := 3) { 
	Size := DllCall("GetLocaleInfo", UInt, Locale, UInt, LCType, UInt, 0, UInt, 0) * 2
	VarSetCapacity(lpLCData, Size, 0)
	DllCall("GetLocaleInfo", UInt, Locale, UInt, LCType, Str, lpLCData, UInt, Size)
	Return lpLCData
} 

Тут надо RegEx под свой язык переделать.

ConvertText(Text, ByRef OppositeLayout)
{  
   RegExReplace(Text, "i)[A-Z@#\$\^&\[\]'`\{}]", "", LatCount)
   RegExReplace(Text, "i)[А-ЯЁ№]", "", CyrCount)

Тут языки указать.

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

195

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

serzh82saratov пишет:

Чем лучше, просто короче код?

Убрал лишнее из GetWord() - восстановление старого буфера и проверки.

196 (изменено: stuermer, 2023-03-20 19:41:14)

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

Тут надо RegEx под свой язык переделать.

Кто-то может под немецкий переделать? Я в Perl не силен.
Буквы хжэ -> üöä соответственно.

197

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

stuermer пишет:

Убрал лишнее из GetWord() - восстановление старого буфера и проверки

Это на любителя.


Добавил ConvertRegistr, но с ним теперь такая штука, он был предназначен для исправления с неправильным CapsLock, а теперь как с неправильным Shift, например "5" теперь меняется на "%".

#SingleInstance Force
#Persistent
#NoEnv  

Global oSymbols := {}
SymbolsListCreate("ENU", "RUS")
Return

^PGDN::SwitchKeysLocale()   ; Ctrl + Page Down
+PGDN::SwitchRegistr()      ; Shift + Page Down

SwitchKeysLocale()
{
   SelText := GetWord(TempClipboard) 
   Clipboard := ConvertText(SelText, Layout)
   SendInput, ^{vk56}   ; Ctrl + V
   Sleep, 50
   SwitchLocale(Layout)
   Sleep, 50
   Clipboard := TempClipboard
}

SwitchRegistr()
{
   SelText := GetWord(TempClipboard)
   Clipboard := ConvertRegistr(SelText) 
   SendInput, ^{vk56}   ; Ctrl + V 
   Sleep, 200 
   Clipboard := TempClipboard
}

GetWord(ByRef TempClipboard)
{
   SetBatchLines, -1
   SetKeyDelay, 0
   
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput, ^{vk43}
   Sleep, 100
   if (Clipboard != "")
      Return Clipboard
   
   While A_Index < 10
   {
      SendInput, ^+{Left}^{vk43}
      ClipWait, 1
      if ErrorLevel
         Return

      if RegExMatch(Clipboard, "P)([ \t])", Found) && A_Index != 1
      {
         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
      }
      Clipboard =
   }
}

ConvertText(Text, ByRef OppositeLayout)
{  
   RegExReplace(Text, "i)[A-Z@#\$\^&\[\]'`\{}]", "", LatCount)
   RegExReplace(Text, "i)[А-ЯЁ№]", "", CyrCount)
   
   if (LatCount != CyrCount)  {
      CurrentLayout := LatCount > CyrCount ? oSymbols.Langs[1] : oSymbols.Langs[2]
      OppositeLayout := LatCount > CyrCount ? oSymbols.Langs[2] : oSymbols.Langs[1]
   }
   else
   {
      threadId := DllCall("GetWindowThreadProcessId", Ptr, WinExist("A"), UInt, 0, Ptr)
      landId := DllCall("GetKeyboardLayout", Ptr, threadId, Ptr) & 0xFFFF
      if (oSymbols.Langs[1] = landId)
         CurrentLayout := oSymbols.Langs[2], OppositeLayout := oSymbols.Langs[1]
      else
         CurrentLayout := oSymbols.Langs[1], OppositeLayout := oSymbols.Langs[2]
   }  
   Return Translate(Text, CurrentLayout, OppositeLayout)
} 

SwitchLocale(Layout)
{
   ControlGetFocus, CtrlFocus, A
   PostMessage, WM_INPUTLANGCHANGEREQUEST := 0x50,, Layout, %CtrlFocus%, A
}

ConvertRegistr(string) {
	Loop, Parse, string
	{ 
		r := oSymbols.Registr[Ord(A_LoopField)] 
		newstring .= (r = "") ? A_LoopField : r
	}
	Return newstring 
}

Translate(string, inhkl, outhkl) {
	Loop, Parse, string
	{ 
		If !sc := oSymbols[inhkl].chartocode[Ord(A_LoopField)]
			newstring .= A_LoopField
		Else
			newstring .= oSymbols[outhkl].sctochar[sc]
	}
	Return newstring 
} 

SymbolsListCreate(L1, L2) {
	Static MAPVK_VK_TO_VSC := 0
	oSymbols := {}
	oSymbols.Langs := [] 
	oSymbols.Registr := {}
	for hkl, LayoutName in GetKeyboardLayoutList()
	{
		If (LayoutName != L1 && LayoutName != L2)
			Continue 
		oSymbols.Langs[2 - (LayoutName = L1)] := hkl 
		oSymbols[hkl] := {}, oSymbols[hkl].sctochar := {}, oSymbols[hkl].chartocode := {}, oSymbols[LayoutName] := hkl
		for min, max in {0x30:0x5A,0xBA:0xE2}
			loop % max - min + 1
			{
				vk := min + A_Index - 1
				If !sc := DllCall("MapVirtualKeyEx", "Uint", vk, "Uint", MAPVK_VK_TO_VSC, "Ptr", hkl, "Uint")
					Continue
				Char := GetKeyChar(vk, sc, hkl, 0), _Char := GetKeyChar(vk, sc, hkl, 1)
				If (Char != "") 
				{
					oSymbols[hkl].sctochar[sc] := Char
					oSymbols[hkl].chartocode[Ord(Char)] := sc 
					If (_Char != "") 
						oSymbols.Registr[Ord(Char)] := _Char
				}
				If (_Char != "") 
				{
					oSymbols[hkl].sctochar[-sc] := _Char
					oSymbols[hkl].chartocode[Ord(_Char)] := -sc 
					If (Char != "") 
						oSymbols.Registr[Ord(_Char)] := Char
				} 
			}
	}  
}

GetKeyChar(vk, sc, HKL, Shift = 0) {
    Static state, _ := VarSetCapacity(state, 256, 0)
		, char, __ := VarSetCapacity(char, 4, 0) 
	If Shift
		NumPut(-128, state, 0x10 , "Char")  
	Else 
		NumPut(0, state, 0x10 , "Char")   
    n := DllCall("ToUnicodeEx", "uint", vk, "uint", sc
        , "ptr", &state, "ptr", &char, "int", 1, "uint", 0, "ptr", HKL)
    Return StrGet(&char, n, "utf-16")
}
	
GetKeyboardLayoutList() {
   VarSetCapacity(List, A_PtrSize*5)
   Size := DllCall("GetKeyboardLayoutList", Int, 5, Str, List)
   Locales := []
   Loop % Size 
		Locales[Locale := NumGet(List, A_PtrSize*(A_Index - 1)) & 0xFFFF] := GetLangName(Locale)
   Return Locales
}

GetLangName(Locale, LCType := 3) { 
	Size := DllCall("GetLocaleInfo", UInt, Locale, UInt, LCType, UInt, 0, UInt, 0) * 2
	VarSetCapacity(lpLCData, Size, 0)
	DllCall("GetLocaleInfo", UInt, Locale, UInt, LCType, Str, lpLCData, UInt, Size)
	Return lpLCData
} 
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

198 (изменено: serzh82saratov, 2023-03-20 22:23:06)

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

stuermer пишет:

Кто-то может под немецкий переделать? Я в Perl не силен.
Буквы хжэ -> üöä соответственно.

RegExMatch(Char, "(*UCP)[^\W\d_]")

И этот ответ, породил решение этого

serzh82saratov пишет:

Добавил ConvertRegistr, но с ним теперь такая штука, он был предназначен для исправления с неправильным CapsLock, а теперь как с неправильным Shift

И самое интересное, теперь этот ответ не нужен, то есть RegEx, работать должно без него, само собой.

SymbolsListCreate без параметров выводит все установленные раскладки в буфер обмена.

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


/*
Смена раскладки написанного текста
Модификация этого скрипта https://forum.script-coding.com/viewtopic.php?pid=102343#p102343

v1.2
С генерацией раскладок
	http://forum.script-coding.com/viewtopic.php?pid=157311#p157311
*/

#SingleInstance Force
#Persistent
ListLines Off
SetBatchLines -1
#NoEnv

Global oSymbols := {} 
; SymbolsListCreate() ; Все раскладки в буфер обмена
SymbolsListCreate("ENU", "RUS") 
Return
   
^PGDN::SwitchKeysLocale()   ; Ctrl + Page Down
+PGDN::SwitchRegistr()      ; Shift + Page Down

; Esc:: ExitApp

SwitchKeysLocale()
{
	SelText := GetWord(TempClipboard) 
	If SelText = 
		Return Clipboard := TempClipboard
	Clipboard := ConvertText(SelText, Layout)
	SendInput  {LCtrl Down}{vk56}{LCtrl Up}    ;  "V"
	Sleep, 50
	SwitchLocale(Layout)
	Sleep, 50
	Clipboard := TempClipboard
}

SwitchRegistr()
{
	SelText := GetWord(TempClipboard)
	If SelText = 
		Return Clipboard := TempClipboard
	Clipboard := ConvertRegistr(SelText) 
	SendInput  {LCtrl Down}{vk56}{LCtrl Up}    ;  "V"
	Sleep, 200 
	Clipboard := TempClipboard
}

GetWord(ByRef TempClipboard)
{
   SetBatchLines, -1
   SetKeyDelay, 0
   
   TempClipboard := ClipboardAll
   Clipboard =
   SendInput  {LCtrl Down}{vk43}{LCtrl Up}    ;  "C"
   Sleep, 100
   if (Clipboard != "")
      Return Clipboard
   
   While A_Index < 20
   {
      SendInput, {LCtrl Down}{LShift Down}{Left}{LCtrl Up}{LShift Up}{LCtrl Down}{vk43}{LCtrl Up}    ;  "C"
      ClipWait, 1
      if ErrorLevel
         Return

      if RegExMatch(Clipboard, "P)([ \t])", Found) && A_Index != 1
      {
         SendInput  {LCtrl Down}{LShift Down}{Right}{LCtrl Up}{LShift Up}
         Return SubStr(Clipboard, FoundPos1 + 1)
      }

      PrevClipboard := Clipboard
      Clipboard =
      SendInput, {LShift Down}{Left}{LShift Up}{LCtrl Down}{vk43}{LCtrl Up}    ;  "C"
      ClipWait, 1
      if ErrorLevel
         Return

      if (StrLen(Clipboard) = StrLen(PrevClipboard))
      {
         Clipboard =
         SendInput, {LShift Down}{Left}{LShift Up}{LCtrl Down}{vk43}{LCtrl Up}    ;  "C"
         ClipWait, 1
         if ErrorLevel
            Return

         if (StrLen(Clipboard) = StrLen(PrevClipboard))
            Return Clipboard
         Else
         {
            SendInput  {LShift Down}{Right 2}{LShift Up}
            Return PrevClipboard
         }
      }

      SendInput  {LShift Down}{Right}{LShift Up}

      s := SubStr(Clipboard, 1, 1)
      if s in %A_Space%,%A_Tab%,`n,`r
      {
         Clipboard =
         SendInput, {LShift Down}{Left}{LShift Up}{LCtrl Down}{vk43}{LCtrl Up}    ;  "C"
         ClipWait, 1
         if ErrorLevel
            Return

         Return Clipboard
      }
      Clipboard =
   }
}

ConvertText(string, ByRef OppositeLayout) 
{   
	L1 := L2 := 0
	Loop, Parse, string
	{  
		_ord := Ord(A_LoopField)
		If oSymbols[oSymbols.Langs[1]].charischar[_ord]
			++L1
		Else If oSymbols[oSymbols.Langs[2]].charischar[_ord]
			++L2 
	}
	if (L1 != L2)  {
		CurrentLayout := L1 > L2 ? oSymbols.Langs[1] : oSymbols.Langs[2]
		OppositeLayout := L1 > L2 ? oSymbols.Langs[2] : oSymbols.Langs[1] 
	}
	else
	{
		threadId := DllCall("GetWindowThreadProcessId", Ptr, WinExist("A"), UInt, 0, Ptr)
		landId := DllCall("GetKeyboardLayout", Ptr, threadId, Ptr) & 0xFFFF
		if (oSymbols.Langs[1] = landId)
			CurrentLayout := oSymbols.Langs[1], OppositeLayout := oSymbols.Langs[2]
		else
			CurrentLayout := oSymbols.Langs[2], OppositeLayout := oSymbols.Langs[1]
	}   
	Return ConvertLayout(string, CurrentLayout, OppositeLayout)
} 

SwitchLocale(Layout)
{
   ControlGetFocus, CtrlFocus, A
   PostMessage, 0x50,, Layout, %CtrlFocus%, A	; WM_INPUTLANGCHANGEREQUEST 
}

ConvertRegistr(string) {
	Loop, Parse, string
	{ 
		r := oSymbols.Registr[Ord(A_LoopField)] 
		newstring .= (r = "") ? A_LoopField : r
	}
	Return newstring 
}

ConvertLayout(string, inhkl, outhkl) {
	Loop, Parse, string
	{ 
		If !sc := oSymbols[inhkl].chartocode[Ord(A_LoopField)]
			newstring .= A_LoopField
		Else
			newstring .= oSymbols[outhkl].sctochar[sc]
	}
	Return newstring 
}   

SymbolsListCreate(L1 = "", L2 = "") {
	; ENU = 1033, RUS = 1049, DEU = 1031
	Static MAPVK_VK_TO_VSC := 0
	If (L1 = "")
	{
		for hkl, LayoutName in GetKeyboardLayoutList()
			LangsStr .= LayoutName "`t" hkl  "`n" 
		MsgBox % Clipboard := LangsStr
		Return
	}
	oSymbols := {} 
	oSymbols.Langs := [] 
	oSymbols.Registr := {}
	for hkl, LayoutName in GetKeyboardLayoutList()
	{ 
		If (LayoutName != L1 && LayoutName != L2)
			Continue 
		oSymbols.Langs[2 - (LayoutName = L1)] := hkl 
		oSymbols[hkl] := {}, oSymbols[hkl].sctochar := {}
		oSymbols[hkl].chartocode := {}, oSymbols[LayoutName] := hkl
		oSymbols[hkl].charischar := {}
		for min, max in {0x30:0x5A,0xBA:0xE2}
		{
			loop % max - min + 1
			{
				vk := min + A_Index - 1
				If !sc := DllCall("MapVirtualKeyEx", "Uint", vk, "Uint", MAPVK_VK_TO_VSC, "Ptr", hkl, "Uint")
					Continue
				Char := GetKeyChar(vk, sc, hkl, 0), _Char := GetKeyChar(vk, sc, hkl, 1)
				If (Char != "") 
				{
					_ord := Ord(Char)
					oSymbols[hkl].sctochar[sc] := Char
					oSymbols[hkl].chartocode[_ord] := sc
					If (RegExMatch(Char, "(*UCP)[^\W\d_]"))
					{
						oSymbols[hkl].charischar[_ord] := 1
						If (_Char != "")
							oSymbols.Registr[_ord] := _Char 
					}
				}
				If (_Char != "") 
				{
					_ord := Ord(_Char)
					oSymbols[hkl].sctochar[-sc] := _Char
					oSymbols[hkl].chartocode[_ord] := -sc 
					If (RegExMatch(_Char, "(*UCP)[^\W\d_]"))
					{
						oSymbols[hkl].charischar[_ord] := 1
						If (Char != "")
							oSymbols.Registr[_ord] := Char 
					}  
				} 
			} 
		}
	}  
	If oSymbols.Langs.Count() != 2 
		Throw Exception("Не найдена указанная раскладка!")
} 

GetKeyChar(vk, sc, HKL, Shift = 0) {
    Static state, _ := VarSetCapacity(state, 256, 0)
		, char, __ := VarSetCapacity(char, 4, 0) 
	If Shift
		NumPut(-128, state, 0x10 , "Char")  
	Else 
		NumPut(0, state, 0x10 , "Char")   
    n := DllCall("ToUnicodeEx", "uint", vk, "uint", sc
        , "ptr", &state, "ptr", &char, "int", 1, "uint", 0, "ptr", HKL)
    Return StrGet(&char, n, "utf-16")
}
	
GetKeyboardLayoutList() {
   VarSetCapacity(List, A_PtrSize*5)
   Size := DllCall("GetKeyboardLayoutList", Int, 5, Str, List)
   Locales := []
   Loop % Size 
		Locales[Locale := NumGet(List, A_PtrSize*(A_Index - 1)) & 0xFFFF] := GetLangName(Locale)
   Return Locales
}

GetLangName(Locale, LCType := 3) { 
	Size := DllCall("GetLocaleInfo", UInt, Locale, UInt, LCType, UInt, 0, UInt, 0) * 2
	VarSetCapacity(lpLCData, Size, 0)
	DllCall("GetLocaleInfo", UInt, Locale, UInt, LCType, Str, lpLCData, UInt, Size)
	Return lpLCData
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

199 (изменено: stuermer, 2023-03-20 20:56:54)

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

RegEx, работать должно без него, само собой.
SymbolsListCreate без параметров выводит все установленные раскладки в буфер обмена.
Нужные раскладки можно менять не перезапуская скрипт, запустив SymbolsListCreate с нужными.

На это я и расчитывал вначале, иначе нет преимущества по сравнению со старой версией в коллекции, если нужно раскладки вручную переделывать.
Работает, спасибо!

200

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

stuermer пишет:

На это я и расчитывал вначале

Да, тогда мне интересно было, потом забылось, а тут слово за слово и допилилось.
Но посмотрим, может рано радоваться, не тестировалось же толком.
Кстати если кто языки будет менять, напишите на каких нормально работает.

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