Что нового

действия с текстом и нажатия комбинаций клавиш в активном окне

Alexey

Новичок
Сообщения
171
Репутация
0
Версия AutoIt: 3.3.14.2
Описание:
- имеется открытое и активное окно блокнота (notepad2), в котором перед запуском скрипта всегда открыт 1 несохранённый текстовый файл с названием 1 и расширением cue
- но путь всегда разный, так как файлы будут всегда разными и находиться будут всегда в разных каталогах
- окно блокнота остаётся активным всё время (во время работы скрипта я никаких окон трогать не буду)

возможен ли скрипт, после запуска которого автоматически выполнялись бы разные действия?
видимо, с какой-то очень мелкой задержкой между действиями, чтобы все корректно выполнялись. действия нужны именно в таком порядке:
1) нажатие ctrl + v

2) замена текста
CDImage.wav
на
1.flac
заменяемый фрагмент всегда имеется только в единственном экземпляре (в первой строке)

3) после каждого такого текстового фрагмента:
AUDIO
вставка такой новой строки (в её начале 4 пробела):
Код:
    TITLE ""
5 символов AUDIO:
- всегда расположены в конце строк
- могут быть в разных количествах (от двух и более)

4) однократный запуск вот этого стороннего готового скрипта (суть его в перемещении строк нужным образом):
Код:
#include <Array.au3>
#include <WinAPISys.au3>

Global $hWnd, $sData, $Window = '[REGEXPCLASS:(?i).*?Pad.*?]'

$hWnd = WinActive($Window)
If Not $hWnd Then Exit

_FixAccelHotKeyLayout()

$sData = ClipGet()
_Send('c')

Local $TSong, $Size, $sTextMod, $sText = ClipGet()
If $sText Then
    $Pos = StringInStr($sText, 'INDEX', 2, -1)
    $TSong = StringRegExp($sText, '.*\V', 3, $Pos)
    $Size = UBound($TSong)
    Select
        Case $Size > 1 And Not @error
          $sTextMod = StringRegExp($sText, '((.*\R\h+?)+' &$TSong[0]&')', 1)
          If IsArray($sTextMod) Then $sText = $sTextMod[0]
            For $i = 1 To $Size - 1
                $sText = StringReplace($sText, 'TITLE ""', 'TITLE "' & $TSong[$i] & '"', 1)
            Next
            ClipPut($sText)
            If BitAND(WinGetState($hWnd), 16) Then ContinueCase
            _Send('v{HOME}')
            ContinueCase
        Case Else
            ClipPut($sData)
            Exit
    EndSelect
EndIf

Func _FixAccelHotKeyLayout()
    Static $iKbrdLayout, $aKbrdLayouts
    If Execute('@exitMethod') <> '' Then
        Local $iUnLoad = 1
        For $i = 1 To $aKbrdLayouts[0]
            If Hex($iKbrdLayout) = Hex('0x' & StringRight($aKbrdLayouts[$i], 4)) Then
                $iUnLoad = 0
                ExitLoop
            EndIf
        Next
        If $iUnLoad Then
            _WinAPI_UnloadKeyboardLayout($iKbrdLayout)
        EndIf
        Return
    EndIf
    $iKbrdLayout = 0x0409
    $aKbrdLayouts = _WinAPI_GetKeyboardLayoutList()
    _WinAPI_LoadKeyboardLayout($iKbrdLayout, $KLF_ACTIVATE)
    OnAutoItExitRegister('_FixAccelHotKeyLayout')
EndFunc

Func _Send($Letter)
    SendKeepActive($hWnd)
    Send('{CTRLDOWN}a' &$Letter& '{CTRLUP}')
    SendKeepActive('')
EndFunc


5) нажатие ctrl + s
6) нажатие alt + f4

Примечания:
- перед запуском скрипта курсор расположен в самом начале файла
- окно блокнота принадлежит файлу notepad.exe
- window class: Notepad2
- window caption: всегда разный. в конце всегда такие символы:
1.cue - Notepad2

- кодировка: utf-8 (не должна меняться)
- match case: во всех случаях должен учитываться
- не знаю, возможно ли это, но хотелось бы обойтись без множественных сохранений и переоткрываний текстового файла во время работы скрипта

размещённый ниже код - это единственное, что я более-менее по теме сумел найти и при этом получить что-то работающее
с оговоркой, что это только мелкий кусочек от нужного результата, да и то не особо помогающий:
Код:
#Include <File.au3>

If (_ReplaceStringInFile("C:\test.cue", "example-1", "example-2") = 0) Then
	ConsoleWriteError("cannot find [example-1] in [test.cue]" & @CRLF)
EndIf
 

hedji

Продвинутый
Сообщения
409
Репутация
94
OffTopic:

Зачем менять файл в блокноте?
Почему нельзя менять файл напрямую из AutoIT?
Код:
#include <File.au3>
_FileWriteToLine()

 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
hedji
не знаю, может быть и можно. мне главное, чтобы скрипт задачу выполнял

просто в данном случае не понимаю, что означают слова "менять файл"
так как нет задачи менять файл. есть необходимость менять содержимое файла

что касается _FileWriteToLine, то в справке написано:

1) Writes text to a specific line in a file
но пункт 3 в моём описании прямо показывает, что никаких "specific line" не будет известно заранее
в каждом случае будут разные строки и разное их количество
это с пунктом 2 проще: там строка одна и она заранее известна

2) $sFilePath - The file to write to
путь заранее не известен тоже - он всегда разный (об этом я упомянул)
 

hedji

Продвинутый
Сообщения
409
Репутация
94
Файлов cue у меня нет, делал на примере txt
Код:
#include <File.au3>

FileDelete("d:\all_files.txt")
$CMD = "cd D:\ & dir/s/b *.txt >> d:\all_files.txt"
RunWait(@ComSpec & " /c " & $CMD) ;получаем список всех файлов txt на диске D:
$all_files = FileReadToArray("d:\all_files.txt") ;записываем его в массив
For $file in $all_files
    $current_file = FileReadToArray($file) ;каждый из файлов попеременно читаем в массив
    $j=0
    For $i=0 To UBound($current_file)-1 ;перебираем построчно
        If $current_file[$i]="CDImage.wav" Then ;если строка равна CDImage.wav, то вместо неё пишем 1.flac
            _FileWriteToLine($file, $i+1+$j, "1.flac", 1)
        EndIf
        If $current_file[$i]="AUDIO" Then
            _FileWriteToLine($file, $i+2+$j, "    TITLE", 0) ;если строка равна AUDIO, то после неё пишем     TITLE
            $j = $j + 1
        EndIf
    Next
Next
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
hedji, пока совсем не получается сообразить, как мне может этот код помочь
на данный момент не могу его даже протестировать, поскольку многое непонятно:

d:\all_files.txt - это временный файл, в фоновом режиме создаваемый скриптом и затем скриптом удаляемый?

допустим, в строке 2 для себя могу изменить d:\all_files.txt на C:\WINDOWS\Temp\auto-it-test-script.txt
в строке 3, соответственно, cd D:\ меняется на cd C:\WINDOWS\Temp\, а d:\all_files.txt меняется на C:\WINDOWS\Temp\auto-it-test-script.txt

но в строке 4 фразу "получаем список всех файлов txt на диске D" как понимать? мне не нужно получать список всех файлов txt/cue на диске D/C/E...
потому как если получать, то в моём случае будут десятки тысяч (если, конечно, я корректно уловил смысл комментариев в этом коде)

в строке 9 есть фраза "если строка равна CDImage.wav"
но строка никогда не будет равна CDImage.wav (CDImage.wav - это всегда только часть строки)
тоже самое касается AUDIO (AUDIO - это всегда только часть строки)
 

hedji

Продвинутый
Сообщения
409
Репутация
94
d:\all_files.txt - это временный файл, в фоновом режиме создаваемый скриптом и затем скриптом удаляемый?
- да

cd D:\ & dir/s/b *.txt >> d:\all_files.txt - получает список txt файлов на диске D:\, если у вас все cue файлы лежат в папке C:\WINDOWS\Temp\, то да, если они где-то на диске С:\, то cd С:\ & dir/s/b *.txt >> d:\all_files.txt Если вы заранее знаете какой файл хотите обработать, то эту часть можно пропустить и дополнить код выбором конкретного файла

замените равенство поиском вхождения подстроки
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
если у вас все cue файлы лежат в папке C:\WINDOWS\Temp\
все cue-файлы лежат примерно в 60 000 каталогах, которые лежат на дисках C, D, E, F, G (в будущем набор этих логических дисков будет многократно меняться)

Если вы заранее знаете какой файл хотите обработать
абсолютно заранее не знаю и знать никогда не буду
боюсь, как бы задача не оказалась гораздо более сложной, чем она, возможно, со стороны показалась вначале
 

hedji

Продвинутый
Сообщения
409
Репутация
94
1) Получить список всех дисков в системе
Код:
DriveGetDrive()

2) Найти все файлы cue на каждом диске из п.1
Код:
dir/s/b *.cue >> d:\all_files.txt
3) В каждом файле из п.2. найти вхождение подстроки и поменять нужные строки
Код:
StringInStr($current_file[$i], "CDImage.wav")


Если бы вы выложили пример пары файлов, тестировали бы на реальных файлах.
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
В каждом файле из п.2. найти вхождение подстроки и поменять нужные строки
в каждом не нужно (нужно только в одном файле)

нет ли какого-то куда более простого подхода?
ведь всего лишь требуется обработать короткое текстовое содержимое одного открытого файла в активном окне блокнота

то есть, дикостью кажется перебирание всех дисков в системе или всех десятков тысяч файлов с таким же расширением лишь для того чтобы внести мелкие изменения только в 1 уже открытый текстовый файл (который находится в активном окне, не фоновом)

пример файла:
Код:
FILE "CDImage.wav" WAVE
  TRACK 01 AUDIO
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    INDEX 01 03:54:00
  TRACK 03 AUDIO
    INDEX 01 07:30:02

[тут всегда несколько строк (с разным текстом): от двух до примерно сотни]
[тут всегда пустая строка]
пример пары файлов не нужен, так как разница всегда будет только:
- в цифрах (например, не 03:54:00, а 04:37:13)
- в содержимом тех строк, которых "от двух до примерно сотни", и которые, по сути, в этом скрипте не участвуют


если пока вести речь только о пунктах 2-3 (из первого сообщения), то вот конкретный пример:
вот это имеется прямо перед запуском скрипта:
Код:
FILE "CDImage.wav" WAVE
  TRACK 01 AUDIO
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    INDEX 01 03:54:00
  TRACK 03 AUDIO
    INDEX 01 07:30:02

Title 01
Title 02
Title 03
вот это должно получиться сразу после завершения работы скрипта:
Код:
FILE "1.flac" WAVE
  TRACK 01 AUDIO
    TITLE ""
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    TITLE ""
    INDEX 01 03:54:00
  TRACK 03 AUDIO
    TITLE ""
    INDEX 01 07:30:02

Title 01
Title 02
Title 03
 

hedji

Продвинутый
Сообщения
409
Репутация
94
в каждом не нужно (нужно только в одном файле)

нет ли какого-то куда более простого подхода?
ведь всего лишь требуется обработать короткое текстовое содержимое одного открытого файла в активном окне блокнота

абсолютно заранее не знаю и знать никогда не буду

Определитесь какую задачу решаем: перелопатить скриптом 60000 файлов, или взять один конкретный файл и в нем поменять.
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
взять 1 конкретный файл и в нём поменять

в пункте 4 (из первого сообщения этой темы) размещён полностью рабочий и проверенный временем скрипт от Alofa
которого, пользуясь случаем, ещё раз благодарю за этот полезный скрипт и прошу, если это не сложно, помочь с добавлением туда хотя бы пунктов 2-3 (из первого сообщения этой темы), которые очень похожи по функционалу на то, что скрипт уже умеет делать

то есть, пункт 4 уже готов в виде скрипта, а смысл в том, чтобы этот готовый скрипт перед тем, что он делает сейчас (специальным образом перемещает те самые строки, которых "от двух до примерно сотни"), выполнял бы ещё пункты 2-3
 
A

Alofa

Гость
Alexey сказал(а):
... если это не сложно...
Да вроде как сложностей быть не должно (за исключением того, что пока PC под рукой нет).
Чтобы избежать разногласий, как в Этой теме, хочу сразу уточнить один момент. Возможно два (как я это вижу) подхода для реализации вашей задачи:
Вар.1) Вычисляем какой файл открыт в активном окне блокнота, закрываем это окно и далее работаем с файлом.
Вар.2) Работаем только с окном блокнота при помощи "костылей".
Какой из вариантов вы хотите увидеть?

P.s: а возможно обойтись вообще без блокнота: создать программу со своим окном и кидать туда файлы для преобразования.
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
пусть будет вариант 1
только я не сразу сообразил, что было бы немного лучше, если бы скрипт работал не c активным окном блокнота, а с последним окном блокнота в панели задач
и работал вне зависимости от состояния последнего окна блокнота (активное/неактивное)

то есть, если это частичное изменение реализуемо без проблем, то вариант 1 будет звучать так:
- вычисляем, какой файл открыт в последнем окне блокнота в панели задач (системная настройка "group similar taskbar buttons" всегда выключена)
- это окно с несохранённым файлом, поэтому сохраняем файл
- закрываем окно
- далее работаем с файлом
- работа заключается в выполнении по очереди 6 пунктов (из первого сообщения этой темы)
из которых пункт 6 теперь не нужен, поскольку закрывать будет нечего - вся работа выполняется при закрытом файле
выполнение пункта 1 подразумевает, что курсор находится в самом начале файла

нужное для обработки скриптом окно блокнота почти всегда будет не единственным в панели задач, где разных окон блокнота может быть вплоть до нескольких десятков
надеюсь, это не станет проблемой для скрипта, то есть, он сможет корректно работать только с одним нужным окном блокнота
и сможет никак не трогать другие окна блокнота, в которых будут открыты другие файлы, в том числе, возможно, и несохранённые
 
A

Alofa

Гость
Alexey сказал(а):
пусть будет вариант 1...
Почитал предыдущую Вашу тему, эту перечитал и пошел по пути наименьшего сопротивления - т.е. сделал вариант №2.
Код:
#include <GuiToolBar.au3>
Local $hWnd, $hControl, $hToolbar, $aText, $sText, $aTitles, $sClip
Local $sFlacFile = '1.flac'

$hWnd = WinWaitActive('[REGEXPCLASS:(?i).*Pad.*]', '', 5)
$hControl = ControlGetHandle($hWnd, '', 'Scintilla1')
$hToolbar = ControlGetHandle($hWnd, '', 'ToolbarWindow321')
If (Not $hWnd) Or (Not $hControl) Or (Not $hToolbar)Then Exit 11

; ControlSend($hWnd, '', $hControl, '+{INS}') ; 1) нажатие ctrl + v (не понял, а нужно ли?)

$sText = ControlGetText($hWnd, '', $hControl)
If Not StringStripWS($sText, 8) Then Exit 22

$sText = StringRegExpReplace($sText, '(?is)(FILE\h*")[^"]+("\h*WAVE.+INDEX(?-s).+\R)\R+((?s).+)', '${1}' & $sFlacFile & '$2<@>$3') ; 2) попутно замена текста CDImage.wav на 1.flac

$aText = StringSplit($sText, '<@>', 1)
If $aText[0] <> 2 Then Exit 33

$aTitles = StringSplit($aText[2], @CRLF, 1)
If @error Then Exit 44

For $i = 1 To $aTitles[0] ; Пункт 3) и 4)
	$aText[1] = StringRegExpReplace($aText[1], '(?i)(AUDIO)(\s+INDEX)', '$1' & @CRLF & '    TITLE "' & $aTitles[$i] & '"$2', 1)
Next

ControlSetText($hWnd, '', $hControl, '')
$sClip = ClipGet()
ClipPut($aText[1])
ControlSend($hWnd, '', $hControl, '+{INS}') ; Вставить преобразованный текст
_GUICtrlToolbar_ClickIndex($hToolbar, 3) ; Coхранить
WinKill($hWnd) ; Закрыть окно
ClipPut($sClip)
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
нажатие ctrl + v (не понял, а нужно ли?)
каждый раз к моменту запуска скрипта в буфере обмена будет немного специально подготовленного текста, который должен быть вставлен в окно блокнота. поэтому нужно ctrl+v

хочу уточнить непонятные для меня нюансы:

1) в строке 23 указано: Пункт 3) и 4)
но пункт 4 - это из другой темы предыдущий скрипт, по размеру превышающий весь этот
верно ли понимаю, что пункта 4 тут в действительности нет?
или весь тот скрипт теперь неимоверно сокращён до нескольких строк? (имеются в виду строки 27-30)

2) верно ли понимаю, что замена текста CDImage.wav на 1.flac реализована как-то хитро?
поскольку ни CDImage, ни wav не упоминаются в скрипте в явном виде

3) верно ли понимаю, что этому варианту скрипта требуется именно открытое окно блокнота?

добавлено позднее:
последнюю строку следует читать как:
3) верно ли понимаю, что этому варианту скрипта требуется именно активное окно блокнота?
 
A

Alofa

Гость
Скрипт всегда ждет (не более 5 секунд) активное окно блокнота2 со следующим содержанием:
Alexey сказал(а):
... пример:
вот это имеется прямо перед запуском скрипта:
Код:
FILE "CDImage.wav" WAVE
  TRACK 01 AUDIO
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    INDEX 01 03:54:00
  TRACK 03 AUDIO
    INDEX 01 07:30:02

Title 01
Title 02
Title 03
...

и делает из всего этого:
Код:
FILE "1.flac" WAVE
  TRACK 01 AUDIO
    TITLE "Title 01"
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    TITLE "Title 02"
    INDEX 01 03:54:00
  TRACK 03 AUDIO
    TITLE "Title 03"
    INDEX 01 07:30:02
с сохранением и закрытием окна.



Добавлено:
Сообщение автоматически объединено:

Alexey сказал(а):
... Пункт 3) и 4)
но пункт 4 - это из другой темы предыдущий скрипт...
Решение пункта 4) тоже здесь присутствует, но только в другом исполнении.
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
не работает совсем. сначала я пробовал с включённой строкой 10, так как от скрипта нажатие ctrl+v всё-таки требуется
в итоге было испорчено содержимое другого открытого, но не активного окна блокнота (с этим окном скрипт не должен был вообще что-либо делать)
из окон блокнота оно предыдущее на панели задач (предпоследнее)
и туда скрипт вставил содержимое буфера обмена

затем я пробовал с выключённой строкой 10 (перед запуском скрипта ctrl+v нажал сам). в итоге скрипт ничего не сделал

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

1) от скрипта не требуется ждать 5 или сколько-то секунд, он должен исполняться сразу после того как был мной запущен (и закрываться сам после выполнения)
раз уж в данном виде скрипт всё равно не работает, не будет ли проще и надёжнее реализовать его в том виде, о котором я просил?
то есть, пусть скрипт просто выполняется применительно к последнему окну блокнота в панели задач
вне зависимости от его состояния (активное/неактивное)

Скрипт всегда ждет (не более 5 секунд) активное окно блокнота2 со следующим содержанием:
2) на всякий случай упомяну, что:
"следующего содержания" не будет никогда, так как строки Title 01 и Title 02 и Title 03 являются примером (на их местах всегда какие-то другие слова)
этих строк в данном примере 3, а в реальности этих строк может быть другое количество

эти первые 7 строк примера являются содержимым буфера обмена, которое вставляется по нажатию на ctrl+v:
Код:
FILE "CDImage.wav" WAVE
  TRACK 01 AUDIO
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    INDEX 01 03:54:00
  TRACK 03 AUDIO
    INDEX 01 07:30:02
опять же, это содержимое всегда похоже визуально, но всегда разное (отличается количество строк и отличаются цифры)

если по работе скрипта требуются какие-то дополнительные пояснения с моей стороны, то они будут даны обязательно, это не проблема
 

Khaibit

Осваивающий
Сообщения
103
Репутация
25
Alexey сказал(а):
попытаюсь озвучить максимально чётко свои соображения
Вот уже на протяжении дюжины сообщений у вас это не получается.
Вот, на пример, когда вы приходите к сапожнику, вы тоже начинаете рассказывать ему как нужно делать?
Пока вы не скажите что это за файл, как выглядит, откуда берется, как он попадает в блокнот, что получается в результате..., ничего не получится.
 
A

Alofa

Гость
OffTopic:
Дааа, опять проблемы со взаимопониманием


Alexey сказал(а):
... было испорчено содержимое другого открытого, но не активного окна блокнота...
Быть такого не может. Скрипт не сдвинется с места пока не найдет АКТИВНОЕ окно с классом "Notepad2".

Alexey сказал(а):
... он должен исполняться сразу после того как был мной запущен (и закрываться сам после выполнения)...
Именно так он и делает.

Alexey сказал(а):
... на всякий случай упомяну, что:
"следующего содержания" не будет никогда...
Да? А как же это:
Alexey сказал(а):
... если пока вести речь только о пунктах 2-3 (из первого сообщения), то вот конкретный пример:
вот это имеется прямо перед запуском скрипта:
Код:
FILE "CDImage.wav" WAVE
  TRACK 01 AUDIO
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    INDEX 01 03:54:00
  TRACK 03 AUDIO
    INDEX 01 07:30:02

Title 01
Title 02
Title 03
вот это должно получиться сразу после завершения работы скрипта:
Код:
FILE "1.flac" WAVE
  TRACK 01 AUDIO
    TITLE ""
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    TITLE ""
    INDEX 01 03:54:00
  TRACK 03 AUDIO
    TITLE ""
    INDEX 01 07:30:02

Title 01
Title 02
Title 03
Alexey сказал(а):
На всякий случай упомяну, что далее наступает очередь пункта 4), а что там должно быть выполнено?
Alexey сказал(а):
... однократный запуск вот этого стороннего готового скрипта...
К несчастью (наверное) я его вспомнил, почитайте тему откуда он и припомните тоже.
А вот что по вашему мнению он (этот кусок кода) должен делать?

Alexey сказал(а):
... эти первые 7 строк примера являются содержимым буфера обмена, которое вставляется по нажатию на ctrl+v...
То есть, если я вас правильно понимаю, это и есть тот текст с которым нужно работать, не трогая в файле все остальное?
Это я к чему: ведь можно сразу вставлять в поле блокнота уже готовый, обработанный текст.
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
Быть такого не может
я написал как есть. ничего не выдумывал и не наговаривал

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

но самое главное всё-таки другое: что конкретно мне ещё нужно написать/дорассказать/пояснить/уточнить, чтобы мои слова/просьбы были услышаны и этот скрипт стал рабочим?
услышаны, а не проигнорированы, как это было неоднократно
 
Верх