1

Тема: AHK: Конвертация текста

В связи с тем, что все найденные мною сценарии-альтернативы программе Punto Switcher работали некорректно (вероятно, из-за Win10), решил подумать над выходом из ситуации. Придумал следующее:

  • Выделить последнее слово слева от каретки или выделить текст

  • Вырезать в буфер обмена

  • Сменить раскладку языка

  • Отправить текст в виде виртуального кода

  • Получить конвертированный текст

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

Проблема в том, что работает на данный момент только лишь конвертация текста с латиницы в кириллицу. Т.е. если вырезать слово "ntrcn", получаю слово "текст". Если же вырезать слово "еуче", то вместо "text" я получаю только пробелы.

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

Char = N 

VK := CharToVk(Char)

If VK
    MsgBox, %VK%
Else
    MsgBox, Invalid character.


; ---------- Function -----------

CharToVk(Char)
{
    VK := DllCall("VkKeyScan", "uchar", Asc(Char), "Short")
    If (VK = -1)
        Return
    SetFormat, Integer, H
    VK :=  SubStr(VK & 0xFF, 3)
    StringUpper, VK, VK
    SetFormat, Integer, D
    Return "vk" VK
}

Если первый параметр заменить на

Char = %Clipboard%

, то из скопированного "текст" получаю виртуальный код первой буквы, т.е. {vk4E}.

Сценарий, написанный по моей просьбе на основе вышеизложенного работает с буфером и отправляет слово целиком, однако, как упоминал, не распознает кириллицу:

^v::
KeyWait Ctrl
for k, v in StrSplit(clipboard)
    SendInput % CharToVk(v)
return

CharToVk(Char) {
    VK := Format("{:x}", GetKeyVK(Char))
    if InStr("!@#$`%^&*()_+<>?:""|{}~",Char)
        return "{vkA0 Down}{VK" VK "}{vkA0 Up}"
    if Char is upper
        return "{vkA0 Down}{VK" VK "}{vkA0 Up}"
    else
        return "{vk" VK "}"
    return
}

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

SendMode Input
#LAlt::
Send ^+{Left}^{vk58} ; Выделить и вырезать последнее слово слева от каретки
if (old_layout = "RU")
	{
		SendMessage, 0x50,, % Locale_EN,, A
	}
else 
	{
		SendMessage, 0x50,, % Locale_RU,, A
	}
gosub, Paste
return


Paste:
{
KeyWait Ctrl
for k, v in StrSplit(clipboard)
    SendInput % CharToVk(v)
return

CharToVk(Char) {
    if !Char
        return "{vk32}"
    VK := DllCall("VkKeyScan", "uchar", Asc(Char), "Short")
    if (VK = -1)
        return
    SetFormat, Integer, H
    VK :=  SubStr(VK & 0xFF, 3)
    StringUpper, VK, VK
    SetFormat, Integer, D
    if InStr("!@#$`%^&*()_+<>?:""|{}~",Char)
       return "{vkA0 Down}{vk" VK "}{vkA0 Up}"    
    if Char is upper
        return "{vkA0 Down}{VK" VK "}{vkA0 Up}"
    else
        return "{vk" VK "}"
}
}

2 (изменено: Alectric, 2015-11-15 10:20:15)

Re: AHK: Конвертация текста

Хмм... у меня твой код просто "съедает" слова, что на русском, что на английском. А вообще, без списков символов вряд-ли выйдет.

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

3

Re: AHK: Конвертация текста

Alectric
https://i.gyazo.com/3f0fbf43455bac1ad77058e9c7df235c.gif

4 (изменено: Alectric, 2015-11-15 10:51:25)

Re: AHK: Конвертация текста

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

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

5

Re: AHK: Конвертация текста

Alectric
https://i.gyazo.com/9c5e3c2b63e943702668ab443d10fb8a.gif

6 (изменено: Alectric, 2015-11-15 11:10:26)

Re: AHK: Конвертация текста

У меня по нажатию WinAlt вставляет ранее копированный текст наизнанку и вообще выходит из системы (т.е. нужно вводить пароль для входа в систему):

	Ъ

уыу 

	Х

		ЫутвЬуыыфпуб 2ч52бб % щсфу_КГбб Ф

	Ъ

пщыгиб Зфыеу

куегкт





ЗфыеуЖ

Х

ЛунЦфше Сек

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

7

Re: AHK: Конвертация текста

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

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

8

Re: AHK: Конвертация текста

Alectric, я тоже этого не понял, но у меня раскладка переключается только благодаря

if (old_layout = "RU")
	{
		SendMessage, 0x50,, % Locale_EN,, A
	}
else 
	{
		SendMessage, 0x50,, % Locale_RU,, A
	}

9

Re: AHK: Конвертация текста

Значит они в "окружении"...

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

10

Re: AHK: Конвертация текста

Зачем эти мучения?

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

11

Re: AHK: Конвертация текста

serzh82saratov, Скайп падает после второй конвертации.
Такая же проблема была и с Punto Switcher до ее обновления.

Я могу ошибаться, но мне кажется странным, что вариант с отправлением виртуальных кодов никому не приглянулся, т.к. кажется, что такой метод должен работать не хуже при гораздо меньшем объеме кода. И самое, на мой взгляд, интересное, что он должен работать с разными языками, для чего необходимо будет лишь заменить строку с заданной раскладкой.

12 (изменено: Alectric, 2015-11-16 10:23:41)

Re: AHK: Конвертация текста

Проблема того кода с первого поста, то из-за чего исчезает слово:

msgbox,% "ru: " asc("ф") "`nen: " asc("a")

Здесь:

VK := DllCall("VkKeyScan", "uchar", Asc(Char), "Short")

...

VK1 := DllCall("VkKeyScan", "uchar", Asc("ф"), "Short")
VK2 := DllCall("VkKeyScan", "uchar", Asc("a"), "Short")

msgbox,% vk1 "`n" vk2

...

Возможно можно позаимствовать некоторые функции из библиотеки у serzh82saratov.

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

13 (изменено: YMP, 2015-11-16 13:36:37)

Re: AHK: Конвертация текста

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


MsgBox, % CharToVk("a") "`n" CharToVk("ф")


; ---------- Functions -----------

CharToVk(Char)
{
    static Eng := 0x4090409, Rus := 0x4190419
    CharCode := Asc(Char)
    Lang := CharCode > 127 ? Rus : Eng
    PrevLang := GetScriptLang()
    If (Lang != PrevLang) {
        SetScriptLang(Lang)
    }
    VK := DllCall("VkKeyScan", "uchar", CharCode, "Short")
    SetFormat, Integer, H
    VK :=  SubStr(VK & 0xFF, 3)
    StringUpper, VK, VK
    SetFormat, Integer, D
    If (Lang != PrevLang) {
        SetScriptLang(PrevLang)
    }
    Return "vk" VK
}

GetScriptLang()
{
    static ThreadID := DllCall("GetWindowThreadProcessId", "ptr", A_ScriptHwnd, "uint", 0, "ptr")
    Return DllCall("GetKeyboardLayout", "ptr", ThreadID, "ptr")
}

SetScriptLang(Lang)
{
    static Func := "PostMessage" . (A_IsUnicode? "W":"A")
    DllCall(Func, "ptr", A_ScriptHwnd, "uint", 0x50, "ptr", 0, "ptr", Lang)
    Sleep, -1
}

14

Re: AHK: Конвертация текста

Далее возникнет проблема регистра букв...

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

15 (изменено: becauseim, 2015-11-16 13:47:40)

Re: AHK: Конвертация текста

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

На данный момент у меня не получилось связать модификацию от YMP с отправлением скопированного текста.

16 (изменено: Alectric, 2015-11-16 18:51:40)

Re: AHK: Конвертация текста

Дану... напечатай слово заглавными буквами(без капслока) и смени этому слову раскладку.

...

Нужно исправить возвращаемое значение на:

    return "{vk" VK "}"
SendMode Input
#LAlt::
Send ^+{Left}^{vk58} ; Выделить и вырезать последнее слово слева от каретки
if (old_layout = "RU")
	{
		SendMessage, 0x50,, % Locale_EN,, A
	}
else
	{
		SendMessage, 0x50,, % Locale_RU,, A
	}
gosub, Paste
return


Paste:
KeyWait Ctrl
for k, v in StrSplit(clipboard)
    Send % CharToVk(v)
return



; ---------- Functions -----------

CharToVk(Char)
{
    static Eng := 0x4090409, Rus := 0x4190419
    CharCode := Asc(Char)
    Lang := charcode > 127 ? Rus : Eng
    PrevLang := getscriptlang()
    If (Lang != PrevLang) {
        SetScriptLang(Lang)
    }
    VK := DllCall("VkKeyScan", "uchar", CharCode, "Short")
    SetFormat, Integer, H
    VK :=  SubStr(VK & 0xFF, 3)
    StringUpper, VK, VK
    SetFormat, Integer, D
    If (Lang != PrevLang) {
        SetScriptLang(PrevLang)
    }
    return "{vk" VK "}"
}

GetScriptLang()
{
    static ThreadID := 0
    If (ThreadID = 0)
        ThreadID := DllCall("GetWindowThreadProcessId", "ptr", A_ScriptHwnd, "uint", 0, "ptr")
    Return DllCall("GetKeyboardLayout", "ptr", ThreadID, "ptr")
}

SetScriptLang(Lang)
{
    static Func := "PostMessage" . (A_IsUnicode? "W":"A")
    DllCall(Func, "ptr", A_ScriptHwnd, "uint", 0x50, "ptr", 0, "ptr", Lang)
    Sleep, -1
}
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

17

Re: AHK: Конвертация текста

https://i.gyazo.com/123619ea7d689b55995b49625b02fe15.gif

18 (изменено: Alectric, 2015-11-16 14:03:26)

Re: AHK: Конвертация текста

OFF: Что за мистика у него там происходит?!... У кого-нибудь еще стоит windows 10, кто-нибудь может это подтвердить?

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

19

Re: AHK: Конвертация текста

Впрочем, теперь и этот метод перестал дружить со Скайпом.

20

Re: AHK: Конвертация текста

У меня 10 стоит. А в чём мистика-то, не пойму. У вас тут какой-то таинственный разговор происходит, непонятный непосвящённому.

21

Re: AHK: Конвертация текста

YMP, у нас тут битва экстрасенсов
А если серьезно, было бы кстати, если бы Вы протестировали на своей "десятке" в окне Скайпа вариант из 16 поста от Alectric. Подозреваю, что у меня одного все так плохо.

22

Re: AHK: Конвертация текста

Я Скайпом не пользуюсь.

23 (изменено: Alectric, 2015-11-16 17:34:49)

Re: AHK: Конвертация текста

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

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

24

Re: AHK: Конвертация текста

Ругается на 30-ю строчку, там точка с запятой откуда-то взялась перед  =. После исправления, в Блокноте заменяет английскую абракадабру на русский текст в нижнем регистре. Русскую абракадабру просто удаляет.

25

Re: AHK: Конвертация текста

У becauseim, регистр остается прежним.

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