1 (изменено: upsi_daezium, 2016-08-16 14:10:57)

Тема: AHK: Скрипт сохранение имени файла с датой и по хоткею

День добрый, новичок на форуме, так что ногами сильно не пинайте.
Мне нужен такой скрипт:
скрипт должен висеть в памяти и при появления окна сохранение файла в любой программе нужно чтобы он добавлял в имя файла вначале дату (ГГГГММДД), в самом имени файла была замена @ на (A) и + на plus, если имя файла длинее 192 символов то сократит его, а в конце имени файла добавить @ и + . Но, если файл уже начинается с  такой даты, то ничего не менять.
Так же допустим при переименовании (клавиша Ф2) файла или папки, нужно, чтобы такая замена работала по хоткею.
Спасибо.

2

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

скрипт должен висеть в памяти и при появления окна сохранение файла в любой программе

Нужно будет создать группу окон и занести в неё все возможные окна. Команда GroupAdd.

3

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

ypppu
Дак, вроде есть маска "сохран*" (еслиЗаголовокОкна), тогда...?
Мне сложно разобраться, я гуманитарий

4

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Ну если шаблон "сохран*" - надёжная примета, то группу можно не создавать.

нужно чтобы он добавлял в имя файла вначале дату (ГГГГММДД)

Простые замены можно делать командой StringReplace. Тут два пути: скопировать строку с именем файла в буфер, произвести замену и вставить обратно. Или считать содержимое элемента управления командой ControlGet или ControlGetText, затем произвести замену командой controlset или ControlSetText.

5

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

ypppu
Какая примета более надежная я не знаю, мне надо чтобы при сохранении срабатывало.
Можете написать код, а то я совсем не понимаю, читаю документацию, все по отдельности понятно, а вместе в голове пока не складывается, непонимаю пока, как мне подступиться к этой задаче.

6

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Могу помочь разобраться, но код писать не буду. Я разбил задачу на несколько этапов и подсказал команды. Документация вся есть, перевод на русский есть. Если возникнут вопросы - спрашивайте.

7

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею


Menu, Tray, Icon, stobject.ICO, 1

SetTitleMatchMode, 1

WinWaitActive, ahk_class #32770
ControlGetText, fileName, Edit1, ahk_class #32770
FormatTime, date,, yyMMdd
ControlSetText, Edit1, %date% %fileName%, ahk_class #32770

; ::dd:: 
; FormatTime, date,, yyMMdd
; SetKeyDelay 0 
; Send %date%
return

Вот наваял, в принципе работает, но только один раз, потом скрипт завершается, а вот в закоментированный код почему-то висит и работает в памяти всегда.
По поводу класса окна #32770, это в вин7, а ХР и в 10 класс такой же, или он меняется?
Еще не нашел как в регулярных выражениях сделать замену перед расширением файла, если оно есть, там нужно идти с конца строки.
Потом когда доработаю в скрипт надо присовокупить возможность делать тоже самое с выделенным текстом по горячей клавише.

8

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Да, в XP класс тоже #32770.

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

В закомментированном коде присутствует строка автозамены, вероятно она не даёт скрипту завершиться.


Чтобы скрипт работал постоянно, существует директива #Persistent. Но Вам наверное лучше будет организовать цикл.

;#Persistent
;Menu, Tray, Icon, stobject.ICO, 1

SetTitleMatchMode, 1

Loop
{
WinWaitActive, ahk_class #32770
ControlGetText, fileName, Edit1, ahk_class #32770
FormatTime, date,, yyMMdd
ControlSetText, Edit1, %date% %fileName%, ahk_class #32770
WinWaitClose, ahk_class #32770
}

; ::dd:: 
; FormatTime, date,, yyMMdd
; SetKeyDelay 0 
; Send %date%
;return

9

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

ypppu
Спасибо, но это вставляет дату постоянно, пока окно открыто и в фокусе, а мне нужно один раз и все.

10

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

У меня всё работает как задумано. Или в Win7 какие-то кардинальные изменения. Или проверьте всё внимательно.

11

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

ypppu
Извиняюсь, забыл закоментировать return, но когда я сделал это, скрипт срабатывает один раз и потом только висит, если вызвать окно сохранения в другой (или той же самой) программе, там он уже не срабатывает.

12

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

upsi_daezium, покажите, в каком виде запускаете код.

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

13

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Вот несколько доработанный скрипт:


Menu, Tray, Icon, stobject.ICO, 1

SetTitleMatchMode, 1

maxFileNameLenght = 19

Loop {
	WinWaitActive, ahk_class #32770
	ControlGetText, fileName, Edit1, ahk_class #32770
	SplitPath, fileName, , , fileExt, fileName1
	fileName := SubStr(fileName, 1, maxFileNameLenght) 
	FormatTime, date,, yyMMdd
	ControlSetText, Edit1, %date% %fileName1% %fileExt%, ahk_class #32770
	WinWaitClose, ahk_class #32770
}

Добавлена функция сплитпат, вместо регулярных выражений. Ограничение максимальной длины имени файла.
Проверял дома на 10х64 работает как надо, срабатывает каждый раз. А на работе 7х64, стабатывает 1 раз для одного окна, потом иконка висит, а ничего не меняется. Пока не могу понять в чем тут дело.
Как вам доработанный скрипт, мне кажется получилось неплохо, я быстро прогрессирую.

14

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

На WinXP работает.
Чтобы найти проблему, зайдите в "lines most recently executed" и посмотрите, на чём скрипт остановился, что он делает.

15

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

WinWaitActive, ahk_class #32770

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

16

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Malcev пишет:
WinWaitActive, ahk_class #32770

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

О, спасибо! Действительно в этом было дело, а то я уже голову сломал.
А можно переделать скрипт, чтобы не было такой ситуации?
И еще хочу ввести проверку, чтобы имя файла не менялось, если оно уже соответствует формату (ГГММДД), делаю так:


	if RegExMatch (fileName, "^\d{6}", fileNameData){
		Msgbox % fileNameData
	}

Но пока ничего не возвращает

17

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Вам нужно, чтобы скрипт всё время искал окна #32770, но игнорировал окна #32770, в которых он уже отработал. И чтобы после их закрытия переставал их игнорировать.
Наверное нужен какой-то динамически обновляющийся перечень, массив.

18

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

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


; Читаем значение из реестра скрыты ли расширения типов файлов.
; Нужно для корректного добавления текста в конец имени.
RegRead,HideFileExt,HKEY_CURRENT_USER,Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced,	HideFileExt


;Бесконечный цикл.
Loop
{
	;Ожидаем окно сохранения класса 32770
	WinWaitActive Сохранение ahk_class #32770
	;Если мы тут значит скрипт нашел окно...
	;Устанавливаем это окно по умолчанию для подпрограмм autohotkey'я.
	WinExist("Сохранение ahk_class #32770")

	;Узнаем значение поля с именем файла. Заносим в переменную Text.
	ControlGetText,Text,Edit1

	; Нужно проверить есть ли дата в начале.
	; Создаем переменную формата YYYYMMDD.
	; YYYY - год. Четырехзначное значение(пример 2016)
	; MM - Месяц. Двухзначное значение(пример 01)
	; DD - День. Двухзначное значение(пример 01)
	date := 20 . SubStr(Text,1,6)
	
	; Если это условие ложь значит в начале нет даты.
	if date is Not time
	{
		; Продолжаем если нет даты...
		; Перезапишит переменную date с сегодняшним числом.
		FormatTime, date,, yyMMdd

		; Если система показывает типы файлов, то в переменной Text убераем окончание и заносим в Extension.
		IfEqual,HideFileExt,0,SplitPath,Text,,,Extension,Text
		; Если переменная с типом файла не пуста, то в начале добавим точку.
		IfNotEqual,Extension,,try Extension := "." Extension
		
		; Замена и сокращение символов.
		Text := StrReplace(Text,"@","A") 
		Text := StrReplace(Text,"+","plus") 
		Text := SubStr(text,1,192)
		
		; Новое значение Text будет равно "date + Text + свой текст + Extension".
		Text := date . Text . "@+" . Extension

		; Устанавливаем новый текст в контрол.
		ControlSetText, Edit1, % Text
		
		; EM_SETSEL это - сообщение для выделения текста в edit поле от определенного символа до другого.
		; Выделяем все символы(делаем тот же эффект выделения что есть по умолчанию)
		; Если второй параметр указать так же % StrLen(Text), то каретка перейдет в конец строки без выделения.
		; Если убрать эту строку вообще, то каретка будет в самом начале строки.
		SendMessage, 0xB1,% 0, % StrLen(Text),Edit1	; EM_SETSEL
	}

	; Ожидаем закрытия.
	WinWaitClose
}

19

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

ypppu спасибо за идею, но это уже какие-то сложные (для меня во всяком случае) материи, так что придется обойтись простым переименованием.
yalanne снимаю шляпу, большое дело, я проверил, скрипт работает замечательно.  Я тоже без дела не сидел, вот мой вариант (с вашим, конечно, не сравнить):


Menu, Tray, Icon, stobject.ICO, 1

SetTitleMatchMode, 1

maxFileNameLenght = 192 ; максимальная длина строки имени файла
tags := " tags "

Loop 
{
	WinWaitActive, ahk_class #32770 ; ahk_class #32770 класс окна сохранения
	ControlGetText, fileName, Edit1, ahk_class #32770
	if not RegExMatch(fileName, "^\d{6}" )
  {	
    SplitPath, fileName, , , fileExt, fileName
    fileName := SubStr(fileName, 1, maxFileNameLenght) 
    if fileExt fileExt := "."fileExt ; если расширение есть, то добавляем к нему точку  
    FormatTime, date,, yyMMdd
    ControlSetText, Edit1, %date% %fileName%%tags%%fileExt%, ahk_class #32770 
    Send ^a
	}
	WinWaitClose, ahk_class #32770

yalanne, ваш скрипт работает, за счет добавления к классу окна названия окна, перестал срабатывать где не надо, но, насколько я понимаю, там написано "Сохранение" (это для вин10), а в 7 написано "Сохранить" (щас не могу проверить, семерка у меня на работе), так что, может не срабатывать. А в английских программах написано "Save as", так что в них не работает, можно ли добавить такой вариант?
У меня еще вопрос, мне нужно еще переименовывать файлы под такой шаблон, думаю, что смогу переписать ваш код, чтобы он срабатывал от горячих клавиш, и переименовывал выделенный текст где угодно, только я пока не понимаю, как это включить в общую программу?

20

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Небольшой вопрос, а как можно управлять кореткой (курсором), например, я хочу чтобы она стояла после @, и можно ли сделать определенное выделение в поле?
Не нашел понятной документации по EM_SETSEL

21 (изменено: yalanne, 2016-08-24 18:12:12)

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Пока что без клавиш...
Может работать сразу снесколькими окнами сохранения(например от notepad и chrome browser и тд)

; Замена запущенной программы
#SingleInstance force


; Читаем значение из реестра скрыты ли расширения типов файлов.
; Нужно для корректного добавления текста в конец имени.
RegRead,HideFileExt,HKEY_CURRENT_USER,Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced,	HideFileExt



; Создаем группу с окнами сохранений.
GroupAdd, SaveDialog,Save As ahk_class #32770
GroupAdd, SaveDialog,Сохранение ahk_class #32770
GroupAdd, SaveDialog,Сохранить как ahk_class #32770


loop
{
	; ожидаем возможные окна.
	WinWaitActive, ahk_group SaveDialog
	
	;Окно найдено.
	
	; В переменной ListSaveDialogOpened хрянятся id окон которые были уже открыты.
	;	Если переменная пустая, то условие хоть как истина.
	;	Иначе проверяем наличие id нового открытого окна в переменной.
	;	Если там этого id нет то условие истина.
	;Функция WinActive() сразу же делает это окно по умолчанию для ahk подпрограмм.
	;Оператор '~=' то же самое что и RegExMatch.
	;	(^|`|) означает что до начала номера id должно быть либо начало переменной, либо символ '|'
	;	($|`|) означает что после номера id должно быть либо конец переменной, либо символ '|'
	If ListSaveDialogOpened ? Not (WinActive("ahk_group SaveDialog") ~= ("(^|`|)" ListSaveDialogOpened "($|`|)") ) : true
	{
		;Окно нам подходит, теперь можно работать с ним.
		
		; Так же добавим его id в переменную что бы в последующие разы игнорило.
		ListSaveDialogOpened .= (ListSaveDialogOpened ? "|" : "")	WinActive()
		
		
		;Узнаем значение поля с именем файла. Заносим в переменную Text.
		ControlGetText,Text,Edit1
			
		; Если система показывает типы файлов, то в переменной Text убераем окончание и заносим в Extension.
		IfEqual,HideFileExt,0,SplitPath,Text,,DirFile,Extension,Text
		; Если переменная с типом файла не пуста, то в начале добавим точку.
		IfNotEqual,Extension,,try Extension := "." Extension

		; Нужно проверить есть ли дата в начале.
		; Создаем переменную формата YYYYMMDD.
		; YYYY - год. Четырехзначное значение(пример 2016)
		; MM - Месяц. Двухзначное значение(пример 01)
		; DD - День. Двухзначное значение(пример 01)
		date := 20 . SubStr(Text,1,6)
		
		; Если это условие ложь значит в начале нет даты.
		if date is Not time
		{
			; Продолжаем если нет даты...
			; Перезапишит переменную date с сегодняшним числом.
			FormatTime, date,, yyMMdd
			
			; Замена и сокращение символов.
			Text := StrReplace(Text,"@","A") 
			Text := StrReplace(Text,"+","plus") 
			Text := SubStr(text,1,192)
			
			; Новое значение Text будет равно "date + Text + свой текст + Extension".
			Text := date . Text . "@+" . Extension

			; Устанавливаем новый текст в контрол.
			ControlSetText, Edit1, % Text
			
			; EM_SETSEL это - сообщение для выделения текста в edit поле от определенного символа до другого.
			; Функция InStr выдает позицию искомого текста(всегда начало слева), не учитывая регистр и поиск должен быть с конца.
			SendMessage, 0xB1,% InStr(Text,"@",0,0) , % InStr(Text,"@",0,0),Edit1	; EM_SETSEL
		}
	}
	; Конец этого условия значит что все нужные манипуляции с окном сделаны.
	
	;Ожидаем его деактивации из фокуса.
	WinWaitNotActive
	
	; Если окон сохранения больше вообще нет, то очищаем переменную.
	If Not WinExist("ahk_group SaveDialog")
		ListSaveDialogOpened := ""
		
	; Если же окна сохранения еще существуют, то те с которым
	;	была работа будут игнорится в следующем цикле.
}


А надо что бы была работа сразу с несколькими выделенными файлами?

22 (изменено: ypppu, 2016-08-25 20:08:33)

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

Низкий вам поклон, за проделанную работу. Первый скрипт меня впечатлил, а это уже совсем за гранью возможного.
Последний вопрос относится к скрипту переименования файлов по по клавише? Если такое возможно сделать, то конечно да.
Я, кстати, тоже не сидел без дела и кое-что наваял:


mButton::
; Читаем значение из реестра скрыты ли расширения типов файлов.
; Нужно для корректного добавления текста в конец имени.
RegRead,HideFileExt,HKEY_CURRENT_USER,Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced,	HideFileExt

Send {F2}
Send ^a
Send ^x
;Узнаем значение поля с именем файла. Заносим в переменную Text.
	Text = %clipboard%
  oldText = %clipboard%
  
	; Нужно проверить есть ли дата в начале.
	; Создаем переменную формата YYYYMMDD.
	; YYYY - год. Четырехзначное значение(пример 2016)
	; MM - Месяц. Двухзначное значение(пример 01)
	; DD - День. Двухзначное значение(пример 01)
	date := 20 . SubStr(Text,1,6)
	
	; Если это условие ложь значит в начале нет даты.
	if date is Not time
	{
		; Продолжаем если нет даты...
		; Перезапишит переменную date с сегодняшним числом.
		FormatTime, date,, yyMMdd

		; Если система показывает типы файлов, то в переменной Text убераем окончание и заносим в Extension.
		IfEqual,HideFileExt,0,SplitPath,Text,,,Extension,Text
		; Если переменная с типом файла не пуста, то в начале добавим точку.
		IfNotEqual,Extension,,try Extension := "." Extension
		
		; Замена и сокращение символов.
		Text := StrReplace(Text,"@","(A)") 
		Text := StrReplace(Text,"+","plus") 
		Text := SubStr(text,1,192)
		
		; Новое значение Text будет равно "date + Text + свой текст + Extension".
		Text := date . " " . Text . " @ + " . Extension
    clipboard = %Text%
  }
  else
  {
    clipboard =%oldText%
  }
Send ^v

Это работает (с некоторыми оговорками) если запустить отдельным скриптом.

23

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

upsi_daezium, избегайте избыточного цитирования.

24

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

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


SetTitleMatchMode, 2 
SendMode, input
GroupAdd, RenameGroup
GroupAdd, RenameGroup, Program Manager ahk_class Progman
GroupAdd, RenameGroup, ahk_class CabinetWClass

#IfWinActive ahk_group RenameGroup
$F2::
   Islnk:=0
   Clipboard =
   Send ^{vk43}
   ClipWait
   IsDir := InStr(FileExist(Clipboard), "D") ? 1 : 0
   If (not IsDir) and (RegExReplace(Clipboard, ".*\.(.*)", "$1")="lnk")
         Islnk:=1
   If (IsDir or IsLnk)
  {
    send {F2}
    return
  }
   i := k := 0
   ControlGetFocus, Control, A
   if InStr(Control, "Edit")
      ControlGetText, FileName, %Control%, A
   else 
   {
      WinGet, ControlList, ControlList, A
      Loop, parse, ControlList, `n
         if InStr(A_LoopField, "Edit")
            i++
      Send {F2}
      While k - i != 1
      {
         Sleep, 15
         k := 0
         WinGet, ControlList, ControlList, A
         Loop, parse, ControlList, `n
            if InStr(A_LoopField, "Edit")
               k++
      }
      Control = Edit%k%
      ControlGetText, FileName, %Control%, A
   }
   FileNameNoExt := RegExReplace(FileName, "(.*)\..*", "$1")
   NameLengh := StrLen(FileNameNoExt) - 3 ; мое добавление для вопроса
   SendMessage, EM_SETSEL := 0xB1, 0, NameLengh, %Control%, A
   Return

У меня вин10, в ней скрипт работает так, нажимаешь впервый раз F2, выделает только имя, а если при этом еще раз нажать F2, то происходит выделение, как описано (отмечено комментарием). Вот щас не могу понять, как сделать, чтобы сразу работало с одного нажатия?

25

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею

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


; Замена запущенной программы
#SingleInstance force


; Читаем значение из реестра скрыты ли расширения типов файлов.
; Нужно для корректного добавления текста в конец имени.
RegRead,HideFileExt,HKEY_CURRENT_USER,Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced,	HideFileExt



; Создаем группу с окнами сохранений.
GroupAdd, SaveDialog,Save As ahk_class #32770
GroupAdd, SaveDialog,Сохранение ahk_class #32770
GroupAdd, SaveDialog,Сохранить как ahk_class #32770

; SetTitleMatchMode, 2 
; SendMode, input
GroupAdd, AllWindows
;GroupAdd, AllWindows,Program Manager ahk_class Progman
;GroupAdd, AllWindows,ahk_class CabinetWClass


loop
{
	; ожидаем возможные окна.
	WinWaitActive, ahk_group SaveDialog
	
	;Окно найдено.
	
	; В переменной ListSaveDialogOpened хрянятся id окон которые были уже открыты.
	;	Если переменная пустая, то условие хоть как истина.
	;	Иначе проверяем наличие id нового открытого окна в переменной.
	;	Если там этого id нет то условие истина.
	;Функция WinActive() сразу же делает это окно по умолчанию для ahk подпрограмм.
	;Оператор '~=' то же самое что и RegExMatch.
	;	(^|`|) означает что до начала номера id должно быть либо начало переменной, либо символ '|'
	;	($|`|) означает что после номера id должно быть либо конец переменной, либо символ '|'
	If ListSaveDialogOpened ? Not (WinActive("ahk_group SaveDialog") ~= ("(^|`|)" ListSaveDialogOpened "($|`|)") ) : true
	{
		;Окно нам подходит, теперь можно работать с ним.
		
		; Так же добавим его id в переменную что бы в последующие разы игнорило.
		ListSaveDialogOpened .= (ListSaveDialogOpened ? "|" : "")	WinActive()
		
		
		;Узнаем значение поля с именем файла. Заносим в переменную Text.
		ControlGetText,Text,Edit1
			
		; Если система показывает типы файлов, то в переменной Text убераем окончание и заносим в Extension.
		IfEqual,HideFileExt,0,SplitPath,Text,,DirFile,Extension,Text
		; Если переменная с типом файла не пуста, то в начале добавим точку.
		IfNotEqual,Extension,,try Extension := "." Extension

		; Нужно проверить есть ли дата в начале.
		; Создаем переменную формата YYYYMMDD.
		; YYYY - год. Четырехзначное значение(пример 2016)
		; MM - Месяц. Двухзначное значение(пример 01)
		; DD - День. Двухзначное значение(пример 01)
		date := 20 . SubStr(Text,1,6)
		
		; Если это условие ложь значит в начале нет даты.
		if date is Not time
		{
			; Продолжаем если нет даты...
			; Перезапишит переменную date с сегодняшним числом.
			FormatTime, date,, yyMMdd
			
			; Замена и сокращение символов.
			Text := StrReplace(Text,"@","(A)") 
			Text := StrReplace(Text,"+","plus") 
			Text := SubStr(text,1,192)
			
			; Новое значение Text будет равно "date + Text + свой текст + Extension".
			Text := date . " " . Text . " @ + " . Extension

			; Устанавливаем новый текст в контрол.
			ControlSetText, Edit1, % Text
			
			; EM_SETSEL это - сообщение для выделения текста в edit поле от определенного символа до другого.
			; Функция InStr выдает позицию искомого текста(всегда начало слева), не учитывая регистр и поиск должен быть с конца.
			SendMessage, 0xB1,% InStr(Text,"@",0,0) , % InStr(Text,"@",0,0),Edit1	; EM_SETSEL
		}
	}
	; Конец этого условия значит что все нужные манипуляции с окном сделаны.
	
	;Ожидаем его деактивации из фокуса.
	WinWaitNotActive
	
	; Если окон сохранения больше вообще нет, то очищаем переменную.
	If Not WinExist("ahk_group SaveDialog")
		ListSaveDialogOpened := ""
		
	; Если же окна сохранения еще существуют, то те с которым
	;	была работа будут игнорится в следующем цикле.
}


#IfWinActive ahk_group AllWindows
$F2::  
   i := k := 0
   ControlGetFocus, Control, A
   if InStr(Control, "Edit")
      ControlGetText, FileName, %Control%, A
   else 
   {
      WinGet, ControlList, ControlList, A
      Loop, parse, ControlList, `n
         if InStr(A_LoopField, "Edit")
            i++
      ;Send {F2}
      Send, % "{" . SubStr(A_ThisHotkey, 2) . "}"
      While k - i != 1
      {
         Sleep, 15
         k := 0
         WinGet, ControlList, ControlList, A
         Loop, parse, ControlList, `n
            if InStr(A_LoopField, "Edit")
               k++
      }
      Control = Edit%k%
      ControlGetText, FileName, %Control%, A
   }
		
	date := 20 . SubStr(FileName,1,6)
  ; SubStr (FileName,1,7) = " " ; проверка что после даты стоит пробел
	if date is Not time ;todo добавить сюда доп. условие, после даты должен идти пробел
	{
		FormatTime, date,, yyMMdd

    IfEqual,HideFileExt, 0,SplitPath,FileName, , ,Ext,FileName
		IfNotEqual,Ext,,try Ext := "." Ext
    oldFileName := Filename Ext
    
		FileName := StrReplace(FileName,"@","(A)") 
		FileName := StrReplace(FileName,"+","plus") 
		FileName := SubStr(FileName,1,192)

		FileName := date . " " . FileName . " @ + " . Ext
  }
  else
  {
    Filename := oldFileName
  }
ControlSetText, %Control%, % FileName
SendMessage, 0xB1,% InStr(FileName,"@",0,0) , % InStr(FileName,"@",0,0),%Control%	; EM_SETSEL

Return

Теперь все в одном скрипте, добавил горячую клавишу. Вдохновлялся скриптом из коллекции "Выделение файла без расширения".
А проблема вот в чем, не могу отловить баг. Он появляется если в программе SynWrite (мой текстовый редактор) нажать F2 (и еще где-то не работает, но щас не помню). После этого скрипт зацикливается, я смотрел lines most recently executed, и перестает работать горячая клавиша и слежение за окнами сохранения. Не могу понять в чем дело?

26

Re: AHK: Скрипт сохранение имени файла с датой и по хоткею


#IfWinActive ahk_group AllWindows
$F2::  
   k := 0
   ControlGetFocus, Control, A
   if InStr(Control, "Edit")
      ControlGetText, FileName, %Control%, A
  else 
   {
      Send {F2}
      Sleep, 25
      k := 0
      WinGet, ControlList, ControlList, A
      Loop, parse, ControlList, `n
          if InStr(A_LoopField, "Edit")
            k++
      k-- ; с этим работает с первого нажатия F2
      Control = Edit%k%
      ControlGetText, FileName, %Control%, A
   }
	
  oldFileName := FileName
  
	date := 20 . SubStr(FileName,1,6)
	if date is Not time 
	{
		FormatTime, date,, yyMMdd
    
    IfEqual,HideFileExt, 0,SplitPath,FileName, , ,Ext,FileName
		IfNotEqual,Ext,,try Ext := "." Ext
    
    oldFileName := Filename . Ext
    
		FileName := StrReplace(FileName,"@","(at)") 
		FileName := StrReplace(FileName,"+","plus") 
		FileName := SubStr(FileName,1,192)

		FileName := date . " " . FileName . " @ + " . Ext
  }
  else
  {
    Filename := oldFileName
  }
ControlSetText, %Control%, % FileName
SendMessage, 0xB1,% InStr(FileName,"@",0,0) , % InStr(FileName,"@",0,0),%Control%	; EM_SETSEL

Return
#IF

Немного посидел, подумал и вот исправленный вариант, выкладываю измененную часть кода, где клавиша F2.
Теперь при единократном нажатии F2, сразу меняется текст контрола.