<?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=5748</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=5748&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Работа с треем».]]></description>
		<lastBuildDate>Wed, 27 Apr 2011 20:46:25 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47881#p47881</link>
			<description><![CDATA[<p>Различную информацию об иконках системного трея можно получить, отправляя им сообщение <a href="http://msdn.microsoft.com/en-us/library/bb787319%28VS.85%29.aspx"><strong>TB_GETBUTTON</strong></a>, и считывая данные из структуры <a href="http://msdn.microsoft.com/en-us/library/bb760476%28VS.85%29.aspx"><strong>TBBUTTON</strong></a>. (Чтобы считать данные из удалённого процесса (explorer.exe), нужно выделить буфер в его адресном пространстве, считать данные в него, а затем скопировать их в буфер из адресного пространства вызывающего процесса.) В составе этой структуры есть член <em>dwData</em>, описанный в MSDN как &quot;application-defined value&quot;. Порыскав по просторам интернета, я, наконец, <a href="http://winjade.net/wp-content/uploads/2008/06/systray-tutorial.pdf">нашёл</a> (pdf) его более подробное описание:<br /></p><div class="quotebox"><blockquote><p>The dwData member of the TBBUTTON structure gives us a pointer to the TRAYDATA structure for the button.</p></blockquote></div><div class="quotebox"><blockquote><p>public struct TRAYDATA<br />{<br />public IntPtr hwnd;<br />public uint uID;<br />public uint uCallbackMessage;<br />private uint Reserved;<br />private uint Reserved2;<br />public IntPtr hIcon;<br />}</p></blockquote></div><p>Возвращаясь к поставленной задаче — удалить &quot;зависшие&quot; иконки убитых приложений и обновить трей — можно получить хэндл родительского окна иконки (первый член структуры <strong>TRAYDATA</strong>) и проверить, существует ли его процесс (вариант с проверкой существования окна почему-то не срабатывает), затем удалить ненужную иконку, отправив ей <a href="http://msdn.microsoft.com/en-us/library/bb787309%28VS.85%29.aspx"><strong>TB_DELETEBUTTON</strong></a>. После этого нужно обновить трей с помощью <a href="http://msdn.microsoft.com/en-us/library/ms725497%28VS.85%29.aspx"><strong>WM_SETTINGCHANGE</strong></a>, иначе в области уведомлений останется пустое место.<br /></p><div class="codebox"><pre><code>#NoTrayIcon
SetBatchLines, -1

PROCESS_VM_OPERATION := (0x8)
PROCESS_VM_READ := (0x10)
PROCESS_QUERY_INFORMATION := (0x400)
SizeOfTBBUTTON := 20, SizeOfTRAYDATA := 24
MEM_COMMIT := 0x1000
MEM_RELEASE := 0x8000
PAGE_READWRITE := 0x4
WM_USER := 0x400
TB_BUTTONCOUNT := (WM_USER + 24)
TB_GETBUTTON := (WM_USER + 23)
WM_WININICHANGE := 0x1A
TB_DELETEBUTTON := (WM_USER + 22)
WM_SETTINGCHANGE := WM_WININICHANGE

; нам нужно найти хэндл окна класса ToolbarWindow32, которое является дочерним окна
; с классом SysPager, которое является дочерним окна с классом TrayNotifyWnd, которое,
; в свою очередь, является дочерним окна с классом Shell_TrayWnd (панели задач)
hShell_TrayWnd := WinExist(&quot;ahk_class Shell_TrayWnd&quot;)
ChildClasses = TrayNotifyWnd|SysPager|ToolbarWindow32  ; классы окон в порядке вложенности
Loop, parse, ChildClasses, |
   hChild := DllCall(&quot;FindWindowEx&quot;, UInt, A_Index = 1 ? hShell_TrayWnd : hChild
                                   , UInt, 0, Str, A_LoopField, UInt, 0)
; последнее вложенное — искомое окно — ToolbarWindow32 делаем последним найденным
WinWait, ahk_id %hChild%
WinGet, PID, PID
hProcess := DllCall(&quot;OpenProcess&quot;, UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, UInt, 0, UInt, PID)
lpData := DllCall(&quot;VirtualAllocEx&quot;, UInt, hProcess, UInt, 0
                                  , UInt, SizeOfTBBUTTON
                                  , UInt, MEM_COMMIT
                                  , UInt, PAGE_READWRITE)
DetectHiddenWindows, On
VarSetCapacity(TBBUTTON, SizeOfTBBUTTON)
VarSetCapacity(TRAYDATA, SizeOfTRAYDATA)
VarSetCapacity(FilePath, A_IsUnicode ? 600 : 300)
Index = 0
SendMessage, TB_BUTTONCOUNT
Loop % IconCount := ErrorLevel
{
   SendMessage, TB_GETBUTTON, Index, lpData
   DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess, UInt, lpData
                              , UInt, &amp;TBBUTTON
                              , UInt, SizeOfTBBUTTON, UInt, 0)

   DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess, UInt, NumGet(TBBUTTON, 12)
                              , UInt, &amp;TRAYDATA
                              , UInt, SizeOfTRAYDATA, UInt, 0)

   WinGet, PID, PID, % &quot;ahk_id &quot; NumGet(TRAYDATA)
   if !PID
      SendMessage, TB_DELETEBUTTON, Index--  ; в случае удаления индексы уменьшаются на 1
   Index++
}

if (Index &lt; IconCount)
   SendMessage, WM_SETTINGCHANGE,,,, ahk_class Shell_TrayWnd  ; иначе останется пустое место

DllCall(&quot;VirtualFreeEx&quot;, UInt, hProcess , UInt, lpData, UInt, 0, UInt, MEM_RELEASE)
DllCall(&quot;CloseHandle&quot;, UInt, hProcess)</code></pre></div><p>(Чёрт, подсветку доделать никак руки не доходят!)<br />И напоследок, код определяющий исполнимые файлы процессов, создавших иконки в трее (нужно учитывать, что часть иконок скрыта).<br /></p><div class="codebox"><pre><code>#NoTrayIcon
SetBatchLines, -1

PROCESS_VM_OPERATION := (0x8)
PROCESS_VM_READ := (0x10)
PROCESS_QUERY_INFORMATION := (0x400)
SizeOfTBBUTTON := 20, SizeOfTRAYDATA := 24
MEM_COMMIT := 0x1000
MEM_RELEASE := 0x8000
PAGE_READWRITE := 0x4
WM_USER := 0x400
TB_BUTTONCOUNT := (WM_USER + 24)
TB_GETBUTTON := (WM_USER + 23)
WM_WININICHANGE := 0x1A
TB_DELETEBUTTON := (WM_USER + 22)
WM_SETTINGCHANGE := WM_WININICHANGE

hShell_TrayWnd := WinExist(&quot;ahk_class Shell_TrayWnd&quot;)
ChildClasses = TrayNotifyWnd|SysPager|ToolbarWindow32  ; классы окон в порядке вложенности
Loop, parse, ChildClasses, |
   hChild := DllCall(&quot;FindWindowEx&quot;, UInt, A_Index = 1 ? hShell_TrayWnd : hChild
                                   , UInt, 0, Str, A_LoopField, UInt, 0)
; последнее вложенное — искомое окно — ToolbarWindow32 делаем последним найденным
WinWait, ahk_id %hChild%
WinGet, PID, PID
hProcess := DllCall(&quot;OpenProcess&quot;, UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, UInt, 0, UInt, PID)
lpData := DllCall(&quot;VirtualAllocEx&quot;, UInt, hProcess, UInt, 0
                                  , UInt, SizeOfTBBUTTON
                                  , UInt, MEM_COMMIT
                                  , UInt, PAGE_READWRITE)
DetectHiddenWindows, On
VarSetCapacity(TBBUTTON, SizeOfTBBUTTON)
VarSetCapacity(TRAYDATA, SizeOfTRAYDATA)
VarSetCapacity(FilePath, A_IsUnicode ? 600 : 300)
Index := 0
SendMessage, TB_BUTTONCOUNT
Loop % IconCount := ErrorLevel
{
   SendMessage, TB_GETBUTTON, Index, lpData
   DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess, UInt, lpData
                              , UInt, &amp;TBBUTTON
                              , UInt, SizeOfTBBUTTON, UInt, 0)

   DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess, UInt, NumGet(TBBUTTON, 12)
                              , UInt, &amp;TRAYDATA
                              , UInt, SizeOfTRAYDATA, UInt, 0)

   WinGet, PID, PID, % &quot;ahk_id &quot; NumGet(TRAYDATA)
   if !PID
      SendMessage, TB_DELETEBUTTON, Index--  ; в случае удаления индексы уменьшаются на 1
   Else
   {
      hProc := DllCall(&quot;OpenProcess&quot;, UInt, PROCESS_QUERY_INFORMATION, UInt, 0, UInt, PID)
      if !DllCall(&quot;GetProcessImageFileName&quot; . (A_IsUnicode ? &quot;W&quot; : &quot;A&quot;)
                                                , UInt, hProc
                                                , Str, FilePath, UInt, 300)
         DllCall(&quot;Psapi\GetProcessImageFileName&quot; . (A_IsUnicode ? &quot;W&quot; : &quot;A&quot;)
                                                   , UInt, hProc
                                                   , Str, FilePath, UInt, 300)
      FilePaths .= FilePath . &quot;`n&quot;
      DllCall(&quot;CloseHandle&quot;, UInt, hProc)
   }
   Index++
}

if (Index &lt; IconCount)
   SendMessage, WM_SETTINGCHANGE,,,, ahk_class Shell_TrayWnd

DllCall(&quot;VirtualFreeEx&quot;, UInt, hProcess , UInt, lpData, UInt, 0, UInt, MEM_RELEASE)
DllCall(&quot;CloseHandle&quot;, UInt, hProcess)

MsgBox, % SubStr(FilePaths, 1, -1)</code></pre></div><p>Оба варианта кода рассчитаны на 32-разрядную версию Windows.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Wed, 27 Apr 2011 20:46:25 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47881#p47881</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47852#p47852</link>
			<description><![CDATA[<p><strong>WUT</strong>, спасибо! Возможно, на этой основе можно будет сделать перевод и на AHK (послушаем коллег).</p>]]></description>
			<author><![CDATA[null@example.com (alexii)]]></author>
			<pubDate>Tue, 26 Apr 2011 18:53:18 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47852#p47852</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47850#p47850</link>
			<description><![CDATA[<p><a href="http://www.forum.script-coding.com/viewtopic.php?pid=47849#p47849">http://www.forum.script-coding.com/view … 849#p47849</a></p>]]></description>
			<author><![CDATA[null@example.com (WUT)]]></author>
			<pubDate>Tue, 26 Apr 2011 17:54:02 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47850#p47850</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47847#p47847</link>
			<description><![CDATA[<div class="quotebox"><cite>BasyAlex пишет:</cite><blockquote><p>А можно ссылочку...</p></blockquote></div><p>Сейчас размещу в соответствующем разделе оба кода</p>]]></description>
			<author><![CDATA[null@example.com (WUT)]]></author>
			<pubDate>Tue, 26 Apr 2011 17:22:55 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47847#p47847</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47846#p47846</link>
			<description><![CDATA[<div class="quotebox"><cite>WUT пишет:</cite><blockquote><p>А обязательно AHK? На Autoit эти вопросы решаются без проблем <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p></blockquote></div><p>А можно ссылочку...</p>]]></description>
			<author><![CDATA[null@example.com (BasyAlex)]]></author>
			<pubDate>Tue, 26 Apr 2011 17:18:42 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47846#p47846</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47845#p47845</link>
			<description><![CDATA[<p>А обязательно AHK? На Autoit эти вопросы решаются без проблем <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></description>
			<author><![CDATA[null@example.com (WUT)]]></author>
			<pubDate>Tue, 26 Apr 2011 17:04:24 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47845#p47845</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47841#p47841</link>
			<description><![CDATA[<p><a href="http://www.autohotkey.com/forum/viewtopic.php?t=19766">Скрипт</a> для определения констант.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Tue, 26 Apr 2011 14:05:04 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47841#p47841</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47840#p47840</link>
			<description><![CDATA[<p>Пошатался по форумам и пришла идея попробовать использовать <em>TB_-сообщения</em>. Вот толко я не нашел их hex-кодов для подстановки в <em>SendMessage/PostMessage</em></p>]]></description>
			<author><![CDATA[null@example.com (BasyAlex)]]></author>
			<pubDate>Tue, 26 Apr 2011 13:51:34 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47840#p47840</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47835#p47835</link>
			<description><![CDATA[<p>У меня та же проблема. Я и говорю, кривой способ. <img src="//forum.script-coding.com/img/smilies/big_smile.png" width="15" height="15" /> Насколько я вижу, Google ничего другого не предлагает.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Tue, 26 Apr 2011 10:29:13 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47835#p47835</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47831#p47831</link>
			<description><![CDATA[<div class="quotebox"><blockquote><p>Вот так можно попробовать, хотя способ довольно кривой</p></blockquote></div><p>Помогает, но&nbsp; DrWeb выдаёт свой <em>TrayTip</em> прямо у курсора мыши.</p>]]></description>
			<author><![CDATA[null@example.com (BasyAlex)]]></author>
			<pubDate>Tue, 26 Apr 2011 08:53:05 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47831#p47831</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47827#p47827</link>
			<description><![CDATA[<p>Вот так можно попробовать, хотя способ довольно кривой:<br /></p><div class="codebox"><pre><code>WinWait, ahk_class Shell_TrayWnd
ControlGetPos,,, W, H, ToolbarWindow321
Loop % W
   PostMessage, WM_MOUSEMOVE := 0x200,, (A_Index - 1)|((H/2)&lt;&lt;16), ToolbarWindow321</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Tue, 26 Apr 2011 07:59:16 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47827#p47827</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47824#p47824</link>
			<description><![CDATA[<div class="quotebox"><cite>alexii пишет:</cite><blockquote><p>Попробовать сделать наподобие такого: Re: Очистка трея.</p></blockquote></div><p>Попробовал использовать wm_mousemove через PostMessage, но возникли сложности:<br /><strong>1</strong><br />При посылании <em>PostMessage,0x200,,,, ahk_class ToolbarWindow32</em> исчезает иконка неработающей проги только если она расположена крайняя-слева, а она может находиться в любом месте трея. Другими словами - у <em>PostMessage</em> необходимо указать координаты <span class="bbu">откуда-куда</span> двигаться мышке. Как это сделать?</p><p><strong>2</strong><br />Возникает проблема с определением <em>ahk_class ToolbarWindow32</em> - их там несколько этого типа окон (все принадлежат <em>explorer.exe</em>). Поэтому приходиться использовать <em>ahk_id</em> и смотреть его через WInspector, что не годится, конечно же.</p>]]></description>
			<author><![CDATA[null@example.com (BasyAlex)]]></author>
			<pubDate>Mon, 25 Apr 2011 23:39:14 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47824#p47824</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47822#p47822</link>
			<description><![CDATA[<div class="quotebox"><cite>BasyAlex пишет:</cite><blockquote><p>Как заставиить трей обновить своё содержимое? Пробовал поискать какое сообщение должно ему передаваться при наведении курсора мыши на иконку неработающей проги для её исчезновения в трее через WInspector, но так и не нашел.</p></blockquote></div><p>Попробовать сделать наподобие такого: <a href="http://www.automate-my-tasks.com:8080/ru/viewtopic.php?f=2&amp;t=955&amp;p=3524#p3531">Re: Очистка трея</a>.</p><p><span style="color: Green"><strong>wodyanoi</strong>, что это за флуд?!</span></p>]]></description>
			<author><![CDATA[null@example.com (alexii)]]></author>
			<pubDate>Mon, 25 Apr 2011 19:50:28 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47822#p47822</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47821#p47821</link>
			<description><![CDATA[<p>угу гулять с девочкой!!! солныфко светит, а мы цалуемса!!!)</p>]]></description>
			<author><![CDATA[null@example.com (wodyanoi)]]></author>
			<pubDate>Mon, 25 Apr 2011 19:41:15 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47821#p47821</guid>
		</item>
		<item>
			<title><![CDATA[AHK: Работа с треем]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47801#p47801</link>
			<description><![CDATA[<p>Всем привет!</p><p><strong>Вопрос 1</strong><br />При некорректном завершении программ, частенько в трее остаются их иконки (к примеру Alcohol120%). Как заставиить трей обновить своё содержимое?</p><p>Пробовал поискать какое сообщение должно ему передаваться при наведении курсора мыши на иконку неработающей проги для её исчезновения в трее через WInspector, но так и не нашел. <br />Кстати, бывает и обратная ситуация - при крахе Explorer-а половина иконок просто исчезает из трея и приходиться перезапускать некоторые приложения дабы они там проявились.:mad:</p><p><strong>Вопрос 2</strong> (Следeт из первого)<br />Как получить список работающих прог висящих у меня в трее? Надобность возникла из-за того, что прога создаёт тьму окон одинакового класса (без имён и какого-либа текста) и только одно из них отвечает за клики в трее.</p><p><em>Стоит прога WallPaper Calendar v3.0.2 build 86 от zepsoft-a для смены обоев на рабочем столе выбираем через трей &quot;Change Wallpaper Image&quot; и меняем обои.<br />В скрипте это выглядит так - перебираем из полутора десятка одинаковых окон &quot;ahk_class TPUtilWindow&quot; выбираем необходимое (метотом тупого перебора через цикл) и посылаем ему PostMessage:<br /></em></p><div class="codebox"><pre><code>Process,Exist,WallCal3.exe
MyProgPID:=ErrorLevel
MyVar:=2
WinGet,ClassIDVar,List,ahk_class TPUtilWindow,,
While (MyVar&gt;0)
{
    MyProgID:=ClassIDVar%A_Index%
    WinGet,MyProgPIDVar,PID,ahk_id %MyProgID%,,
    if MyProgPIDVar=%MyProgPID%
    {
        OutputVar:=ClassIDVar%A_Index%
        MyVar-=1
    }
}
PostMessage,0x111,30,0,,ahk_id %OutputVar%</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (BasyAlex)]]></author>
			<pubDate>Mon, 25 Apr 2011 12:10:29 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47801#p47801</guid>
		</item>
	</channel>
</rss>
