1 (изменено: alexii, 2011-07-20 04:48:05)

Тема: AHK: Запомнить порядок активации окон

Привет!

Можно как-то организовать запоминание скриптом порядка активации последних 10-12 окон? Так, чтобы по горячей клавише можно было перейти по порядку назад к тем окнам, которые были активны перед текущим.

Допустим в фокус попадали окна в таком порядке:  ...1,7,2,9,4,6. После нажатия горячей клавиши активируется 4, после следующего нажатия 9, потом 2 и т.д.

Спасибо за помощь!

2

Re: AHK: Запомнить порядок активации окон

Первое, что приходит в голову - создать 10 переменных и записывать/считывать в них имена последних 10 окон.

3

Re: AHK: Запомнить порядок активации окон

И прекрасно.Но как это осуществить? Как отслеживать, что новое окно стало активным и как потом переключаться назад?  С кодом поможешь? Если не сложно конечно.

4

Re: AHK: Запомнить порядок активации окон

Самое простое - периодически проверять, которое окно активно. Команда WinGet позволяет получить информацию об активном окне.
С кодом вряд ли помогу, могу подсказать, куда копать.

5

Re: AHK: Запомнить порядок активации окон

Вот пример активации одного предыдущего окна:

~lbutton::
ifwinnotactive, ahk_id %name%
{
oldWin = %name%
winget,name,id,A
}
return

!sc02C::     ;Alt + Z
Winactivate, ahk_id %oldWin%
return

Но суть в том что если сразу переключать с окна на окно то работать данный скрипт не будет. Он работает если кликнуть в неактивное окно и кликнуть в него ещё раз, иначе окно видимо не становится активным и не определяется, а после этого один раз кликнуть в другое окно(если кликнуть дважды то это окно теперь будет точкой отсчета к которому будем возвращаться а не предыдущее) и можем смело жать Alt + Z, после чего предыдущее активное окно станет активным. ИМХО  после первых 50 кликов я бы уже и забыл каким там было 10е активное окно и пришлось бы перебирать, уж лучше если есть возможность сразу на конкретные кнопки задать активацию определенных окон.

6

Re: AHK: Запомнить порядок активации окон

MixaLich, мне как раз не очень важно под каким номером было это окно. Важно на 1-5 окон  отлистать назад, пусть после двух-пяти тыков хоткея.

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

И вот когда с нужным окном(невжно под каким номером) не закончено действие, а появилось 2 новых и фокус перешёл к ним, а потом ещё к какому-то старому, нужно вернуться в то самое нужное.  Вполне подойдёт нажать на хоткей 3-5 раз, пока из под завалов не поднимется наверх нужное, которое я вполне готов опознавать визуально.

  Вот такая задача.

7

Re: AHK: Запомнить порядок активации окон

Ясно. После танцев с бубном родился следующий код, его мы делаем отдельным скриптом:

f1:: ;кнопку естественно ставим любую
winget,name_id,id,A

loop
{
loop
{
keywait, LButton, D
sleep, 100
ifwinnotactive, ahk_id %name_id%
{
winget,name_id,id,A
filedelete, c:\t1.txt ; пути подобных файлов тоже меняем по усмотрению
fileappend, %name_id%, c:\t1.txt
break
}
}
loop
{
keywait, LButton, D
sleep, 100
ifwinnotactive, ahk_id %name_id%
{
winget,name_id,id,A
filedelete, c:\t2.txt
fileappend, %name_id%, c:\t2.txt
break
}
}
loop
{
keywait, LButton, D
sleep, 100
ifwinnotactive, ahk_id %name_id%
{
winget,name_id,id,A
filedelete, c:\t3.txt
fileappend, %name_id%, c:\t3.txt
break
}
}
loop
{
keywait, LButton, D
sleep, 100
ifwinnotactive, ahk_id %name_id%
{
winget,name_id,id,A
filedelete, c:\t4.txt
fileappend, %name_id%, c:\t4.txt
break
}
}
loop
{
keywait, LButton, D
sleep, 100
ifwinnotactive, ahk_id %name_id%
{
winget,name_id,id,A
filedelete, c:\t5.txt
fileappend, %name_id%, c:\t5.txt
break
}
}
}
return

Далее нам нужен еще скрипт:

Numpad1::
ifexist, c:\t2.txt
{
filereadline, win1, c:\t1.txt, 1
winactivate, ahk_id %win1%
}
return

Numpad2::
ifexist, c:\t2.txt
{
filereadline, win2, c:\t2.txt, 1
winactivate, ahk_id %win2%
}
return

Numpad3::
ifexist, c:\t3.txt
{
filereadline, win3, c:\t3.txt, 1
winactivate, ahk_id %win3%
}
return

Numpad4::
ifexist, c:\t4.txt
{
filereadline, win4, c:\t4.txt, 1
winactivate, ahk_id %win4%
}
return

Numpad5::
ifexist, c:\t5.txt
{
filereadline, win5, c:\t5.txt, 1
winactivate, ahk_id %win5%
}
return

Все это работает следующим образом: запускаете оба скрипта, делаете активным окно, запускаете выполнение скрипта1 нажав f1, теперь кликая мышью по другим окнам их Иды будут записываться в файлы блокнота, так мы можем потом нажимать цифры на цифровой клавиатуре от 1 - 5 и соответственно вызывать последние активные окна. Если переключать будете табом то новые окна не записываются а старые остаются, достаточно после таба кликнуть в него и оно запомнится. Проверил, вроде работает, для меня это оказалась не такая легкая задача как кажется на первый взгляд, поэтому и код такой.

8

Re: AHK: Запомнить порядок активации окон

Спасибо огромное за проделанную работу! Попробую применить.
Если будет работать, потом попробую на одну кнопку переделать.

9

Re: AHK: Запомнить порядок активации окон

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

10

Re: AHK: Запомнить порядок активации окон

Да, в этом варианте кликать для запоминания надо. По иному в голову пока ничего больше не приходит.

11

Re: AHK: Запомнить порядок активации окон

MixaLich пишет:

Да, в этом варианте кликать для запоминания надо. По иному в голову пока ничего больше не приходит.

Примерно так:

MAX_WINDOWS := 3 ;сколько окон запоминаем
stop		:= 0

;обнуляем все дескрипторы
i:=0
while i<=MAX_WINDOWS
{
	window%i%:=0
	i:=i+1
}

WinGet, cur, ID, A
window1:=cur
while stop==0
{
	;ждём пока текущее окно не потеряет фокус
	WinWaitNotActive ahk_id%cur%
	;получаем дескриптор нового активного окна
	WinGet, cur, ID, A
	;если получить не удалось, то ждём 1/20 секунды и пробуем снова.
	;Если и тогда не получится, то переходим к следующему витку цикла
	if cur=
	{
		sleep 50
		WinGet, cur, ID, A
		if cur=
			continue
	}
	;ищем текущее окно в сохранённых
	i := 1
	while i<= MAX_WINDOWS
	{
		if(cur=window%i%)
		{
			break
		}
		i:=i+1
	}
	;если нету, то будем менять последний
	if(i>MAX_WINDOWS)
	{
		i:=MAX_WINDOWS
	}
	;меняем
	while i > 1
	{
		k := i-1
		window%i% := window%k%
		i := k
	}
	window1 := cur
}
;===========================================

F2::
	;если окно ещё существует, то показываем его, иначе выводим сообщение
	ifWinExist ahk_id%window2%
		WinActivate ahk_id%window2%
	else
		msgbox Окна уже нет
return
F3::
	ifWinExist ahk_id%window3%
		WinActivate ahk_id%window3%
	else
		msgbox Окна уже нет
return
F12:: 
	;прервать слежку за окнами после смены этого окна
	stop := 1
return

12

Re: AHK: Запомнить порядок активации окон

WinWaitNotActive, такой команды не знал, в хозяйстве пригодится:).

13

Re: AHK: Запомнить порядок активации окон

Забыл глаза разуть когда документацию читал

14

Re: AHK: Запомнить порядок активации окон

Мой вариант (без учёта несуществования окна):

   Capacity = 10   ; сколько окон запоминать

   WinArray := []
   Loop
   {
      WinGet, ID,, A
      if (!ChangeActiveHotkey && ID != WinArray.1)
      {
         WinArray.Insert(1, ID)
         WinArray.Remove(Capacity + 1)
         CurrentWin = 1
      }
      ChangeActiveHotkey =
      WinWaitNotActive, ahk_id %ID%
   }
   Return

^Left::
^Right::
   limit := A_ThisHotkey = "^Left" ? WinArray.MaxIndex() : 1
   if (CurrentWin = limit)
      Return
      
   ChangeActiveHotkey = 1
   CurrentWin := A_ThisHotkey = "^Left" ? ++CurrentWin : --CurrentWin
   WinActivate, % "ahk_id " WinArray[CurrentWin]
   Return

Листает по горячим клавишам Ctrl + Left и Ctrl + Right.

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

15

Re: AHK: Запомнить порядок активации окон

Ух ты! И коротко так получилось! Здорово! Только он что-то на

WinArray.1

ругается. Неврный символ?

16

Re: AHK: Запомнить порядок активации окон

Нет, боюсь, у тебя старая версия AHK! Обнови.

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

17

Re: AHK: Запомнить порядок активации окон

Обновил. Из того, что успел проверить - работает отлично. К сожалению отрубилась половина клавишей в другом скрипте, скорее всего из-за обновления. Разбираюсь.

18

Re: AHK: Запомнить порядок активации окон

Для совместимости со скриптами, написанными под AHK-basic, лучше пользоваться ANSI-версией AHK_L. Если всё же установлена Unicode-версия, то под неё скрипты нужно сохранять в формате Utf-8.

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

19

Re: AHK: Запомнить порядок активации окон

Спасибо, помогло!

20

Re: AHK: Запомнить порядок активации окон

teadrinker, всё работает отлично! Безумно благодарен!

21

Re: AHK: Запомнить порядок активации окон

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

;--------------  Рамка
TH = 6   ; толщина рамки

   SetWinDelay, 0
   Gui, +LastFound +ToolWindow -Caption +AlwaysOnTop +Disabled
   WinGet, ID
   Gui, Color, Yellow

   SetTimer, Frame, 50
   Return

Frame:
   WinGetPos, X, Y, W, H, A
   if (X = XPrev && Y = YPrev && W = WPrev && H = HPrev)
      Return

   XPrev := X, YPrev := Y, WPrev := W, HPrev := H
   X -= TH, Y -= TH, W += 2*TH, H += 2*TH

   Gui, Show, x%X% y%Y% w%W% h%H% Hide
   Options := "0-0 " W "-0 " W "-" H " 0-" H " 0-0 " TH "-" TH
      . " " W-TH "-" TH " " W-TH "-" H-TH " " TH "-" H-TH " " TH "-" TH
   DetectHiddenWindows, On
   WinSet, Region, % Options, ahk_id %ID%
   Gui, Show, NA
   Return

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

22

Re: AHK: Запомнить порядок активации окон

DetectHiddenWindows, On
SetWinDelay, 0
TH := 6
Capacity := 10
WinArray := []
Gui, +LastFound +ToolWindow -Caption +AlwaysOnTop +Disabled
WinGet, FrameID
Gui, Color, Yellow
SetTimer, Frame, 50
Loop
   {
      WinGet, ID,, A
      If (!ChangeActiveHotkey && ID != WinArray.1)
         {
            WinArray.Insert(1, ID)
            WinArray.Remove(Capacity + 1)
            CurrentWin = 1
         }
      ChangeActiveHotkey =
      WinWaitNotActive % "ahk_id" ID
   }
Return

Frame:
   WinGetPos, X, Y, W, H, A
   If (X = XPrev && Y = YPrev && W = WPrev && H = HPrev)
      Return
   XPrev := X, YPrev := Y, WPrev := W, HPrev := H
   X -= TH, Y -= TH, W += 2*TH, H += 2*TH
   Gui, Show, x%X% y%Y% w%W% h%H% Hide
   Options := "0-0 "W "-0 "W "-"H " 0-"H " 0-0 "TH "-"TH
   . " "W-TH "-"TH " "W-TH "-"H-TH " "TH "-"H-TH " "TH "-"TH
   WinSet, Region, % Options, % "ahk_id" FrameID
   Gui, Show, NA
   Return

^Left::
^Right::
   limit := A_ThisHotkey = "^Left" ? WinArray.MaxIndex() : 1
   If (CurrentWin = limit)
      Return
   ChangeActiveHotkey = 1
   CurrentWin := A_ThisHotkey = "^Left" ? ++CurrentWin : --CurrentWin
   WinActivate % "ahk_id " WinArray[CurrentWin]
   Return

23

Re: AHK: Запомнить порядок активации окон

Grey, спасибо, работает!