<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Свёртка приложений в трей]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=6623</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=6623&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Свёртка приложений в трей».]]></description>
		<lastBuildDate>Wed, 04 Jan 2012 22:59:02 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: Свёртка приложений в трей]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=55298#p55298</link>
			<description><![CDATA[<p>Это славно, <strong>Grey</strong>!</p>]]></description>
			<author><![CDATA[null@example.com (DD)]]></author>
			<pubDate>Wed, 04 Jan 2012 22:59:02 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=55298#p55298</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Свёртка приложений в трей]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=55214#p55214</link>
			<description><![CDATA[<div class="codebox"><pre><code>#HotkeyModifierTimeout, 100
DetectHiddenWindows, On
SetWinDelay, 10
SetKeyDelay, 0
mwt_MaxWindows:=30, mwt_MaxLength:=36
HiddenIDs:=[], MenuItems:=[]
Hotkey, #vk48, mwt_Minimize
Hotkey, ^!vk52, mwt_RestoreAll
Menu, Tray, Icon, % A_WinDir &quot;\system32\Shell32.dll&quot;, 99
Menu, Tray, NoStandard
Menu, Tray, Tip, % &quot;Win+H - hide current window&quot;
               . &quot;`nCtrl+Alt+R - restore all windows&quot;
Menu, Tray, Add, &amp;Terminate, mwt_RestoreAllThenExit
Menu, Tray, Add, &amp;Restore all, mwt_RestoreAll
Menu, Tray, Add
OnExit, mwt_RestoreAllThenExit
Return

mwt_Minimize:
   If GetCount()&gt;=mwt_MaxWindows
   {
      MsgBox, 4160,, % &quot;Не может быть скрыто одновременно&quot;
                    . &quot; больше, чем &quot;mwt_MaxWindows &quot; окон.&quot;, 1
      Return
   }
   WinWait, A,, 2
   If ErrorLevel
      Return
   WinGet, mwt_ActiveID, ID
   WinGetTitle, mwt_ActiveTitle
   WinGetClass, mwt_ActiveClass
   WinGet, mwt_ActivePID, PID
   WinGet, mwt_List, List, % &quot;ahk_pid&quot;mwt_ActivePID
   WinGet, mwt_ActiveProcess, ProcessName
   If !mwt_ActiveTitle
      mwt_ActiveTitle:=mwt_ActiveProcess
   If mwt_ActiveClass~=&quot;WorkerW|Shell_TrayWnd|Progman&quot;
      Return
   Send, !{Esc}
   If StrLen(mwt_ActiveTitle)&gt;mwt_MaxLength
      mwt_ActiveTitle:=SubStr(mwt_ActiveTitle, 1, mwt_MaxLength)&quot;...&quot;
   For Key, Value In MenuItems
   {
      If % Value=mwt_ActiveTitle
         mwt_ActiveTitle:=mwt_ActiveTitle
                        . &quot; (&quot;GetCountWithTitle(mwt_ActiveTitle)+1 &quot;)&quot;
   }
   If % mwt_ActiveProcess=&quot;explorer.exe&quot;
   {
      WinHide, % &quot;ahk_id&quot;mwt_ActiveID
      HiddenIDs.Insert(mwt_ActiveTitle, mwt_ActiveID)
   }
   Else
   {
      Loop, % mwt_List
      {
         mwt_id:=mwt_List%A_Index%
         WinGet, WStyle, Style, % &quot;ahk_id&quot;mwt_id
         If (WStyle &amp; 0x10000000) ; WS_VISIBLE
         {
            WinHide, % &quot;ahk_id&quot;mwt_id
            HiddenIDs.Insert(mwt_ActiveTitle
                            . (A_Index=1 ? &quot;&quot;:A_Index), mwt_id)
         }
      }
   }
   Menu, Tray, Add, % mwt_ActiveTitle, RestoreFromTrayMenu
   MenuItems.Insert(mwt_ActiveTitle, mwt_ActiveTitle)
   Return

RestoreFromTrayMenu:
   Menu, Tray, Delete, % MenuItem:=A_ThisMenuItem
   For Key, Value In HiddenIDs
   {
      If % Key=MenuItem
      {
         WinShow, % &quot;ahk_id&quot;Value
         WinActivate, % &quot;ahk_id&quot;Value
         HiddenIDs[Key]:=&quot;&quot;, MenuItems[Key]:=&quot;&quot;
      }
      Else If InStr(Key, MenuItem)=1
      {
         WinShow, % &quot;ahk_id&quot;Value
         HiddenIDs[Key]:=&quot;&quot;
      }
   }
   Return

mwt_RestoreAll:
   For Key, Value In HiddenIDs
      If % Value!=&quot;&quot;
         WinShow, % &quot;ahk_id&quot;Value
   HiddenIDs:=[]
   For Key, Value In MenuItems
      If % Value!=&quot;&quot;
         Menu, Tray, Delete, % Value
   MenuItems:=[]
   Return

mwt_RestoreAllThenExit:
   Gosub, mwt_RestoreAll
   ExitApp

GetCountWithTitle(Title)
{
   global MenuItems
   For Key, Value In MenuItems
      If InStr(Value, Title)=1
         Counter++
   Return, Counter
}

GetCount()
{
   global MenuItems
   For Key, Value In MenuItems
      Counter++
   Return, Counter
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Grey)]]></author>
			<pubDate>Sat, 31 Dec 2011 20:36:47 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=55214#p55214</guid>
		</item>
		<item>
			<title><![CDATA[AHK: Свёртка приложений в трей]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=55150#p55150</link>
			<description><![CDATA[<p><a href="http://www.script-coding.com/AutoHotkey/AhkTray.html">Источник и описание</a>.</p><p>Его гоняючи (из своего, правда, постоянно загруженного), не раз сталкивался с поведением, когда скрипт &quot;забывает&quot; список хэндлов свёрнутых ранее окон, не реагируя на хоткей восстановления.<br />К счастью, пришла идея вписывать эти хэндлы в создаваемый при запуске скрипта файл и удалять при выходе из него.<br />К несчастью же, всякий раз при попытке идею самостоятельно воплотить раздаётся нестройный глухой стук <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.<br />Вмешаться прошу.</p><div class="codebox"><pre><code>#SingleInstance Force

;установка иконки скрипта в трее с изображением окошек
Menu, Tray, Icon, %A_WinDir%\system32\Shell32.dll, 99
;максимальное количество окон, которое может быть скрыто
mwt_MaxWindows = 30
;горячая клавиша, скрывающая текущее окно
mwt_Hotkey = #h ;Win+H
;горячая клавиша, восстанавливающая все скрытые окна
mwt_HotkeyRestoreAll = ^!r ;Ctrl+Alt+R
;эта установка убирает &quot;системные&quot; пункты меню иконки скрипта в трее;
;если эти пункты нужны, задайте &quot;Y&quot; вместо &quot;N&quot;
mwt_StandardMenu = N
;следующие настройки позволяют избежать потребности отпускать и
;нажимать снова модификатор горячей клавиши всякий раз,
;когда вы хотите быстро скрыть более, чем одно окно
#HotkeyModifierTimeout 100
SetWinDelay 10
SetKeyDelay 0
;может быть запущено не более одного экземпляра сценария
#SingleInstance
;работать со скрытыми окнами
DetectHiddenWindows, On
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;назначение горячей клавиши, скрывающей текущее окно
Hotkey, %mwt_Hotkey%, mwt_Minimize
;назначение горячей клавиши, восстанавливающей все скрытые окна
Hotkey, %mwt_HotkeyRestoreAll%, mwt_RestoreAll
;при завершении сценария необходимо отобразить все скрытые окна, если таковые есть
OnExit, mwt_RestoreAllThenExit
;настройка меню иконки скрипта в трее
if mwt_StandardMenu = Y
	Menu, Tray, Add
else
{
	Menu, Tray, NoStandard
	Menu, Tray, Add, Выход и восстановление всех скрытых окон, mwt_RestoreAllThenExit
}
Menu, Tray, Add, Восстановление всех скрытых окон, mwt_RestoreAll
Menu, Tray, Add
;ограничение ширины меню
if a_AhkVersion = ;пусто (для версий ранее 1.0.22)
	mwt_MaxLength = 100
else
	mwt_MaxLength = 260
return ;конец секции авто-выполнения скрипта
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;отсюда начинается исполнение, когда нажата горячая клавиша, скрывающая текущее окно
mwt_Minimize:
if mwt_WindowCount &gt;= %mwt_MaxWindows%
{
	MsgBox Не может быть скрыто одновременно больше, чем %mwt_MaxWindows% окон.
	return
}
;получаем активное окно и используем его как &quot;последнее найденное окно&quot;,
;т.е. окно по умолчанию для всех дальнейших вызовов функций, связанных с окнами
WinWait, A,, 2
if ErrorLevel &lt;&gt; 0
	return
;получаем информацию об активном окне
WinGet, mwt_ActiveID, ID ;хэндл (HWND) окна
WinGetTitle, mwt_ActiveTitle ;заголовок окна
WinGetClass, mwt_ActiveClass ;имя класса окна
WinGet, mwt_ActivePID, PID ;идентификатор процесса, которому принадлежит окно
WinGet, mwt_List, List, ahk_pid %mwt_ActivePID% ;список всех окон этого процесса
WinGet, mwt_ActiveProcess, ProcessName ;имя процесса, которому принадлежит окно
;рабочий стол и панель задач скрывать нельзя
if mwt_ActiveClass in Shell_TrayWnd,Progman
	return
;поскольку скрытие окна не будет деактивировать его, переключимся
;в другое окно (как будто пользователь нажал Alt+Escape)
Send, !{esc}
;собственно скрываем нужные окна процесса (делаем их невидимыми),
;скрытию подлежат все окна текущего процесса со стилем WS_VISIBLE,
;mwt_WindowsIDs - список хэндлов скрываемых окон,
;разделённых символом | (вертикальная черта)
mwt_WindowsIDs = &quot;&quot;
;проводник - особый случай, скрывать можно только текущее окно процесса
If mwt_ActiveProcess = explorer.exe
{
	WinHide, ahk_id %mwt_ActiveID%
	mwt_WindowsIDs = %mwt_WindowsIDs%|%mwt_ActiveID%
}
;скрываем все видимые окна процесса
Else
{
	Loop, %mwt_List%
	{
		mwt_id := mwt_List%A_Index%
		WinGet, style, Style, ahk_id %mwt_id%
		if ( style &amp; 0x10000000 ) ;WS_VISIBLE
		{
			WinHide, ahk_id %mwt_id%
			;Result := DllCall(&quot;ShowWindow&quot;, &quot;UInt&quot;, mwt_id, &quot;Int&quot;, &quot;0&quot;)
			mwt_WindowsIDs = %mwt_WindowsIDs%|%mwt_id%
		}
	}
}
;если заголовок окна пуст, используем имя класса,
;т.к. нам нужен непустой заголовок пункта меню
if mwt_ActiveTitle =
	mwt_ActiveTitle = ahk_class %mwt_ActiveClass%
;обрезаем заголовок окна до максимальной длины mwt_MaxLength
StringLeft, mwt_ActiveTitle, mwt_ActiveTitle, %mwt_MaxLength%
;обеспечение уникальности заголовка пункта меню:
Loop, %mwt_MaxWindows%
{
	if mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
	{
		;Нашли такой же заголовок, так что заголовок не уникален.
		StringTrimLeft, mwt_ActiveIDShort, mwt_ActiveID, 2
		StringLen, mwt_ActiveIDShortLength, mwt_ActiveIDShort
		StringLen, mwt_ActiveTitleLength, mwt_ActiveTitle
		mwt_ActiveTitleLength += %mwt_ActiveIDShortLength%
		mwt_ActiveTitleLength += 1
		if mwt_ActiveTitleLength &gt; %mwt_MaxLength%
		{
			TrimCount = %mwt_ActiveTitleLength%
			TrimCount -= %mwt_MaxLength%
			StringTrimRight, mwt_ActiveTitle, mwt_ActiveTitle, %TrimCount%
		}
		;создаём уникальный заголовок:
		mwt_ActiveTitle = %mwt_ActiveTitle% %mwt_ActiveIDShort%
		break
	}
}
;на всякий случай проверим, нет ли этого окна уже в списке ранее скрытых
mwt_AlreadyExists = n
Loop, %mwt_MaxWindows%
{
	if mwt_WindowID%a_index% = %mwt_ActiveID%
	{
		mwt_AlreadyExists = y
		break
	}
}
;добавим окно в массив и в меню
if mwt_AlreadyExists = n
{
	Menu, Tray, add, %mwt_ActiveTitle%, RestoreFromTrayMenu
	mwt_WindowCount += 1
	Loop, %mwt_MaxWindows% ;поиск свободного элемента в массиве
	{
		if mwt_WindowID%a_index% = ;элемент свободен
		{
			mwt_WindowID%a_index% = %mwt_ActiveID%
			mwt_WindowTitle%a_index% = %mwt_ActiveTitle%
			mwt_WindowPID%a_index% = %mwt_ActivePID%
			mwt_WinIDs%a_index% = %mwt_WindowsIDs%
			break
		}
	}
}
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;отсюда начинается исполнение, когда вызвана команда меню иконки скрипта в трее,
;соответствующая конкретному скрытому окну
RestoreFromTrayMenu:
Menu, Tray, delete, %A_ThisMenuItem%
;поиск окна по его уникальному заголовку, сохраненному как название пункта меню
Loop, %mwt_MaxWindows%
{
	if mwt_WindowTitle%a_index% = %A_ThisMenuItem%
	{
		StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
		StringTrimRight, PIDToRestore, mwt_WindowPID%a_index%, 0
		mwt_WindowsIDs := mwt_WinIDs%a_index%
		Loop, parse, mwt_WindowsIDs, |
			WinShow, ahk_id %A_LoopField%
		WinActivate ahk_id %IDToRestore%
		mwt_WindowID%a_index% = ;очищаем элементы массивов
		mwt_WindowTitle%a_index% =
		mwt_WindowPID%a_index% =
		mwt_WinIDs%a_index% =
		mwt_WindowCount -= 1
		break
	}
}
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;отсюда начинается исполнение, когда вызвана команда меню иконки скрипта в трее
;&quot;Выход и восстановление всех скрытых окон&quot;
mwt_RestoreAllThenExit:
Gosub, mwt_RestoreAll
ExitApp ;завершение работы скрипта
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;отсюда начинается исполнение, когда вызвана команда меню иконки скрипта в трее
;&quot;Восстановление всех скрытых окон&quot;
mwt_RestoreAll:
Loop, %mwt_MaxWindows%
{
	if mwt_WindowID%a_index% &lt;&gt;
	{
		StringTrimRight, IDToRestore, mwt_WindowID%a_index%, 0
		StringTrimRight, PIDToRestore, mwt_WindowPID%a_index%, 0
		mwt_WindowsIDs := mwt_WinIDs%a_index%
		Loop, parse, mwt_WindowsIDs, |
			WinShow, ahk_id %A_LoopField%
		WinActivate ahk_id %IDToRestore%
		StringTrimRight, MenuToRemove, mwt_WindowTitle%a_index%, 0
		Menu, Tray, delete, %MenuToRemove%
		mwt_WindowID%a_index% =
		mwt_WindowTitle%a_index% =
		mwt_WindowPID%a_index% =
		mwt_WinIDs%a_index% =
		mwt_WindowCount -= 1
	}
	if mwt_WindowCount = 0
		break
}
return</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (DD)]]></author>
			<pubDate>Thu, 29 Dec 2011 23:11:02 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=55150#p55150</guid>
		</item>
	</channel>
</rss>
