Войти

Показать полную графическую версию : [архив - Часть 2] AutoIt скрипты


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

amel27
03-10-2007, 10:16
А подробнее можно плиз?как раз тот случай, когда для нахождения нового символа вместо перебора всех элементов массива и попарного сравнения можно в качестве индекса просто указать старый символ и сразу получить результат. Хотя кода для инициализации массива Scripting.Dictionary потребуется больше, зато сама перекодировка символа будет проходить одной командой.
нужно получить текст с начала строкиесли навскидку - выделение всей строки и возврат текста текущего контрола:
Send("{HOME}+{END}")$sText = ControlGetText ("", "", ControlGetFocus (""))
с длинными кусками текста немного замедлено выделение, но это всё что я пока могу придуматьда уж, мне тоже ничего лучше в голову пока не приходит, надо подумать :(

Creat0R
03-10-2007, 13:30
amel27, выделение всей строки и возврат текста текущего контрола:
Я этого не могу делать, ведь нужно не выделяя получать текст, дав возможность набирать текст в это время юзеру (мне) :)

$sText = ControlGetText ("", "", ControlGetFocus (""))
Это первое что я попробовал ;) Спасибо. Там не стандартные элементы, и стандартными средставми AutoIt получить текст (или делать другие опирации), не реально.

надо подумать
Мне кажется тут нужно как то по RegExp получить нужное число “прыжков” влево (в соответствии с “законами выделения” по Ctrl Shit Left). Я пробовал, но всё что у меня получилось это разделить исходный текст на запятые, пробелы, и подобные символы.. но нужен более продвинуты Pattern, где будут учитываться идущие подряд разделители, разновидность разделителей идущих подряд :wacko: , и т.п.

Diamond
04-10-2007, 00:58
Creat0R,
Он для конвертирования текста набранного не в той раскладке
... и правда... как я сразу не догадался, тем более что сам иногда забываю переключать раскладку. Уже добавил скрипт в свою коллекцию, спасибо! :)

amel27
04-10-2007, 12:33
samsobiКак мне найти ее истинные координаты и щелкнуть правой кнопкой мыши?
ТУТ (http://forum.oszone.net/post-649281-1493.html) Creat0R давал линк на библиотеку функций для работы с треем (о нем речь?). Среди них есть _SysTrayIconPos() и _SysTrayIconIndex(), с помощью которых можно найти индекс иконки и определить ее координаты на рабочем столе, останется только" сделать клик".


Creat0R, Там не стандартные элементы, и стандартными средставми AutoIt получить текст (или делать другие опирации), не реально чем же он нестандартен?.. как я это себе представляю: 1) нужно найти HWND активного контрола, 2) пытаться "поговорить" с ним при помощи SendMessage(). Вот тестовый вариант для определения длины текста текущего контрола, попробуй для своего:HotKeySet("^`", "TEST")
While 1
Sleep(500)
WEnd

Func TEST()
ConsoleWrite (_ControlGetTextLength()&@CRLF)
EndFunc

Func _ControlGetTextLength()
Local $u = DllStructCreate("int;int;hwnd;hwnd;hwnd;hwnd;hwnd;hwnd;long;long;long;long")
DllStructSetData ($u, 1, DllStructGetSize($u))

Local $TopWnd = DllCall('user32.dll', 'hwnd', 'GetForegroundWindow')
Local $TID = DllCall('user32.dll', 'int', 'GetWindowThreadProcessId', 'hwnd', $TopWnd[0], 'ptr', 0)
DllCall('user32.dll', 'int', 'GetGUIThreadInfo', 'int', $TID[0], 'ptr', DllStructGetPtr($u))
Local $Res = DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', DllStructGetData($u,8), 'int', 0xE, 'int', 0, 'ptr', 0)
Return $Res[0]
EndFunc
Мне кажется тут нужно как то по RegExp получить нужное число “прыжковдля этого мало знать выделенный фрагмент - нужен вест текст... к тому же нет гарантий, что разные окна будут обрабатывать клавиши одинаково... к примеру Ctrl+A в IE у меня не сработал

А подробнее можно плиз? »
Вот что получилось (на базе твоего, но без сохранения выделения):Global $objASC = ObjCreate("Scripting.Dictionary")
Global $objANS = ObjCreate("Scripting.Dictionary")

InitMatrix ($objASC, $objANS)
HotKeySet("^`", "ConvertProc")
While 1
Sleep(500)
WEnd

Func ConvertProc()
Send("^{Insert}")
Local $strSelect = ClipGet()
If $strSelect='' Then Return
ClipPut(InvertText($strSelect, $objASC, $objANS))
Sleep(100)
Send("+{Insert}")
ClipPut('')
EndFunc

Func InvertText($sText, ByRef $objASC, ByRef $objANS)
If StringIsASCII($sText) Then
Return ConvertText($sText, $objASC)
Else
Return ConvertText($sText, $objANS)
EndIf
EndFunc

Func ConvertText($sText, ByRef $objMatrix)
Local $i, $s, $n, $sRes=''
For $i=1 To StringLen($sText)
$s = StringMid($sText,$i,1)
$n = $objMatrix.Item ($s)
If $n Then
$sRes &= $n
Else
$sRes &= $s
EndIf
Next
Return $sRes
EndFunc

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

Creat0R
04-10-2007, 18:21
amel27, Вот тестовый вариант для определения длины текста текущего контрола, попробуй для своего:
Попробовал, всегда возвращает 0 :( (текст ест-но набран).

нужен вест текст
Ctrl Shift Home :)

нет гарантий, что разные окна будут обрабатывать клавиши одинаково
Ну хотябы для тех которые обрабатывают стандартные клавиши (виндовские).

Вот что получилось
Класно получилось, спасибо, попробую это использовать в моё скрипте...
Я кстати ещё хотел бы сделать небольшой GUI-интерфейс для этого скрипта, чтобы “на лету” можно было править соотношения символов (т.е сопостовлять к одной клавише другую, у меня иногда не очень удобно получается, нужно руками править некоторые символы). Это поможет использовать не только Rus <-> Eng ;)

amel27
05-10-2007, 03:51
Creat0R
Попробовал, всегда возвращает 0HWND возвращается корректно, хотя стандартные сообщения действительно не воспринимает... причем все тулзы класса WinInfo вообще не распознают текст окна... на всякий случай может кому пригодится - функция для возврата HWND окна/контрола текущего ввода:Func _ControlGetFocus()
Local $res, $u = DllStructCreate("int;int;hwnd;hwnd;hwnd;hwnd;hwnd;hwnd;long;long;long;long")
DllStructSetData ($u, 1, DllStructGetSize($u))

$res = DllCall('user32.dll', 'hwnd', 'GetForegroundWindow')
$res = DllCall('user32.dll', 'int', 'GetWindowThreadProcessId', 'hwnd', $res[0], 'ptr', 0)
DllCall('user32.dll', 'int', 'GetGUIThreadInfo', 'int', $res[0], 'ptr', DllStructGetPtr($u))
Return DllStructGetData($u, 4)
EndFunc
Ctrl Shift Homeнет, при этом потеряется текущая позиция курсора... для полного обсчета требуется: полный текст, выделенный текст, текущая позиция курсора - положение выделенного фрагмента по отношению ко всему тексту... т.е. одними клавишами тут ИМХО не обойтись - нужны альтернативные способы получения инфы... но тогда потеряется универсальность (твой пример с OperaWindowClass).

Creat0R
05-10-2007, 04:56
amel27, стандартные сообщения действительно не воспринимает
Может есть другие методы получения текста? вот интересно, как Punto Switcher распознаёт текст в любом месте?

тогда потеряется универсальность
Ну хотябы для стандартнных полей, не страшно если в строке адреса выделяться не будет, в крайнем случае там можно будет использовать текущий метод (Send(+{Left " & StringLen($ClipText) & "}")).

Но вообще то, вот как я имел в виду:

Откроем Notepad, и впишем туда это:

this is a test() and ; only test ;

Теперь поставим курсор в конец этого текста, зажмём Ctrl + Shift, и поодиночно будем нажимать клавишу влево - нам понадобится нажать 10 раз клавишу влево чтобы весь наш (нужный) текст был выделен.

Вот я и подумал, если мы заранее знаем наш текст (который изначально был выделен и конвертирован - но нам нужен уже “новый”, конвертированный текст), то всё что нам нужно сделать, так это распознать сколько раз в этом тексте, встречаются символы по которым Ctrl Shift Left будет переходить - т.е как я это вижу, нужно по RegExp подобрать условия замены (на основе нашего текста), чтобы получить в результате нужное количество сдвигов влево (в нашем случае должно получится 10) по @Extended, ну или через размерность массива если использовать только StringRegExp().

Maza Faka
05-10-2007, 09:19
При копировании с использованием
ObjCreate("shell.application")
, возвращаемое значение отсутствует, соответственно возникает вопрос, как отследить скопировался ли файл или во время процесса копирования пользователь отменил копирование и исходя из результата выдать итоговое сообщение. Пока проверяю сравнивая размер исходного и конечного файла, но может есть более красивое и практичное решение?

$copy = CopyFile("d:\Video\Films", "C:\", "video.avi")
If @error Then
MsgBox(16, "Error", "Copying is canceled")
Else
MsgBox(0, "Done", "Copying successful")
EndIf

Func CopyFile($source, $dest, $file)
$WinShell = ObjCreate("shell.application")
$WinSHell.NameSpace($dest).CopyHere($source &"\"& $file)
If FileGetSize($source &"\"& $file) = FileGetSize($dest & $file) Then
Return 0
Else
Return SetError(1)
EndIf
EndFunc

Diamond
05-10-2007, 10:11
Вопрос по GUIRegisterMsg($WM_NCPAINT), как я понял если $wParam возвращает 1, значит произошла перерисовка всего окна.
Во всех остальных случаях можно ли как-то узнать координаты перерисовки?

Creat0R
05-10-2007, 10:59
amel27
нужно по RegExp подобрать условия замены (на основе нашего текста), чтобы получить в результате нужное количество сдвигов влево »
Вот оно! :clever-ma Сделал (после 3-ёх часов экспериментирования :wacko: ):

Func GetLeftJumps($Text)
StringRegExpReplace($Text, '\n', '')
Local $Extended = @extended

$Text = StringStripWS($Text, 3)

$Text = StringRegExpReplace($Text, '\s+|\t+', ' ')
$Text = StringRegExpReplace($Text, '~|`|!|#|%|\^|&|\*|\(|\)|-|\+|=|\{|\}|''|"|;|:|/|\\|<|>|\?|,|\[|\]|ч|Ч|ё|Ё', '|')
$Text = StringRegExpReplace($Text, '\|+', '|')
If StringIsASCII($Text) Then $Text = StringRegExpReplace($Text, '\.', '|')

Local $WordsCountArr = StringRegExp($Text, "[\s\.:;,]*([а-яА-Яa-zA-Z0-9-_]+)[\s\.:;,]*", 3)
StringRegExpReplace($Text, '\|', '')
Return $Extended + @extended + UBound($WordsCountArr)
EndFunc

Возможно это сделать и более короче, но я умею только так, а глвавное - оно работает!
Есть конечно пару(?) недостатков - к примеру, если выделить текст посредине общего текста, то выделяться будут и все предыдущие символы, идущие подряд до первого символа в выделенном тексте.

Вот полное применение + использование твоего примера:

#NoTrayIcon

Global $objASC = ObjCreate('Scripting.Dictionary')
Global $objANS = ObjCreate('Scripting.Dictionary')
InitMatrix($objASC, $objANS)

HotKeySet('`', 'ConvertProc')
HotKeySet('^q', 'Quit')

While 1
Sleep(100)
WEnd

Func ConvertProc()
Local $OldClip = ClipGet()
ClipPut('')
Send('^{Insert}')
Local $SelectedText = ClipGet()
If $SelectedText = '' Then Return
Local $InvertedText = InvertText($SelectedText, $objASC, $objANS)

ClipPut($InvertedText)
Sleep(100)
Send('+{Insert}')

Local $LeftJumps = GetLeftJumps($InvertedText)
Send('^+{LEFT ' & $LeftJumps & '}')

Send('{CTRLDOWN}')
Send('{CTRLUP}')

ClipPut($OldClip)
EndFunc

Func InvertText($sText, ByRef $objASC, ByRef $objANS)
If StringIsASCII($sText) Then
Return ConvertText($sText, $objASC)
Else
Return ConvertText($sText, $objANS)
EndIf
EndFunc

Func GetLeftJumps($Text)
StringRegExpReplace($Text, '\n', '')
Local $Extended = @extended

$Text = StringStripWS($Text, 3)

$Text = StringRegExpReplace($Text, '\s+|\t+', ' ')
$Text = StringRegExpReplace($Text, '~|`|!|#|%|\^|&|\*|\(|\)|-|\+|=|\{|\}|''|"|;|:|/|\\|<|>|\?|,|\[|\]|ч|Ч|ё|Ё', '|')
$Text = StringRegExpReplace($Text, '\|+', '|')
If StringIsASCII($Text) Then $Text = StringRegExpReplace($Text, '\.', '|')

Local $WordsCountArr = StringRegExp($Text, "[\s\.:;,]*([а-яА-Яa-zA-Z0-9-_]+)[\s\.:;,]*", 3)
StringRegExpReplace($Text, '\|', '')
Return $Extended + @extended + UBound($WordsCountArr)
EndFunc

Func ConvertText($sText, ByRef $objMatrix)
Local $i, $s, $n, $sRes = ''
For $i = 1 To StringLen($sText)
$s = StringMid($sText, $i, 1)
$n = $objMatrix.Item ($s)
If $n Then
$sRes &= $n
Else
$sRes &= $s
EndIf
Next
Return $sRes
EndFunc

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

Func Quit()
Exit
EndFunc

Главную клавишу конвертирования пришлось изменить, Ctrl ` вызывало проблемы - пока оставил только `.

samsobi
05-10-2007, 20:56
ТУТ Creat0R давал линк на библиотеку функций для работы с треем (о нем речь?). »
Да, о нем родимом! Большое спасибо за наводку, буду копать и изучать!

Maza Faka
06-10-2007, 09:43
Очень часто спрашивают, как кликнуть по иконке программы в трее. С помощью библиотеки SysTray_UDF.au3 (http://slil.ru/24942418), которую доработал amel27 сделать это очень просто: ;)

#include <SysTray_UDF.au3>

$pid = ProcessExists("edialer.exe")
$index = _SysTrayIconIndex($pid)
If @error Then MsgBox(16, "Error", "This process not have tray icon")
$pos = _SysTrayIconPos($index)
MouseClick("right", $pos[0], $pos[1])

Creat0R
06-10-2007, 10:52
Maza Faka,
Хотел сделать ещё и возможность кликания без задействования мышки, но что то не выходит...
Полагаю я неправильно использую функцию ScreenToClient в User32.dll. Может кто-то знает как правильнее? (это кстати моя одна из первых попыток работать с Dll ;)).

#NoTrayIcon
#include <SysTray_UDF.au3>

$Pid = ProcessExists("Opera.exe")
If Not $Pid Then
MsgBox(16, "Error", "This process not exists")
Exit
EndIf

$Index = _SysTrayIconIndex($Pid)
If @error Then
MsgBox(16, "Error", "This process not have tray icon")
Exit
EndIf

$Pos = _SysTrayIconPos($Index)

$hWnd = WinGetHandle("[Class:Shell_TrayWnd]")
$YPos = ScreenToClient($hWnd, $Pos[0])
$XPos = ScreenToClient($hWnd, $Pos[1])

ControlClick("[Class:Shell_TrayWnd]", "", "ToolbarWindow321", "Right", 1, $XPos, $YPos)

Func ScreenToClient($hWnd, $Point)
Local $Struct = DllStructCreate("int;int")
DllStructSetData($Struct, 1, $Point)
DllStructSetData($Struct, 2, $Point)
Local $Ret = DllCall("User32.dll", "int", "ScreenToClient", "hwnd", $hWnd, "ptr", DllStructGetPtr($Struct))
Return $Ret[0]
EndFunc

Maza Faka
06-10-2007, 14:02
Creat0R
Задумка неплохая, но тут я тебе не советчик, для меня все эти функции с DLL пока тёмный лес :-)

Creat0R
06-10-2007, 18:43
Как можно проверить системные элементы (типа «Мой компьютер», «Мои документы» и т.п) находящиеся на рабочем столе?
Т.е имеется список подобных элементов (имена), нужно каждый из них по этому списку проверить существует ли он на рабочем столе.. как это можно сделать?
В реестре конкретной инфы я так и не нашёл, к примеру у меня «Корзина» называется так: «Mycop» (это латинские буквы) :) - поиск по реестру почти ничего не дал, т.е нет зацепки чтобы проверить именно это имя, и что именно этот элемент находится на рабочем столе.

Creat0R
07-10-2007, 04:06
Обновил Au3ToPost 1.7 (http://creator-lab.ucoz.ru/load/3-1-0-18)

Список изменении:
v1.7

Ещё более надёжная интеграция в SciTE (теперь если файл настроек пуст или не найден, то используется шаблон стандартного файла, в который и пишутся необходимые пункты).
Изменён метод вставки символа Tab - оказывается можно использовать CTRL TAB :)
Исправлена ошибка некорректной вставки раскрашенного кода в форум.
В Главное Меню добавлен пункт "Добавлять тег [В] к коду".
Пункт "О Программе" перемещён в новое меню "Справка".
Добавлен пункт "Проверить обновления..." в меню "Справка".
Исправлена проблема при закрытии дочернего окна с результатом (возврат в главное окно) - управление в главное окно возвращалось не сразу после закрытия.
Теперь при установленной русской раскладки клавиатуры как раскладка по умолчанию, нажатие <Ctrl A> приведёт к выделению всего текста в Edit поле.
Теперь рядом с исходником должна быть папка с ресурсами программы (Resources) - Содержит в себе все необходимые ресурсы для работы скрипта.
Мелкие поправки в коде.

Maza Faka
07-10-2007, 08:51
поиск по реестру почти ничего не дал »
Можно проверять по CLSID в ключе реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace
Например CLSID корзины выглядит так: {645FF040-5081-101B-9F08-00AA002F954E}

Maza Faka
07-10-2007, 13:56
Как отследить нажал ли пользователь определённую кнопку в приложении и в соотвествии с этим выполнить некое действие, что-то вроде этого:

Dim $command

While Not $command
$command = ControlCommand("Aut2Exe v3 - AutoIt Script to EXE Converter", "", "Button2", "IsChecked")
Sleep(30)
WEnd
MsgBox(0, "", "Checked")

Creat0R
07-10-2007, 18:01
Maza Faka,
Можно проверять по CLSID в ключе реестра
Там нет настоящих имён элементов :(

Как отследить нажал ли пользователь определённую кнопку в приложении
Твой пример не работает?
Ну можно ещё проверять нажатия кнопки мышки (используя _IsPressed()) по определённым коортдинатам.

amel27
08-10-2007, 07:19
Creat0R
Вот оно! »во замутил! :) ...у меня вроде получилось без RegExp:Func ConvertProc()
Send("^{Insert}")
Local $strSelect = ClipGet()
If $strSelect='' Then Return
ClipPut(InvertText($strSelect, $objASC, $objANS))
Sleep(100)
Send("+{Insert}")
RestoreSelection(StringLen($strSelect))
ClipPut('')
EndFunc

Func RestoreSelection($iLen)
Local $iOldLen=0, $iNewLen=0, $iFixLen=0
Send("^+{RIGHT}^{Insert}")
Local $sOld = ClipGet()
Send("^+{LEFT}^{Insert}")
Local $sNew = ClipGet()
If $sOld<>$sNew Then
$iFixLen = StringLen($sOld)
$iNewLen = StringLen($sNew)
EndIf
While $iNewLen<$iLen
Send("^+{LEFT}^{Insert}")
$iOldLen = $iNewLen
$iNewLen = StringLen(ClipGet())
Wend
If $iNewLen=$iLen Then Return
If ($iNewLen-$iLen)<(1+$iFixLen+$iLen-$iOldLen) Then
Send('+{RIGHT ' & ($iNewLen-$iLen) & '}')
Else
Send('^+{RIGHT}+{LEFT ' & ($iLen+$iFixLen-$iOldLen) & '}')
EndIf
EndFunc
Как можно проверить системные элементы (типа «Мой компьютер», «Мои документы» и т.п) находящиеся на рабочем столе? »Ранее (http://forum.oszone.net/post-605123-1120.html) уже постил свой вариант через API, потом аналогичная тема появилась на оффсайте, там вроде обошлись только штатными функциями:Restore Icon Positions, on the Desktop and in Windows (http://www.autoitscript.com/forum/index.php?showtopic=50804&st=0&p=384391&#entry384391)

ADD:через реестр: http://wiki.oszone.net/index.php/%D0%A2%D0%B2%D0%B8%D0%BA%D0%B8_%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0/HKCU.REG

З.Ы. А зачем Send('{CTRLDOWN}') Send('{CTRLUP}'), от залипаний Ctrl?




© OSzone.net 2001-2012